@capgo/capacitor-inappbrowser 8.23.0 → 8.24.1
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.
- package/README.md +82 -81
- package/dist/docs.json +17 -1
- package/dist/esm/definitions.d.ts +50 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.js +6 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +39 -11
- package/dist/esm/web.js +324 -64
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +407 -152
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +407 -152
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/InAppBrowserPlugin/InAppBrowserPlugin.swift +1 -1
- package/package.json +2 -2
package/dist/esm/web.d.ts
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { WebPlugin } from '@capacitor/core';
|
|
2
2
|
import type { InAppBrowserPlugin, OpenWebViewOptions, OpenOptions, GetCookieOptions, ClearCookieOptions, BringToFrontOptions, DimensionOptions, DispatchInputEventOptions, OpenSecureWindowOptions, OpenSecureWindowResponse, ScreenshotResult } from './definitions';
|
|
3
|
+
export declare const formatDoctype: (doctype: DocumentType | null) => string;
|
|
4
|
+
export declare const TRUSTED_TYPES_POLICY_BLOCKED_MESSAGE: string;
|
|
5
|
+
/** Clears the lazy Trusted Types policy cache (for tests). */
|
|
6
|
+
export declare const resetTrustedHtmlPolicyCache: () => void;
|
|
7
|
+
export declare const createTrustedHtml: (html: string) => string | unknown;
|
|
8
|
+
export declare const injectNativeBridge: (html: string) => string;
|
|
9
|
+
/** Whether a webview message origin may replace the postMessage target (full origin string). */
|
|
10
|
+
export declare function mayAdoptPostMessageOrigin(openedUrl: string, messageOrigin: string): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Wraps fetched HTML in a sandboxed iframe (opaque origin, no allow-same-origin) so the remote page
|
|
13
|
+
* cannot read the app's storage or DOM even though the wrapper is a Blob created by the app origin.
|
|
14
|
+
* A <base href> pointing at the final response URL keeps relative URLs resolving against the target.
|
|
15
|
+
* The wrapper relays messages from the app (its opener) into the sandboxed frame.
|
|
16
|
+
*/
|
|
17
|
+
export declare const buildIsolatedDocument: (html: string, baseHref: string) => string;
|
|
3
18
|
export declare class InAppBrowserWeb extends WebPlugin implements InAppBrowserPlugin {
|
|
19
|
+
private readonly webViews;
|
|
20
|
+
private webViewCounter;
|
|
21
|
+
constructor();
|
|
22
|
+
private readonly handleWindowMessage;
|
|
23
|
+
private isFromWebView;
|
|
24
|
+
private watchClosed;
|
|
25
|
+
private resolveWebViewEntry;
|
|
26
|
+
private resolveTargetOrigin;
|
|
27
|
+
private hasHeaders;
|
|
28
|
+
private navigateOpenedWindow;
|
|
4
29
|
clearAllCookies(): Promise<any>;
|
|
5
30
|
clearCache(): Promise<any>;
|
|
6
31
|
clearAllBrowsingData(): Promise<any>;
|
|
@@ -14,35 +39,38 @@ export declare class InAppBrowserWeb extends WebPlugin implements InAppBrowserPl
|
|
|
14
39
|
close(options?: {
|
|
15
40
|
id?: string;
|
|
16
41
|
}): Promise<any>;
|
|
17
|
-
hide(
|
|
42
|
+
hide(_options?: {
|
|
18
43
|
id?: string;
|
|
19
44
|
}): Promise<void>;
|
|
20
|
-
show(
|
|
45
|
+
show(_options?: {
|
|
21
46
|
id?: string;
|
|
22
47
|
}): Promise<void>;
|
|
23
|
-
sendToBack(
|
|
48
|
+
sendToBack(_options?: {
|
|
24
49
|
id?: string;
|
|
25
50
|
transparentBackground?: boolean;
|
|
26
51
|
}): Promise<void>;
|
|
27
|
-
bringToFront(
|
|
28
|
-
dispatchInputEvent(
|
|
52
|
+
bringToFront(_options?: BringToFrontOptions): Promise<void>;
|
|
53
|
+
dispatchInputEvent(_options: DispatchInputEventOptions): Promise<void>;
|
|
29
54
|
setUrl(options: {
|
|
30
55
|
url: string;
|
|
31
56
|
}): Promise<any>;
|
|
32
57
|
reload(options?: {
|
|
33
58
|
id?: string;
|
|
34
59
|
}): Promise<any>;
|
|
35
|
-
postMessage(options:
|
|
36
|
-
|
|
60
|
+
postMessage(options: {
|
|
61
|
+
detail: Record<string, any>;
|
|
62
|
+
id?: string;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
takeScreenshot(_options?: {
|
|
37
65
|
id?: string;
|
|
38
66
|
}): Promise<ScreenshotResult>;
|
|
39
67
|
goBack(): Promise<any>;
|
|
40
68
|
getPluginVersion(): Promise<{
|
|
41
69
|
version: string;
|
|
42
70
|
}>;
|
|
43
|
-
updateDimensions(
|
|
71
|
+
updateDimensions(_options: DimensionOptions): Promise<void>;
|
|
44
72
|
handleProxyRequest(options: Parameters<InAppBrowserPlugin['handleProxyRequest']>[0]): Promise<void>;
|
|
45
|
-
setEnabledSafeTopMargin(
|
|
73
|
+
setEnabledSafeTopMargin(_options: {
|
|
46
74
|
enabled: boolean;
|
|
47
75
|
id?: string;
|
|
48
76
|
}): Promise<void>;
|
|
@@ -50,12 +78,12 @@ export declare class InAppBrowserWeb extends WebPlugin implements InAppBrowserPl
|
|
|
50
78
|
enabled: boolean;
|
|
51
79
|
id?: string;
|
|
52
80
|
}): Promise<void>;
|
|
53
|
-
getFullscreen(
|
|
81
|
+
getFullscreen(_options?: {
|
|
54
82
|
id?: string;
|
|
55
83
|
}): Promise<{
|
|
56
84
|
enabled: boolean;
|
|
57
85
|
}>;
|
|
58
|
-
setEnabledSafeBottomMargin(
|
|
86
|
+
setEnabledSafeBottomMargin(_options: {
|
|
59
87
|
enabled: boolean;
|
|
60
88
|
id?: string;
|
|
61
89
|
}): Promise<void>;
|
package/dist/esm/web.js
CHANGED
|
@@ -1,5 +1,238 @@
|
|
|
1
1
|
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
const HTML_ATTRIBUTE_ESCAPES = { '&': '&', '"': '"', '<': '<', '>': '>' };
|
|
3
|
+
const escapeHtmlAttribute = (value) => value.replace(/[&"<>]/g, (c) => HTML_ATTRIBUTE_ESCAPES[c]);
|
|
4
|
+
const OPENING_HEAD_TAG = /<head(?:\s[^>]*)?>/i;
|
|
5
|
+
const NATIVE_BRIDGE_SCRIPT = "(function(){window.addEventListener('message',function(e){if(e.source===window.parent){window.dispatchEvent(new CustomEvent('messageFromNative',{detail:e.data}));}});})();";
|
|
6
|
+
export const formatDoctype = (doctype) => {
|
|
7
|
+
if (!doctype) {
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
if (doctype.publicId) {
|
|
11
|
+
const system = doctype.systemId ? ` "${doctype.systemId}"` : '';
|
|
12
|
+
return `<!DOCTYPE ${doctype.name} PUBLIC "${doctype.publicId}"${system}>`;
|
|
13
|
+
}
|
|
14
|
+
if (doctype.systemId) {
|
|
15
|
+
return `<!DOCTYPE ${doctype.name} SYSTEM "${doctype.systemId}">`;
|
|
16
|
+
}
|
|
17
|
+
return `<!DOCTYPE ${doctype.name}>`;
|
|
18
|
+
};
|
|
19
|
+
const serializeParsedHtml = (doc) => formatDoctype(doc.doctype) + doc.documentElement.outerHTML;
|
|
20
|
+
const TRUSTED_TYPES_POLICY_NAME = 'capgo-inappbrowser';
|
|
21
|
+
export const TRUSTED_TYPES_POLICY_BLOCKED_MESSAGE = "InAppBrowser could not create the Trusted Types policy 'capgo-inappbrowser'. " +
|
|
22
|
+
'Add capgo-inappbrowser to the host app Content-Security-Policy trusted-types directive.';
|
|
23
|
+
let trustedHtmlPolicy;
|
|
24
|
+
/** Clears the lazy Trusted Types policy cache (for tests). */
|
|
25
|
+
export const resetTrustedHtmlPolicyCache = () => {
|
|
26
|
+
trustedHtmlPolicy = undefined;
|
|
27
|
+
};
|
|
28
|
+
const getTrustedHtmlPolicy = () => {
|
|
29
|
+
var _a;
|
|
30
|
+
if (trustedHtmlPolicy !== undefined) {
|
|
31
|
+
return trustedHtmlPolicy;
|
|
32
|
+
}
|
|
33
|
+
const trustedTypes = (_a = globalThis.window) === null || _a === void 0 ? void 0 : _a.trustedTypes;
|
|
34
|
+
if (!trustedTypes) {
|
|
35
|
+
trustedHtmlPolicy = null;
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
trustedHtmlPolicy = trustedTypes.createPolicy(TRUSTED_TYPES_POLICY_NAME, {
|
|
40
|
+
createHTML: (value) => value,
|
|
41
|
+
});
|
|
42
|
+
return trustedHtmlPolicy;
|
|
43
|
+
}
|
|
44
|
+
catch (_b) {
|
|
45
|
+
throw new Error(TRUSTED_TYPES_POLICY_BLOCKED_MESSAGE);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export const createTrustedHtml = (html) => {
|
|
49
|
+
const policy = getTrustedHtmlPolicy();
|
|
50
|
+
return policy ? policy.createHTML(html) : html;
|
|
51
|
+
};
|
|
52
|
+
const trustedHtmlToString = (html) => (typeof html === 'string' ? html : String(html));
|
|
53
|
+
export const injectNativeBridge = (html) => {
|
|
54
|
+
if (typeof DOMParser !== 'undefined') {
|
|
55
|
+
const doc = new DOMParser().parseFromString(createTrustedHtml(html), 'text/html');
|
|
56
|
+
const script = doc.createElement('script');
|
|
57
|
+
script.textContent = NATIVE_BRIDGE_SCRIPT;
|
|
58
|
+
if (doc.body) {
|
|
59
|
+
doc.body.appendChild(script);
|
|
60
|
+
return serializeParsedHtml(doc);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return `${html}<script>${NATIVE_BRIDGE_SCRIPT}</script>`;
|
|
64
|
+
};
|
|
65
|
+
/** Whether a webview message origin may replace the postMessage target (full origin string). */
|
|
66
|
+
export function mayAdoptPostMessageOrigin(openedUrl, messageOrigin) {
|
|
67
|
+
try {
|
|
68
|
+
const opened = new URL(openedUrl);
|
|
69
|
+
const incoming = new URL(messageOrigin);
|
|
70
|
+
if (opened.protocol !== incoming.protocol) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (opened.port !== incoming.port) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (opened.origin === incoming.origin) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
const openedHost = opened.hostname;
|
|
80
|
+
const incomingHost = incoming.hostname;
|
|
81
|
+
return incomingHost === openedHost || incomingHost.endsWith(`.${openedHost}`);
|
|
82
|
+
}
|
|
83
|
+
catch (_a) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Wraps fetched HTML in a sandboxed iframe (opaque origin, no allow-same-origin) so the remote page
|
|
89
|
+
* cannot read the app's storage or DOM even though the wrapper is a Blob created by the app origin.
|
|
90
|
+
* A <base href> pointing at the final response URL keeps relative URLs resolving against the target.
|
|
91
|
+
* The wrapper relays messages from the app (its opener) into the sandboxed frame.
|
|
92
|
+
*/
|
|
93
|
+
export const buildIsolatedDocument = (html, baseHref) => {
|
|
94
|
+
const baseTag = `<base href="${escapeHtmlAttribute(baseHref)}">`;
|
|
95
|
+
let inner = OPENING_HEAD_TAG.test(html)
|
|
96
|
+
? html.replace(OPENING_HEAD_TAG, (tag) => `${tag}${baseTag}`)
|
|
97
|
+
: `${baseTag}${html}`;
|
|
98
|
+
inner = injectNativeBridge(inner);
|
|
99
|
+
const srcdoc = trustedHtmlToString(createTrustedHtml(inner));
|
|
100
|
+
const sandbox = 'allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation';
|
|
101
|
+
const relay = "(function(){var f=document.getElementById('capgo-iab-frame');" +
|
|
102
|
+
"window.addEventListener('message',function(e){if(e.source===window.opener&&f&&f.contentWindow){f.contentWindow.postMessage(e.data,'*');}});})();";
|
|
103
|
+
return ('<!doctype html><html><head><meta charset="utf-8">' +
|
|
104
|
+
'<style>html,body,iframe{margin:0;padding:0;border:0;width:100%;height:100%;display:block}</style></head>' +
|
|
105
|
+
`<body><iframe id="capgo-iab-frame" sandbox="${sandbox}" referrerpolicy="no-referrer" srcdoc="${escapeHtmlAttribute(srcdoc)}"></iframe>` +
|
|
106
|
+
`<script>${relay}</script></body></html>`);
|
|
107
|
+
};
|
|
2
108
|
export class InAppBrowserWeb extends WebPlugin {
|
|
109
|
+
constructor() {
|
|
110
|
+
super();
|
|
111
|
+
this.webViews = new Map();
|
|
112
|
+
this.webViewCounter = 0;
|
|
113
|
+
this.handleWindowMessage = (event) => {
|
|
114
|
+
const match = Array.from(this.webViews.entries()).find(([, entry]) => this.isFromWebView(entry, event.source));
|
|
115
|
+
if (!match) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const [id, entry] = match;
|
|
119
|
+
if (entry.window === event.source &&
|
|
120
|
+
event.origin &&
|
|
121
|
+
event.origin !== 'null' &&
|
|
122
|
+
mayAdoptPostMessageOrigin(entry.url, event.origin)) {
|
|
123
|
+
entry.origin = event.origin;
|
|
124
|
+
}
|
|
125
|
+
let data = event.data;
|
|
126
|
+
if (typeof data === 'string') {
|
|
127
|
+
try {
|
|
128
|
+
data = JSON.parse(data);
|
|
129
|
+
}
|
|
130
|
+
catch (_a) {
|
|
131
|
+
this.notifyListeners('messageFromWebview', { id, rawMessage: event.data });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (data && typeof data === 'object' && !Array.isArray(data)) {
|
|
136
|
+
this.notifyListeners('messageFromWebview', Object.assign(Object.assign({}, data), { id }));
|
|
137
|
+
}
|
|
138
|
+
else if (typeof event.data === 'string') {
|
|
139
|
+
this.notifyListeners('messageFromWebview', { id, rawMessage: event.data });
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
if (globalThis.window !== undefined) {
|
|
143
|
+
globalThis.window.addEventListener('message', this.handleWindowMessage);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
isFromWebView(entry, source) {
|
|
147
|
+
if (!source) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (entry.window === source) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
if (!entry.objectUrl) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const frame = entry.window.document.getElementById('capgo-iab-frame');
|
|
158
|
+
return (frame === null || frame === void 0 ? void 0 : frame.contentWindow) === source;
|
|
159
|
+
}
|
|
160
|
+
catch (_a) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
watchClosed(id) {
|
|
165
|
+
const entry = this.webViews.get(id);
|
|
166
|
+
if (!(entry === null || entry === void 0 ? void 0 : entry.window.closed)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
globalThis.clearInterval(entry.timer);
|
|
170
|
+
if (entry.objectUrl) {
|
|
171
|
+
URL.revokeObjectURL(entry.objectUrl);
|
|
172
|
+
}
|
|
173
|
+
this.webViews.delete(id);
|
|
174
|
+
this.notifyListeners('closeEvent', { id, url: entry.url });
|
|
175
|
+
}
|
|
176
|
+
resolveWebViewEntry(id) {
|
|
177
|
+
if (id) {
|
|
178
|
+
const entry = this.webViews.get(id);
|
|
179
|
+
if (entry && !entry.window.closed) {
|
|
180
|
+
return { id, entry };
|
|
181
|
+
}
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
const match = Array.from(this.webViews.entries())
|
|
185
|
+
.reverse()
|
|
186
|
+
.find(([, entry]) => !entry.window.closed);
|
|
187
|
+
if (!match) {
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
return { id: match[0], entry: match[1] };
|
|
191
|
+
}
|
|
192
|
+
resolveTargetOrigin(url) {
|
|
193
|
+
var _a, _b;
|
|
194
|
+
try {
|
|
195
|
+
return new URL(url).origin;
|
|
196
|
+
}
|
|
197
|
+
catch (_c) {
|
|
198
|
+
return (_b = (_a = globalThis.location) === null || _a === void 0 ? void 0 : _a.origin) !== null && _b !== void 0 ? _b : 'null';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
hasHeaders(headers) {
|
|
202
|
+
return headers != null && Object.keys(headers).length > 0;
|
|
203
|
+
}
|
|
204
|
+
navigateOpenedWindow(id, win, url, headers) {
|
|
205
|
+
if (!this.hasHeaders(headers)) {
|
|
206
|
+
win.location.href = url;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
void (async () => {
|
|
210
|
+
var _a, _b;
|
|
211
|
+
try {
|
|
212
|
+
const response = await fetch(url, { headers });
|
|
213
|
+
if (!response.ok) {
|
|
214
|
+
throw new Error(`Request failed with status ${response.status}`);
|
|
215
|
+
}
|
|
216
|
+
const html = await response.text();
|
|
217
|
+
const parsed = new URL(response.url || url, (_b = (_a = globalThis.location) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : 'https://localhost/');
|
|
218
|
+
const baseHref = `${parsed.origin}${parsed.pathname}${parsed.search}`;
|
|
219
|
+
const blob = new Blob([buildIsolatedDocument(html, baseHref)], { type: 'text/html;charset=utf-8' });
|
|
220
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
221
|
+
const entry = this.webViews.get(id);
|
|
222
|
+
if (!entry || win.closed) {
|
|
223
|
+
URL.revokeObjectURL(objectUrl);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
entry.objectUrl = objectUrl;
|
|
227
|
+
win.location.href = objectUrl;
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
console.error('[InAppBrowser] Failed to load web view with headers', error);
|
|
231
|
+
win.close();
|
|
232
|
+
this.watchClosed(id);
|
|
233
|
+
}
|
|
234
|
+
})();
|
|
235
|
+
}
|
|
3
236
|
clearAllCookies() {
|
|
4
237
|
console.log('clearAllCookies');
|
|
5
238
|
return Promise.resolve();
|
|
@@ -12,100 +245,127 @@ export class InAppBrowserWeb extends WebPlugin {
|
|
|
12
245
|
console.log('clearAllBrowsingData');
|
|
13
246
|
return Promise.resolve();
|
|
14
247
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
248
|
+
open(options) {
|
|
249
|
+
const opened = globalThis.open('', '_blank');
|
|
250
|
+
if (!opened) {
|
|
251
|
+
return Promise.reject(new Error('Popup blocked'));
|
|
252
|
+
}
|
|
253
|
+
opened.opener = null;
|
|
254
|
+
opened.location.href = options.url;
|
|
255
|
+
return Promise.resolve();
|
|
18
256
|
}
|
|
19
|
-
|
|
257
|
+
clearCookies(options) {
|
|
20
258
|
console.log('cleanCookies', options);
|
|
21
|
-
return;
|
|
259
|
+
return Promise.resolve();
|
|
22
260
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return options;
|
|
261
|
+
getCookies(options) {
|
|
262
|
+
return Promise.resolve(options);
|
|
26
263
|
}
|
|
27
|
-
|
|
264
|
+
openWebView(options) {
|
|
265
|
+
var _a, _b, _c;
|
|
28
266
|
if (options.fullscreen) {
|
|
29
|
-
|
|
267
|
+
return Promise.reject(this.unimplemented('Fullscreen is only supported by native openWebView presentations.'));
|
|
268
|
+
}
|
|
269
|
+
const { popup = false, width, height } = (_a = options.web) !== null && _a !== void 0 ? _a : {};
|
|
270
|
+
const features = popup
|
|
271
|
+
? ['popup=yes', width ? `width=${width}` : '', height ? `height=${height}` : ''].filter(Boolean).join(',')
|
|
272
|
+
: '';
|
|
273
|
+
const opened = globalThis.open('', '_blank', features);
|
|
274
|
+
if (!opened) {
|
|
275
|
+
return Promise.reject(new Error('Popup blocked'));
|
|
30
276
|
}
|
|
31
|
-
|
|
32
|
-
|
|
277
|
+
const id = `web-${++this.webViewCounter}`;
|
|
278
|
+
const timer = globalThis.setInterval(() => this.watchClosed(id), 500);
|
|
279
|
+
// Header loads render inside an app-origin wrapper document, so messages target the app origin there.
|
|
280
|
+
const origin = this.hasHeaders(options.headers)
|
|
281
|
+
? ((_c = (_b = globalThis.location) === null || _b === void 0 ? void 0 : _b.origin) !== null && _c !== void 0 ? _c : 'null')
|
|
282
|
+
: this.resolveTargetOrigin(options.url);
|
|
283
|
+
this.webViews.set(id, { window: opened, url: options.url, timer, origin });
|
|
284
|
+
this.navigateOpenedWindow(id, opened, options.url, options.headers);
|
|
285
|
+
return Promise.resolve({ id });
|
|
33
286
|
}
|
|
34
|
-
|
|
287
|
+
executeScript({ code }) {
|
|
35
288
|
console.log('code', code);
|
|
36
|
-
return code;
|
|
289
|
+
return Promise.resolve(code);
|
|
37
290
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
291
|
+
close(options) {
|
|
292
|
+
const resolved = this.resolveWebViewEntry(options === null || options === void 0 ? void 0 : options.id);
|
|
293
|
+
if (!resolved) {
|
|
294
|
+
return Promise.resolve();
|
|
295
|
+
}
|
|
296
|
+
resolved.entry.window.close();
|
|
297
|
+
this.watchClosed(resolved.id);
|
|
298
|
+
return Promise.resolve();
|
|
41
299
|
}
|
|
42
|
-
|
|
43
|
-
console.log('hide',
|
|
44
|
-
return;
|
|
300
|
+
hide(_options) {
|
|
301
|
+
console.log('hide', _options);
|
|
302
|
+
return Promise.resolve();
|
|
45
303
|
}
|
|
46
|
-
|
|
47
|
-
console.log('show',
|
|
48
|
-
return;
|
|
304
|
+
show(_options) {
|
|
305
|
+
console.log('show', _options);
|
|
306
|
+
return Promise.resolve();
|
|
49
307
|
}
|
|
50
|
-
|
|
51
|
-
console.log('sendToBack not supported on web',
|
|
52
|
-
return;
|
|
308
|
+
sendToBack(_options) {
|
|
309
|
+
console.log('sendToBack not supported on web', _options);
|
|
310
|
+
return Promise.resolve();
|
|
53
311
|
}
|
|
54
|
-
|
|
55
|
-
console.log('bringToFront not supported on web',
|
|
56
|
-
return;
|
|
312
|
+
bringToFront(_options) {
|
|
313
|
+
console.log('bringToFront not supported on web', _options);
|
|
314
|
+
return Promise.resolve();
|
|
57
315
|
}
|
|
58
|
-
|
|
59
|
-
console.log('dispatchInputEvent not supported on web',
|
|
60
|
-
return;
|
|
316
|
+
dispatchInputEvent(_options) {
|
|
317
|
+
console.log('dispatchInputEvent not supported on web', _options);
|
|
318
|
+
return Promise.resolve();
|
|
61
319
|
}
|
|
62
|
-
|
|
320
|
+
setUrl(options) {
|
|
63
321
|
console.log('setUrl', options.url);
|
|
64
|
-
return;
|
|
322
|
+
return Promise.resolve();
|
|
65
323
|
}
|
|
66
|
-
|
|
324
|
+
reload(options) {
|
|
67
325
|
console.log('reload', options);
|
|
68
|
-
return;
|
|
326
|
+
return Promise.resolve();
|
|
69
327
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
328
|
+
postMessage(options) {
|
|
329
|
+
const resolved = this.resolveWebViewEntry(options.id);
|
|
330
|
+
if (resolved) {
|
|
331
|
+
resolved.entry.window.postMessage(options.detail, resolved.entry.origin);
|
|
332
|
+
}
|
|
333
|
+
return Promise.resolve();
|
|
73
334
|
}
|
|
74
|
-
|
|
75
|
-
console.log('takeScreenshot not supported on web',
|
|
76
|
-
|
|
335
|
+
takeScreenshot(_options) {
|
|
336
|
+
console.log('takeScreenshot not supported on web', _options);
|
|
337
|
+
return Promise.reject(this.unimplemented('Screenshots are not supported on web.'));
|
|
77
338
|
}
|
|
78
|
-
|
|
339
|
+
goBack() {
|
|
79
340
|
console.log('goBack');
|
|
80
|
-
return;
|
|
341
|
+
return Promise.resolve();
|
|
81
342
|
}
|
|
82
|
-
|
|
83
|
-
return { version: 'web' };
|
|
343
|
+
getPluginVersion() {
|
|
344
|
+
return Promise.resolve({ version: 'web' });
|
|
84
345
|
}
|
|
85
|
-
|
|
86
|
-
console.log('updateDimensions',
|
|
87
|
-
|
|
88
|
-
return;
|
|
346
|
+
updateDimensions(_options) {
|
|
347
|
+
console.log('updateDimensions', _options);
|
|
348
|
+
return Promise.resolve();
|
|
89
349
|
}
|
|
90
|
-
|
|
350
|
+
handleProxyRequest(options) {
|
|
91
351
|
console.log('handleProxyRequest not supported on web', options);
|
|
92
|
-
return;
|
|
352
|
+
return Promise.resolve();
|
|
93
353
|
}
|
|
94
|
-
|
|
95
|
-
console.log('setEnabledSafeTopMargin not supported on web',
|
|
96
|
-
return;
|
|
354
|
+
setEnabledSafeTopMargin(_options) {
|
|
355
|
+
console.log('setEnabledSafeTopMargin not supported on web', _options);
|
|
356
|
+
return Promise.resolve();
|
|
97
357
|
}
|
|
98
|
-
|
|
358
|
+
setFullscreen(options) {
|
|
99
359
|
console.log('setFullscreen not supported on web', options);
|
|
100
|
-
|
|
360
|
+
return Promise.reject(this.unimplemented('Fullscreen is only supported by native openWebView presentations.'));
|
|
101
361
|
}
|
|
102
|
-
|
|
103
|
-
console.log('getFullscreen not supported on web',
|
|
104
|
-
|
|
362
|
+
getFullscreen(_options) {
|
|
363
|
+
console.log('getFullscreen not supported on web', _options);
|
|
364
|
+
return Promise.reject(this.unimplemented('Fullscreen is only supported by native openWebView presentations.'));
|
|
105
365
|
}
|
|
106
|
-
|
|
107
|
-
console.log('setEnabledSafeBottomMargin not supported on web',
|
|
108
|
-
return;
|
|
366
|
+
setEnabledSafeBottomMargin(_options) {
|
|
367
|
+
console.log('setEnabledSafeBottomMargin not supported on web', _options);
|
|
368
|
+
return Promise.resolve();
|
|
109
369
|
}
|
|
110
370
|
async openSecureWindow(options) {
|
|
111
371
|
const w = 600;
|
|
@@ -118,7 +378,7 @@ export class InAppBrowserWeb extends WebPlugin {
|
|
|
118
378
|
]
|
|
119
379
|
.map((x) => x.join('='))
|
|
120
380
|
.join(',');
|
|
121
|
-
const popup =
|
|
381
|
+
const popup = globalThis.open(options.authEndpoint, 'Authorization', settings);
|
|
122
382
|
if (!popup) {
|
|
123
383
|
throw new Error('Failed to open secure window');
|
|
124
384
|
}
|
package/dist/esm/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n InAppBrowserPlugin,\n OpenWebViewOptions,\n OpenOptions,\n GetCookieOptions,\n ClearCookieOptions,\n BringToFrontOptions,\n DimensionOptions,\n DispatchInputEventOptions,\n OpenSecureWindowOptions,\n OpenSecureWindowResponse,\n ScreenshotResult,\n} from './definitions';\n\nexport class InAppBrowserWeb extends WebPlugin implements InAppBrowserPlugin {\n clearAllCookies(): Promise<any> {\n console.log('clearAllCookies');\n return Promise.resolve();\n }\n clearCache(): Promise<any> {\n console.log('clearCache');\n return Promise.resolve();\n }\n clearAllBrowsingData(): Promise<any> {\n console.log('clearAllBrowsingData');\n return Promise.resolve();\n }\n async open(options: OpenOptions): Promise<any> {\n console.log('open', options);\n return options;\n }\n\n async clearCookies(options: ClearCookieOptions): Promise<any> {\n console.log('cleanCookies', options);\n return;\n }\n\n async getCookies(options: GetCookieOptions): Promise<any> {\n // Web implementation to get cookies\n return options;\n }\n\n async openWebView(options: OpenWebViewOptions): Promise<any> {\n if (options.fullscreen) {\n throw this.unimplemented('Fullscreen is only supported by native openWebView presentations.');\n }\n console.log('openWebView', options);\n return options;\n }\n\n async executeScript({ code }: { code: string }): Promise<any> {\n console.log('code', code);\n return code;\n }\n\n async close(options?: { id?: string }): Promise<any> {\n console.log('close', options);\n return;\n }\n\n async hide(options?: { id?: string }): Promise<void> {\n console.log('hide', options);\n return;\n }\n\n async show(options?: { id?: string }): Promise<void> {\n console.log('show', options);\n return;\n }\n\n async sendToBack(options?: { id?: string; transparentBackground?: boolean }): Promise<void> {\n console.log('sendToBack not supported on web', options);\n return;\n }\n\n async bringToFront(options?: BringToFrontOptions): Promise<void> {\n console.log('bringToFront not supported on web', options);\n return;\n }\n\n async dispatchInputEvent(options: DispatchInputEventOptions): Promise<void> {\n console.log('dispatchInputEvent not supported on web', options);\n return;\n }\n\n async setUrl(options: { url: string }): Promise<any> {\n console.log('setUrl', options.url);\n return;\n }\n\n async reload(options?: { id?: string }): Promise<any> {\n console.log('reload', options);\n return;\n }\n async postMessage(options: Record<string, any>): Promise<any> {\n console.log('postMessage', options);\n return options;\n }\n\n async takeScreenshot(options?: { id?: string }): Promise<ScreenshotResult> {\n console.log('takeScreenshot not supported on web', options);\n throw this.unimplemented('Screenshots are not supported on web.');\n }\n\n async goBack(): Promise<any> {\n console.log('goBack');\n return;\n }\n\n async getPluginVersion(): Promise<{ version: string }> {\n return { version: 'web' };\n }\n\n async updateDimensions(options: DimensionOptions): Promise<void> {\n console.log('updateDimensions', options);\n // Web platform doesn't support dimension control\n return;\n }\n\n async handleProxyRequest(options: Parameters<InAppBrowserPlugin['handleProxyRequest']>[0]): Promise<void> {\n console.log('handleProxyRequest not supported on web', options);\n return;\n }\n\n async setEnabledSafeTopMargin(options: { enabled: boolean; id?: string }): Promise<void> {\n console.log('setEnabledSafeTopMargin not supported on web', options);\n return;\n }\n\n async setFullscreen(options: { enabled: boolean; id?: string }): Promise<void> {\n console.log('setFullscreen not supported on web', options);\n throw this.unimplemented('Fullscreen is only supported by native openWebView presentations.');\n }\n\n async getFullscreen(options?: { id?: string }): Promise<{ enabled: boolean }> {\n console.log('getFullscreen not supported on web', options);\n throw this.unimplemented('Fullscreen is only supported by native openWebView presentations.');\n }\n\n async setEnabledSafeBottomMargin(options: { enabled: boolean; id?: string }): Promise<void> {\n console.log('setEnabledSafeBottomMargin not supported on web', options);\n return;\n }\n\n async openSecureWindow(options: OpenSecureWindowOptions): Promise<OpenSecureWindowResponse> {\n const w = 600;\n const h = 550;\n const settings = [\n ['width', w],\n ['height', h],\n ['left', screen.width / 2 - w / 2],\n ['top', screen.height / 2 - h / 2],\n ]\n .map((x) => x.join('='))\n .join(',');\n\n const popup = window.open(options.authEndpoint, 'Authorization', settings);\n if (!popup) {\n throw new Error('Failed to open secure window');\n }\n if (typeof popup.focus === 'function') {\n popup.focus();\n }\n return new Promise((resolve, reject) => {\n const bc = new BroadcastChannel(options.broadcastChannelName || 'oauth-channel');\n bc.addEventListener('message', (event) => {\n if (event.data.startsWith(options.redirectUri)) {\n bc.close();\n resolve({ redirectedUri: event.data });\n } else {\n bc.close();\n reject(new Error('Redirect URI does not match, expected ' + options.redirectUri + ' but got ' + event.data));\n }\n });\n setTimeout(() => {\n bc.close();\n reject(new Error('The sign-in flow timed out'));\n }, 5 * 60000);\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n InAppBrowserPlugin,\n OpenWebViewOptions,\n OpenOptions,\n GetCookieOptions,\n ClearCookieOptions,\n BringToFrontOptions,\n DimensionOptions,\n DispatchInputEventOptions,\n OpenSecureWindowOptions,\n OpenSecureWindowResponse,\n ScreenshotResult,\n} from './definitions';\n\ntype TrackedWebView = {\n window: Window;\n url: string;\n timer: number;\n /** Origin used as postMessage target. Updated from the last message the page sent (handles redirects). */\n origin: string;\n /** Object URL of the isolating wrapper document for header loads, revoked on close. */\n objectUrl?: string;\n};\n\nconst HTML_ATTRIBUTE_ESCAPES: Record<string, string> = { '&': '&', '\"': '"', '<': '<', '>': '>' };\n\nconst escapeHtmlAttribute = (value: string): string => value.replace(/[&\"<>]/g, (c) => HTML_ATTRIBUTE_ESCAPES[c]);\n\nconst OPENING_HEAD_TAG = /<head(?:\\s[^>]*)?>/i;\n\nconst NATIVE_BRIDGE_SCRIPT =\n \"(function(){window.addEventListener('message',function(e){if(e.source===window.parent){window.dispatchEvent(new CustomEvent('messageFromNative',{detail:e.data}));}});})();\";\n\nexport const formatDoctype = (doctype: DocumentType | null): string => {\n if (!doctype) {\n return '';\n }\n if (doctype.publicId) {\n const system = doctype.systemId ? ` \"${doctype.systemId}\"` : '';\n return `<!DOCTYPE ${doctype.name} PUBLIC \"${doctype.publicId}\"${system}>`;\n }\n if (doctype.systemId) {\n return `<!DOCTYPE ${doctype.name} SYSTEM \"${doctype.systemId}\">`;\n }\n return `<!DOCTYPE ${doctype.name}>`;\n};\n\nconst serializeParsedHtml = (doc: Document): string => formatDoctype(doc.doctype) + doc.documentElement.outerHTML;\n\nconst TRUSTED_TYPES_POLICY_NAME = 'capgo-inappbrowser';\n\nexport const TRUSTED_TYPES_POLICY_BLOCKED_MESSAGE =\n \"InAppBrowser could not create the Trusted Types policy 'capgo-inappbrowser'. \" +\n 'Add capgo-inappbrowser to the host app Content-Security-Policy trusted-types directive.';\n\ntype CapgoTrustedHtmlPolicy = {\n createHTML: (html: string) => unknown;\n};\n\ntype CapgoTrustedTypes = {\n createPolicy: (name: string, rules: { createHTML: (html: string) => string }) => CapgoTrustedHtmlPolicy;\n};\n\nlet trustedHtmlPolicy: CapgoTrustedHtmlPolicy | null | undefined;\n\n/** Clears the lazy Trusted Types policy cache (for tests). */\nexport const resetTrustedHtmlPolicyCache = (): void => {\n trustedHtmlPolicy = undefined;\n};\n\nconst getTrustedHtmlPolicy = (): CapgoTrustedHtmlPolicy | null => {\n if (trustedHtmlPolicy !== undefined) {\n return trustedHtmlPolicy;\n }\n const trustedTypes = (globalThis.window as (Window & { trustedTypes?: CapgoTrustedTypes }) | undefined)?.trustedTypes;\n if (!trustedTypes) {\n trustedHtmlPolicy = null;\n return null;\n }\n try {\n trustedHtmlPolicy = trustedTypes.createPolicy(TRUSTED_TYPES_POLICY_NAME, {\n createHTML: (value: string) => value,\n });\n return trustedHtmlPolicy;\n } catch {\n throw new Error(TRUSTED_TYPES_POLICY_BLOCKED_MESSAGE);\n }\n};\n\nexport const createTrustedHtml = (html: string): string | unknown => {\n const policy = getTrustedHtmlPolicy();\n return policy ? policy.createHTML(html) : html;\n};\n\nconst trustedHtmlToString = (html: string | unknown): string => (typeof html === 'string' ? html : String(html));\n\nexport const injectNativeBridge = (html: string): string => {\n if (typeof DOMParser !== 'undefined') {\n const doc = new DOMParser().parseFromString(createTrustedHtml(html) as string, 'text/html');\n const script = doc.createElement('script');\n script.textContent = NATIVE_BRIDGE_SCRIPT;\n if (doc.body) {\n doc.body.appendChild(script);\n return serializeParsedHtml(doc);\n }\n }\n return `${html}<script>${NATIVE_BRIDGE_SCRIPT}</script>`;\n};\n\n/** Whether a webview message origin may replace the postMessage target (full origin string). */\nexport function mayAdoptPostMessageOrigin(openedUrl: string, messageOrigin: string): boolean {\n try {\n const opened = new URL(openedUrl);\n const incoming = new URL(messageOrigin);\n if (opened.protocol !== incoming.protocol) {\n return false;\n }\n if (opened.port !== incoming.port) {\n return false;\n }\n if (opened.origin === incoming.origin) {\n return true;\n }\n const openedHost = opened.hostname;\n const incomingHost = incoming.hostname;\n return incomingHost === openedHost || incomingHost.endsWith(`.${openedHost}`);\n } catch {\n return false;\n }\n}\n\n/**\n * Wraps fetched HTML in a sandboxed iframe (opaque origin, no allow-same-origin) so the remote page\n * cannot read the app's storage or DOM even though the wrapper is a Blob created by the app origin.\n * A <base href> pointing at the final response URL keeps relative URLs resolving against the target.\n * The wrapper relays messages from the app (its opener) into the sandboxed frame.\n */\nexport const buildIsolatedDocument = (html: string, baseHref: string): string => {\n const baseTag = `<base href=\"${escapeHtmlAttribute(baseHref)}\">`;\n let inner = OPENING_HEAD_TAG.test(html)\n ? html.replace(OPENING_HEAD_TAG, (tag) => `${tag}${baseTag}`)\n : `${baseTag}${html}`;\n inner = injectNativeBridge(inner);\n const srcdoc = trustedHtmlToString(createTrustedHtml(inner));\n const sandbox =\n 'allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation';\n const relay =\n \"(function(){var f=document.getElementById('capgo-iab-frame');\" +\n \"window.addEventListener('message',function(e){if(e.source===window.opener&&f&&f.contentWindow){f.contentWindow.postMessage(e.data,'*');}});})();\";\n return (\n '<!doctype html><html><head><meta charset=\"utf-8\">' +\n '<style>html,body,iframe{margin:0;padding:0;border:0;width:100%;height:100%;display:block}</style></head>' +\n `<body><iframe id=\"capgo-iab-frame\" sandbox=\"${sandbox}\" referrerpolicy=\"no-referrer\" srcdoc=\"${escapeHtmlAttribute(srcdoc)}\"></iframe>` +\n `<script>${relay}</script></body></html>`\n );\n};\n\nexport class InAppBrowserWeb extends WebPlugin implements InAppBrowserPlugin {\n private readonly webViews = new Map<string, TrackedWebView>();\n private webViewCounter = 0;\n\n constructor() {\n super();\n if (globalThis.window !== undefined) {\n globalThis.window.addEventListener('message', this.handleWindowMessage);\n }\n }\n\n private readonly handleWindowMessage = (event: MessageEvent): void => {\n const match = Array.from(this.webViews.entries()).find(([, entry]) => this.isFromWebView(entry, event.source));\n if (!match) {\n return;\n }\n const [id, entry] = match;\n if (\n entry.window === event.source &&\n event.origin &&\n event.origin !== 'null' &&\n mayAdoptPostMessageOrigin(entry.url, event.origin)\n ) {\n entry.origin = event.origin;\n }\n let data: unknown = event.data;\n if (typeof data === 'string') {\n try {\n data = JSON.parse(data);\n } catch {\n this.notifyListeners('messageFromWebview', { id, rawMessage: event.data });\n return;\n }\n }\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n this.notifyListeners('messageFromWebview', { ...(data as Record<string, unknown>), id });\n } else if (typeof event.data === 'string') {\n this.notifyListeners('messageFromWebview', { id, rawMessage: event.data });\n }\n };\n\n private isFromWebView(entry: TrackedWebView, source: MessageEventSource | null): boolean {\n if (!source) {\n return false;\n }\n if (entry.window === source) {\n return true;\n }\n if (!entry.objectUrl) {\n return false;\n }\n try {\n const frame = entry.window.document.getElementById('capgo-iab-frame') as HTMLIFrameElement | null;\n return frame?.contentWindow === source;\n } catch {\n return false;\n }\n }\n\n private watchClosed(id: string): void {\n const entry = this.webViews.get(id);\n if (!entry?.window.closed) {\n return;\n }\n globalThis.clearInterval(entry.timer);\n if (entry.objectUrl) {\n URL.revokeObjectURL(entry.objectUrl);\n }\n this.webViews.delete(id);\n this.notifyListeners('closeEvent', { id, url: entry.url });\n }\n\n private resolveWebViewEntry(id?: string): { id: string; entry: TrackedWebView } | undefined {\n if (id) {\n const entry = this.webViews.get(id);\n if (entry && !entry.window.closed) {\n return { id, entry };\n }\n return undefined;\n }\n const match = Array.from(this.webViews.entries())\n .reverse()\n .find(([, entry]) => !entry.window.closed);\n if (!match) {\n return undefined;\n }\n return { id: match[0], entry: match[1] };\n }\n\n private resolveTargetOrigin(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return globalThis.location?.origin ?? 'null';\n }\n }\n\n private hasHeaders(headers?: Record<string, string>): headers is Record<string, string> {\n return headers != null && Object.keys(headers).length > 0;\n }\n\n private navigateOpenedWindow(id: string, win: Window, url: string, headers?: Record<string, string>): void {\n if (!this.hasHeaders(headers)) {\n win.location.href = url;\n return;\n }\n\n void (async () => {\n try {\n const response = await fetch(url, { headers });\n if (!response.ok) {\n throw new Error(`Request failed with status ${response.status}`);\n }\n const html = await response.text();\n const parsed = new URL(response.url || url, globalThis.location?.href ?? 'https://localhost/');\n const baseHref = `${parsed.origin}${parsed.pathname}${parsed.search}`;\n const blob = new Blob([buildIsolatedDocument(html, baseHref)], { type: 'text/html;charset=utf-8' });\n const objectUrl = URL.createObjectURL(blob);\n const entry = this.webViews.get(id);\n if (!entry || win.closed) {\n URL.revokeObjectURL(objectUrl);\n return;\n }\n entry.objectUrl = objectUrl;\n win.location.href = objectUrl;\n } catch (error) {\n console.error('[InAppBrowser] Failed to load web view with headers', error);\n win.close();\n this.watchClosed(id);\n }\n })();\n }\n\n clearAllCookies(): Promise<any> {\n console.log('clearAllCookies');\n return Promise.resolve();\n }\n\n clearCache(): Promise<any> {\n console.log('clearCache');\n return Promise.resolve();\n }\n\n clearAllBrowsingData(): Promise<any> {\n console.log('clearAllBrowsingData');\n return Promise.resolve();\n }\n\n open(options: OpenOptions): Promise<any> {\n const opened = globalThis.open('', '_blank');\n if (!opened) {\n return Promise.reject(new Error('Popup blocked'));\n }\n opened.opener = null;\n opened.location.href = options.url;\n return Promise.resolve();\n }\n\n clearCookies(options: ClearCookieOptions): Promise<any> {\n console.log('cleanCookies', options);\n return Promise.resolve();\n }\n\n getCookies(options: GetCookieOptions): Promise<any> {\n return Promise.resolve(options);\n }\n\n openWebView(options: OpenWebViewOptions): Promise<any> {\n if (options.fullscreen) {\n return Promise.reject(this.unimplemented('Fullscreen is only supported by native openWebView presentations.'));\n }\n const { popup = false, width, height } = options.web ?? {};\n const features = popup\n ? ['popup=yes', width ? `width=${width}` : '', height ? `height=${height}` : ''].filter(Boolean).join(',')\n : '';\n const opened = globalThis.open('', '_blank', features);\n if (!opened) {\n return Promise.reject(new Error('Popup blocked'));\n }\n\n const id = `web-${++this.webViewCounter}`;\n const timer = globalThis.setInterval(() => this.watchClosed(id), 500);\n // Header loads render inside an app-origin wrapper document, so messages target the app origin there.\n const origin = this.hasHeaders(options.headers)\n ? (globalThis.location?.origin ?? 'null')\n : this.resolveTargetOrigin(options.url);\n this.webViews.set(id, { window: opened, url: options.url, timer, origin });\n this.navigateOpenedWindow(id, opened, options.url, options.headers);\n return Promise.resolve({ id });\n }\n\n executeScript({ code }: { code: string }): Promise<any> {\n console.log('code', code);\n return Promise.resolve(code);\n }\n\n close(options?: { id?: string }): Promise<any> {\n const resolved = this.resolveWebViewEntry(options?.id);\n if (!resolved) {\n return Promise.resolve();\n }\n resolved.entry.window.close();\n this.watchClosed(resolved.id);\n return Promise.resolve();\n }\n\n hide(_options?: { id?: string }): Promise<void> {\n console.log('hide', _options);\n return Promise.resolve();\n }\n\n show(_options?: { id?: string }): Promise<void> {\n console.log('show', _options);\n return Promise.resolve();\n }\n\n sendToBack(_options?: { id?: string; transparentBackground?: boolean }): Promise<void> {\n console.log('sendToBack not supported on web', _options);\n return Promise.resolve();\n }\n\n bringToFront(_options?: BringToFrontOptions): Promise<void> {\n console.log('bringToFront not supported on web', _options);\n return Promise.resolve();\n }\n\n dispatchInputEvent(_options: DispatchInputEventOptions): Promise<void> {\n console.log('dispatchInputEvent not supported on web', _options);\n return Promise.resolve();\n }\n\n setUrl(options: { url: string }): Promise<any> {\n console.log('setUrl', options.url);\n return Promise.resolve();\n }\n\n reload(options?: { id?: string }): Promise<any> {\n console.log('reload', options);\n return Promise.resolve();\n }\n\n postMessage(options: { detail: Record<string, any>; id?: string }): Promise<void> {\n const resolved = this.resolveWebViewEntry(options.id);\n if (resolved) {\n resolved.entry.window.postMessage(options.detail, resolved.entry.origin);\n }\n return Promise.resolve();\n }\n\n takeScreenshot(_options?: { id?: string }): Promise<ScreenshotResult> {\n console.log('takeScreenshot not supported on web', _options);\n return Promise.reject(this.unimplemented('Screenshots are not supported on web.'));\n }\n\n goBack(): Promise<any> {\n console.log('goBack');\n return Promise.resolve();\n }\n\n getPluginVersion(): Promise<{ version: string }> {\n return Promise.resolve({ version: 'web' });\n }\n\n updateDimensions(_options: DimensionOptions): Promise<void> {\n console.log('updateDimensions', _options);\n return Promise.resolve();\n }\n\n handleProxyRequest(options: Parameters<InAppBrowserPlugin['handleProxyRequest']>[0]): Promise<void> {\n console.log('handleProxyRequest not supported on web', options);\n return Promise.resolve();\n }\n\n setEnabledSafeTopMargin(_options: { enabled: boolean; id?: string }): Promise<void> {\n console.log('setEnabledSafeTopMargin not supported on web', _options);\n return Promise.resolve();\n }\n\n setFullscreen(options: { enabled: boolean; id?: string }): Promise<void> {\n console.log('setFullscreen not supported on web', options);\n return Promise.reject(this.unimplemented('Fullscreen is only supported by native openWebView presentations.'));\n }\n\n getFullscreen(_options?: { id?: string }): Promise<{ enabled: boolean }> {\n console.log('getFullscreen not supported on web', _options);\n return Promise.reject(this.unimplemented('Fullscreen is only supported by native openWebView presentations.'));\n }\n\n setEnabledSafeBottomMargin(_options: { enabled: boolean; id?: string }): Promise<void> {\n console.log('setEnabledSafeBottomMargin not supported on web', _options);\n return Promise.resolve();\n }\n\n async openSecureWindow(options: OpenSecureWindowOptions): Promise<OpenSecureWindowResponse> {\n const w = 600;\n const h = 550;\n const settings = [\n ['width', w],\n ['height', h],\n ['left', screen.width / 2 - w / 2],\n ['top', screen.height / 2 - h / 2],\n ]\n .map((x) => x.join('='))\n .join(',');\n\n const popup = globalThis.open(options.authEndpoint, 'Authorization', settings);\n if (!popup) {\n throw new Error('Failed to open secure window');\n }\n if (typeof popup.focus === 'function') {\n popup.focus();\n }\n return new Promise((resolve, reject) => {\n const bc = new BroadcastChannel(options.broadcastChannelName || 'oauth-channel');\n bc.addEventListener('message', (event) => {\n if (event.data.startsWith(options.redirectUri)) {\n bc.close();\n resolve({ redirectedUri: event.data });\n } else {\n bc.close();\n reject(new Error('Redirect URI does not match, expected ' + options.redirectUri + ' but got ' + event.data));\n }\n });\n setTimeout(() => {\n bc.close();\n reject(new Error('The sign-in flow timed out'));\n }, 5 * 60000);\n });\n }\n}\n"]}
|