Skip to content

Commit 943419f

Browse files
authored
Merge pull request #58 from ionic-team/development
feat(android,ios): add onBrowserPageNavigationCompleted event
2 parents 7d0ce42 + 6bf10b1 commit 943419f

File tree

7 files changed

+190
-225
lines changed

7 files changed

+190
-225
lines changed

CapacitorInappbrowser.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Pod::Spec.new do |s|
1212
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
1313
s.source_files = 'ios/Sources/InAppBrowserPlugin/*.{swift,h,m,c,cc,mm,cpp}'
1414
s.ios.deployment_target = '14.0'
15-
s.dependency 'OSInAppBrowserLib', spec='~> 1.0'
15+
s.dependency 'OSInAppBrowserLib', spec='~> 2.0'
1616
s.dependency 'Capacitor'
1717
s.swift_version = '5.1'
1818
end

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ await InAppBrowser.addListener('browserClosed', () => {
6464
console.log("browser was closed.");
6565
});
6666

67+
await InAppBrowser.addListener('browserPageNavigationCompleted', (data) => {
68+
console.log("browser page navigation was completed. " + data.url);
69+
});
70+
6771
await InAppBrowser.addListener('browserPageLoaded', () => {
6872
console.log("browser was loaded.");
6973
});
@@ -84,6 +88,7 @@ InAppBrowser.removeAllListeners();
8488
* [`openInExternalBrowser(...)`](#openinexternalbrowser)
8589
* [`close()`](#close)
8690
* [`addListener('browserClosed' | 'browserPageLoaded', ...)`](#addlistenerbrowserclosed--browserpageloaded-)
91+
* [`addListener('browserPageNavigationCompleted', ...)`](#addlistenerbrowserpagenavigationcompleted-)
8792
* [`removeAllListeners()`](#removealllisteners)
8893
* [Interfaces](#interfaces)
8994
* [Enums](#enums)
@@ -167,6 +172,24 @@ Adds a listener for the specified browser event.
167172
--------------------
168173

169174

175+
### addListener('browserPageNavigationCompleted', ...)
176+
177+
```typescript
178+
addListener(eventName: 'browserPageNavigationCompleted', listenerFunc: (data: BrowserPageNavigationCompletedEventData) => void) => Promise<PluginListenerHandle>
179+
```
180+
181+
Adds a listener for the specified browser event.
182+
183+
| Param | Type | Description |
184+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
185+
| **`eventName`** | <code>'browserPageNavigationCompleted'</code> | The name of the browser event to listen for: 'browserPageNavigationCompleted'. |
186+
| **`listenerFunc`** | <code>(data: <a href="#browserpagenavigationcompletedeventdata">BrowserPageNavigationCompletedEventData</a>) =&gt; void</code> | The function to be called when the event occurs. |
187+
188+
**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
189+
190+
--------------------
191+
192+
170193
### removeAllListeners()
171194

172195
```typescript
@@ -293,6 +316,15 @@ Defines the options for opening a URL in the external browser and used by the ot
293316
| **`remove`** | <code>() =&gt; Promise&lt;void&gt;</code> |
294317

295318

319+
#### BrowserPageNavigationCompletedEventData
320+
321+
Defines the data for the 'browserPageNavigationCompleted' event.
322+
323+
| Prop | Type | Description |
324+
| --------- | ------------------- | ------------------------------------ |
325+
| **`url`** | <code>string</code> | The URL of the page that was loaded. |
326+
327+
296328
### Enums
297329

298330

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ repositories {
5858
dependencies {
5959
// implementation fileTree(dir: 'libs', include: ['*.jar'])
6060
implementation project(':capacitor-android')
61-
implementation "io.ionic.libs:ioninappbrowser-android:1.2.1"
61+
implementation "io.ionic.libs:ioninappbrowser-android:1.3.0"
6262
implementation 'androidx.browser:browser:1.8.0'
6363
implementation "androidx.constraintlayout:constraintlayout:2.2.0"
6464
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"

android/src/main/java/com/capacitorjs/osinappbrowser/InAppBrowserPlugin.kt

Lines changed: 75 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -32,52 +32,22 @@ class InAppBrowserPlugin : Plugin() {
3232

3333
@PluginMethod
3434
fun openInExternalBrowser(call: PluginCall) {
35-
val url = call.getString("url")
36-
if (url.isNullOrEmpty()) {
37-
sendErrorResult(call, OSInAppBrowserError.InputArgumentsIssue(OSInAppBrowserTarget.EXTERNAL_BROWSER))
38-
return
39-
}
40-
41-
if (!isSchemeValid(url)) {
42-
sendErrorResult(call, OSInAppBrowserError.InvalidURL)
43-
return
44-
}
45-
46-
try {
35+
handleBrowserCall(call, OSInAppBrowserTarget.EXTERNAL_BROWSER) { url ->
4736
val externalBrowserRouter = OSIABExternalBrowserRouterAdapter(context)
48-
4937
engine?.openExternalBrowser(externalBrowserRouter, url) { success ->
50-
if (success) {
51-
call.resolve()
52-
} else {
53-
sendErrorResult(call, OSInAppBrowserError.OpenFailed(url, OSInAppBrowserTarget.EXTERNAL_BROWSER))
54-
}
38+
handleBrowserResult(call, success, url, OSInAppBrowserTarget.EXTERNAL_BROWSER)
5539
}
56-
} catch (e: Exception) {
57-
sendErrorResult(call, OSInAppBrowserError.OpenFailed(url, OSInAppBrowserTarget.EXTERNAL_BROWSER))
5840
}
5941
}
6042

6143
@PluginMethod
6244
fun openInSystemBrowser(call: PluginCall) {
63-
val url = call.getString("url")
64-
val options = call.getObject("options")
65-
66-
if (url.isNullOrEmpty() || options == null) {
67-
sendErrorResult(call, OSInAppBrowserError.InputArgumentsIssue(OSInAppBrowserTarget.SYSTEM_BROWSER))
68-
return
69-
}
70-
71-
if (!isSchemeValid(url)) {
72-
sendErrorResult(call, OSInAppBrowserError.InvalidURL)
73-
return
74-
}
75-
76-
try {
45+
handleBrowserCall(call, OSInAppBrowserTarget.SYSTEM_BROWSER) { url ->
46+
val options = call.getObject("options")
47+
?: return@handleBrowserCall sendErrorResult(call, OSInAppBrowserError.InputArgumentsIssue(OSInAppBrowserTarget.SYSTEM_BROWSER))
7748
// Try closing active router before continuing to open
7849
close {
7950
val customTabsOptions = buildCustomTabsOptions(options)
80-
8151
val customTabsRouter = OSIABCustomTabsRouterAdapter(
8252
context = context,
8353
lifecycleScope = activity.lifecycleScope,
@@ -90,41 +60,21 @@ class InAppBrowserPlugin : Plugin() {
9060
notifyListeners(OSIABEventType.BROWSER_FINISHED.value, null)
9161
}
9262
)
93-
9463
engine?.openCustomTabs(customTabsRouter, url) { success ->
95-
if (success) {
96-
activeRouter = customTabsRouter
97-
call.resolve()
98-
} else {
99-
sendErrorResult(call, OSInAppBrowserError.OpenFailed(url, OSInAppBrowserTarget.SYSTEM_BROWSER))
100-
}
64+
if (success) activeRouter = customTabsRouter
65+
handleBrowserResult(call, success, url, OSInAppBrowserTarget.SYSTEM_BROWSER)
10166
}
10267
}
103-
} catch (e: Exception) {
104-
sendErrorResult(call, OSInAppBrowserError.OpenFailed(url, OSInAppBrowserTarget.SYSTEM_BROWSER))
10568
}
10669
}
10770

10871
@PluginMethod
10972
fun openInWebView(call: PluginCall) {
110-
val url = call.getString("url")
111-
val options = call.getObject("options")
112-
113-
if (url.isNullOrEmpty() || options == null) {
114-
sendErrorResult(call, OSInAppBrowserError.InputArgumentsIssue(OSInAppBrowserTarget.WEB_VIEW))
115-
return
116-
}
117-
118-
if (!isSchemeValid(url)) {
119-
sendErrorResult(call, OSInAppBrowserError.InvalidURL)
120-
return
121-
}
122-
123-
try {
124-
// Try closing active router before continuing to open
73+
handleBrowserCall(call, OSInAppBrowserTarget.WEB_VIEW) { url ->
74+
val options = call.getObject("options")
75+
?: return@handleBrowserCall sendErrorResult(call, OSInAppBrowserError.InputArgumentsIssue(OSInAppBrowserTarget.WEB_VIEW))
12576
close {
12677
val webViewOptions = buildWebViewOptions(options)
127-
12878
val webViewRouter = OSIABWebViewRouterAdapter(
12979
context = context,
13080
lifecycleScope = activity.lifecycleScope,
@@ -135,22 +85,20 @@ class InAppBrowserPlugin : Plugin() {
13585
},
13686
onBrowserFinished = {
13787
notifyListeners(OSIABEventType.BROWSER_FINISHED.value, null)
88+
},
89+
onBrowserPageNavigationCompleted = {
90+
notifyListeners(
91+
OSIABEventType.BROWSER_PAGE_NAVIGATION_COMPLETED.value,
92+
JSObject().put("url", it)
93+
)
13894
}
13995
)
140-
14196
engine?.openWebView(webViewRouter, url) { success ->
142-
if (success) {
143-
activeRouter = webViewRouter
144-
call.resolve()
145-
} else {
146-
sendErrorResult(call, OSInAppBrowserError.OpenFailed(url, OSInAppBrowserTarget.WEB_VIEW))
147-
}
97+
if (success) activeRouter = webViewRouter
98+
handleBrowserResult(call, success, url, OSInAppBrowserTarget.WEB_VIEW)
14899
}
149100
}
150-
} catch (e: Exception) {
151-
sendErrorResult(call, OSInAppBrowserError.OpenFailed(url, OSInAppBrowserTarget.WEB_VIEW))
152101
}
153-
154102
}
155103

156104
@PluginMethod
@@ -175,43 +123,54 @@ class InAppBrowserPlugin : Plugin() {
175123
} ?: callback(false)
176124
}
177125

126+
private fun handleBrowserCall(call: PluginCall, target: OSInAppBrowserTarget, action: (String) -> Unit) {
127+
val url = call.getString("url")
128+
if (url.isNullOrEmpty()) {
129+
sendErrorResult(call, OSInAppBrowserError.InputArgumentsIssue(target))
130+
return
131+
}
132+
if (!isSchemeValid(url)) {
133+
sendErrorResult(call, OSInAppBrowserError.InvalidURL)
134+
return
135+
}
136+
try {
137+
action(url)
138+
} catch (e: Exception) {
139+
sendErrorResult(call, OSInAppBrowserError.OpenFailed(url, target))
140+
}
141+
}
142+
143+
private fun handleBrowserResult(call: PluginCall, success: Boolean, url: String, target: OSInAppBrowserTarget) {
144+
if (success) {
145+
call.resolve()
146+
} else {
147+
sendErrorResult(call, OSInAppBrowserError.OpenFailed(url, target))
148+
}
149+
}
150+
178151
/**
179152
* Parses options that come in a JSObject to create a 'OSIABWebViewOptions' object.
180153
* @param options The options to open the URL in a WebView.
181154
*/
182155
private fun buildWebViewOptions(options: JSObject): OSIABWebViewOptions {
183156
return options.let {
184-
val showURL = it.getBoolean("showURL", true) ?: true
185-
val showToolbar = it.getBoolean("showToolbar", true) ?: true
186-
val clearCache = it.getBoolean("clearCache", true) ?: true
187-
val clearSessionCache = it.getBoolean("clearSessionCache", true) ?: true
188-
val mediaPlaybackRequiresUserAction = it.getBoolean("mediaPlaybackRequiresUserAction", false) ?: false
189-
val closeButtonText = it.getString("closeButtonText") ?: "Close"
190-
val toolbarPosition = it.getInteger("toolbarPosition")?.let { ordinal ->
191-
OSIABToolbarPosition.entries[ordinal]
192-
} ?: OSIABToolbarPosition.TOP
193-
val leftToRight = it.getBoolean("leftToRight", false) ?: false
194-
val showNavigationButtons = it.getBoolean("showNavigationButtons", false) ?: false
195-
val customWebViewAgent = it.getString("customWebViewUserAgent", null) ?: null
196157
val androidOptions = it.getJSObject("android")
197-
val allowZoom = androidOptions?.getBoolean("allowZoom", true) ?: true
198-
val hardwareBack = androidOptions?.getBoolean("hardwareBack", true) ?: true
199-
val pauseMedia = androidOptions?.getBoolean("pauseMedia", true) ?: true
200-
201158
OSIABWebViewOptions(
202-
showURL,
203-
showToolbar,
204-
clearCache,
205-
clearSessionCache,
206-
mediaPlaybackRequiresUserAction,
207-
closeButtonText,
208-
toolbarPosition,
209-
leftToRight,
210-
showNavigationButtons,
211-
allowZoom,
212-
hardwareBack,
213-
pauseMedia,
214-
customWebViewAgent
159+
showURL = it.getBoolean("showURL", true) ?: true,
160+
showToolbar = it.getBoolean("showToolbar", true) ?: true,
161+
clearCache = it.getBoolean("clearCache", true) ?: true,
162+
clearSessionCache = it.getBoolean("clearSessionCache", true) ?: true,
163+
mediaPlaybackRequiresUserAction = it.getBoolean("mediaPlaybackRequiresUserAction", false) ?: false,
164+
closeButtonText = it.getString("closeButtonText") ?: "Close",
165+
toolbarPosition = it.getInteger("toolbarPosition")?.let { ordinal ->
166+
OSIABToolbarPosition.entries[ordinal]
167+
} ?: OSIABToolbarPosition.TOP,
168+
leftToRight = it.getBoolean("leftToRight", false) ?: false,
169+
showNavigationButtons = it.getBoolean("showNavigationButtons", false) ?: false,
170+
allowZoom = androidOptions?.getBoolean("allowZoom", true) ?: true,
171+
hardwareBack = androidOptions?.getBoolean("hardwareBack", true) ?: true,
172+
pauseMedia = androidOptions?.getBoolean("pauseMedia", true) ?: true,
173+
customUserAgent = it.getString("customWebViewUserAgent", null)
215174
)
216175
}
217176
}
@@ -222,38 +181,21 @@ class InAppBrowserPlugin : Plugin() {
222181
*/
223182
private fun buildCustomTabsOptions(options: JSObject): OSIABCustomTabsOptions {
224183
val optionsJson = options.getJSObject("android")
225-
226-
return optionsJson.let {
227-
val showTitle = it?.getBoolean("showTitle", true) ?: true
228-
val hideToolbarOnScroll = it?.getBoolean("hideToolbarOnScroll", false) ?: false
229-
val viewStyle = it?.getInteger("viewStyle")?.let { ordinal ->
230-
OSIABViewStyle.entries[ordinal]
231-
} ?: OSIABViewStyle.FULL_SCREEN
232-
233-
val bottomSheetOptions = it?.getJSObject("bottomSheetOptions")?.let { json ->
234-
val height = json.getInteger("height", 1) ?: 1
235-
val isFixed = json.getBoolean("isFixed", false) ?: false
236-
237-
OSIABBottomSheet(height, isFixed)
238-
}
239-
240-
val startAnimation = it?.getInteger("startAnimation")?.let { ordinal ->
241-
OSIABAnimation.entries[ordinal]
242-
} ?: OSIABAnimation.FADE_IN
243-
244-
val exitAnimation = it?.getInteger("exitAnimation")?.let { ordinal ->
245-
OSIABAnimation.entries[ordinal]
246-
} ?: OSIABAnimation.FADE_OUT
247-
248-
OSIABCustomTabsOptions(
249-
showTitle = showTitle,
250-
hideToolbarOnScroll = hideToolbarOnScroll,
251-
viewStyle = viewStyle,
252-
bottomSheetOptions = bottomSheetOptions,
253-
startAnimation = startAnimation,
254-
exitAnimation = exitAnimation
255-
)
256-
}
184+
return OSIABCustomTabsOptions(
185+
showTitle = optionsJson?.getBoolean("showTitle", true) ?: true,
186+
hideToolbarOnScroll = optionsJson?.getBoolean("hideToolbarOnScroll", false) ?: false,
187+
viewStyle = optionsJson?.getInteger("viewStyle")?.let { OSIABViewStyle.entries[it] }
188+
?: OSIABViewStyle.FULL_SCREEN,
189+
bottomSheetOptions = optionsJson?.getJSObject("bottomSheetOptions")?.let {
190+
OSIABBottomSheet(
191+
height = it.getInteger("height", 1) ?: 1,
192+
isFixed = it.getBoolean("isFixed", false) ?: false
193+
)
194+
},
195+
startAnimation = optionsJson?.getInteger("startAnimation")?.let { OSIABAnimation.entries[it] }
196+
?: OSIABAnimation.FADE_IN,
197+
exitAnimation = optionsJson?.getInteger("exitAnimation")?.let { OSIABAnimation.entries[it] } ?: OSIABAnimation.FADE_OUT
198+
)
257199
}
258200

259201
/**
@@ -272,11 +214,10 @@ class InAppBrowserPlugin : Plugin() {
272214
private fun sendErrorResult(call: PluginCall, error: OSInAppBrowserError) {
273215
call.reject(error.message, error.code)
274216
}
275-
276-
277217
}
278218

279219
enum class OSIABEventType(val value: String) {
280220
BROWSER_FINISHED("browserClosed"),
281-
BROWSER_PAGE_LOADED("browserPageLoaded")
221+
BROWSER_PAGE_LOADED("browserPageLoaded"),
222+
BROWSER_PAGE_NAVIGATION_COMPLETED("browserPageNavigationCompleted")
282223
}

example-app/src/pages/Home.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { IonButton, IonContent, IonHeader, IonInput, IonPage, IonTitle, IonToolbar } from '@ionic/react';
2-
import { InAppBrowser, DefaultSystemBrowserOptions, DefaultWebViewOptions, DefaultAndroidWebViewOptions, DismissStyle, iOSViewStyle, iOSAnimation, ToolbarPosition, AndroidViewStyle, AndroidAnimation } from '@capacitor/inappbrowser';
2+
import { InAppBrowser, DefaultSystemBrowserOptions, DefaultWebViewOptions, DefaultAndroidWebViewOptions, DismissStyle, iOSViewStyle, iOSAnimation, ToolbarPosition, AndroidViewStyle, AndroidAnimation, BrowserPageNavigationCompletedEventData } from '@capacitor/inappbrowser';
33
import './Home.css';
44

55
const Home: React.FC = () => {
66

7-
const test = () => {
7+
const openInExternalBrowser = () => {
88
InAppBrowser.openInExternalBrowser({
99
url: "https://www.google.com"
1010
});
@@ -153,6 +153,10 @@ const Home: React.FC = () => {
153153
console.log("browser was loaded.");
154154
});
155155

156+
InAppBrowser.addListener('browserPageNavigationCompleted', (data: BrowserPageNavigationCompletedEventData) => {
157+
console.log("browser page navigation was completed. " + data.url);
158+
});
159+
156160
return (
157161
<IonPage>
158162
<IonHeader>
@@ -167,7 +171,7 @@ const Home: React.FC = () => {
167171
</IonToolbar>
168172
</IonHeader>
169173
<div>
170-
<IonButton onClick={test}>TEST</IonButton>
174+
<IonButton onClick={openInExternalBrowser}>External Browser</IonButton>
171175
<IonButton onClick={openInSystemBrowserWithDefaults}>System Browser with Defaults</IonButton>
172176
<IonButton onClick={openInSystemBrowserWithCustomValues}>System Browser with Custom Values</IonButton>
173177
<IonButton onClick={openInWebViewWithDefaults}>Web View with Defaults</IonButton>

0 commit comments

Comments
 (0)