react-native-inappbrowser-reborn
Advanced tools
Comparing version 3.4.0 to 3.5.0
@@ -25,2 +25,16 @@ # Changelog | ||
## [3.5.0] - 2020-10-16 | ||
### Added | ||
- Added `hasBackButton` option to sets a back arrow instead of the default X icon to close the custom tab by [@aitorct](https://github.com/aitorct) ([#109](https://github.com/proyecto26/react-native-inappbrowser/pull/109)). | ||
- Added default browser configuration for custom tab if any by [@thuongtv-vn](https://github.com/thuongtv-vn) ([#177](https://github.com/proyecto26/react-native-inappbrowser/pull/177)). | ||
- Added `browserPackage` option to use a Package name of a browser to be used to handle Custom Tabs. | ||
- Added `showInRecents` option to determine whether browsed website should be shown as separate entry in Android recents/multitasking view. | ||
### Fixed | ||
- Android `isAvailable` method checks **Custom Tab** support by [@aitorct](https://github.com/aitorct) ([#108](https://github.com/proyecto26/react-native-inappbrowser/pull/108)). | ||
- Added a null check for `redirectResolve` in `safariViewControllerDidFinish` by [@ssuchanowski](https://github.com/ssuchanowski) ([#160](https://github.com/proyecto26/react-native-inappbrowser/pull/160)). | ||
- Fixed **README** updating `modalPresentationStyle` to **fullscreen** by [@Thomazella](https://github.com/Thomazella) ([#161](https://github.com/proyecto26/react-native-inappbrowser/pull/161)). | ||
- Fixed `AppStateActiveOnce` event listener by [@logangouget](https://github.com/logangouget) ([#179](https://github.com/proyecto26/react-native-inappbrowser/pull/179)). | ||
## [3.4.0] - 2020-04-08 | ||
@@ -30,6 +44,6 @@ | ||
- Added `ephemeralWebSession` option to supports `ephemeralWebBrowserSession` on iOS 13 by [@avenner](https://github.com/avenner) ([#141](https://github.com/proyecto26/react-native-inappbrowser/pull/141)). | ||
- Add `@ReactModule` annotation by [@janicduplessis](https://github.com/janicduplessis) ([#94](https://github.com/proyecto26/react-native-inappbrowser/pull/94)). | ||
- Added `@ReactModule` annotation by [@janicduplessis](https://github.com/janicduplessis) ([#94](https://github.com/proyecto26/react-native-inappbrowser/pull/94)). | ||
### Fixed | ||
- Remove listener of `openAuth` when `closeAuth` is called. | ||
- Removed listener of `openAuth` when `closeAuth` is called. | ||
@@ -44,3 +58,3 @@ ## [3.3.4] - 2020-01-07 | ||
### Fixed | ||
- Remove build warnings with **iOS** 13 using [Pragmas](https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas). | ||
- Removed build warnings with **iOS** 13 using [Pragmas](https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas). | ||
@@ -97,3 +111,3 @@ ## [3.3.2] - 2019-11-15 | ||
- Present the **SafariViewController** modally or as push instead using the `modalEnabled` property ([4a0d57c](https://github.com/proyecto26/react-native-inappbrowser/commit/4a0d57c73eccaaf45a212853c50aa41520b550c8)). | ||
- Add workaround to dismiss **SafariViewController** without animation. | ||
- Added workaround to dismiss **SafariViewController** without animation. | ||
@@ -122,3 +136,3 @@ ### Removed | ||
### Fixed | ||
- Add `customTabsIntent.startAnimationBundle` when the `ChromeTabsManagerActivity` intent is created to fix **Android** animations by [@miktolon](https://github.com/miktolon) ([3f0cb35](https://github.com/proyecto26/react-native-inappbrowser/commit/3f0cb356733832a4578ebf1cb45377aa0d8d2806)). | ||
- Added `customTabsIntent.startAnimationBundle` when the `ChromeTabsManagerActivity` intent is created to fix **Android** animations by [@miktolon](https://github.com/miktolon) ([3f0cb35](https://github.com/proyecto26/react-native-inappbrowser/commit/3f0cb356733832a4578ebf1cb45377aa0d8d2806)). | ||
@@ -154,3 +168,3 @@ ### Changed | ||
- Provide example how to restore old status bar style by [@MrLoh](https://github.com/MrLoh) ([8cb9e75](https://github.com/proyecto26/react-native-inappbrowser/commit/8cb9e7535a3edb0d9919eab7813bf5f136f455ff)). | ||
- Add `com.facebook.infer.annotation` dependecy to fix build error by [Artem Emelyanov](mailto:snainer@gmail.com) ([80ff313](https://github.com/proyecto26/react-native-inappbrowser/commit/80ff313c36911d4d82d2885ad8424d7f0f72de29)). | ||
- Added `com.facebook.infer.annotation` dependecy to fix build error by [Artem Emelyanov](mailto:snainer@gmail.com) ([80ff313](https://github.com/proyecto26/react-native-inappbrowser/commit/80ff313c36911d4d82d2885ad8424d7f0f72de29)). | ||
- Clear `mOpenBrowserPromise` after sending a cancel by [@rbscott](https://github.com/rbscott) ([d9cc2a3](https://github.com/proyecto26/react-native-inappbrowser/commit/d9cc2a3183f84790deb22bf01f4f7658d67bc8ca)). | ||
@@ -163,3 +177,4 @@ - Fix README to import native package in `MainApplication` instead of `MainActivity` by [@mammad2c](https://github.com/mammad2c) ([ce3f5a9](https://github.com/proyecto26/react-native-inappbrowser/commit/ce3f5a93812a1a2dd7293092bb4a2972f4943268)). | ||
[Unreleased]: https://github.com/proyecto26/react-native-inappbrowser/compare/v3.4.0...HEAD | ||
[Unreleased]: https://github.com/proyecto26/react-native-inappbrowser/compare/v3.5.0...HEAD | ||
[3.5.0]: https://github.com/proyecto26/react-native-inappbrowser/compare/v3.4.0...v3.5.0 | ||
[3.4.0]: https://github.com/proyecto26/react-native-inappbrowser/compare/v3.3.4...v3.4.0 | ||
@@ -166,0 +181,0 @@ [3.3.4]: https://github.com/proyecto26/react-native-inappbrowser/compare/v3.3.3...v3.3.4 |
@@ -55,3 +55,5 @@ declare module 'react-native-inappbrowser-reborn' { | ||
}, | ||
headers?: { [key: string]: string } | ||
headers?: { [key: string]: string }, | ||
browserPackage?: string, | ||
showInRecents?: boolean | ||
} | ||
@@ -63,3 +65,3 @@ | ||
interface RNInAppBrowserClassMethods { | ||
interface InAppBrowserClassMethods { | ||
open: ( | ||
@@ -79,5 +81,5 @@ url: string, | ||
const RNInAppBrowser: RNInAppBrowserClassMethods; | ||
export const InAppBrowser: InAppBrowserClassMethods; | ||
export default RNInAppBrowser; | ||
export default InAppBrowser; | ||
} |
227
index.js
@@ -9,124 +9,42 @@ /** | ||
import invariant from 'invariant'; | ||
import type { | ||
BrowserResult, | ||
AuthSessionResult, | ||
InAppBrowserOptions, | ||
} from './types'; | ||
import { | ||
Linking, | ||
NativeModules, | ||
Platform, | ||
processColor, | ||
AppState, | ||
AppStateStatus, | ||
} from 'react-native'; | ||
RNInAppBrowser, | ||
openBrowserAsync, | ||
openAuthSessionAsync, | ||
openAuthSessionPolyfillAsync, | ||
closeAuthSessionPolyfillAsync, | ||
authSessionIsNativelySupported, | ||
} from './utils'; | ||
const { RNInAppBrowser } = NativeModules; | ||
type RedirectEvent = { | ||
url: 'string', | ||
}; | ||
type BrowserResult = { | ||
type: 'cancel' | 'dismiss', | ||
}; | ||
type RedirectResult = { | ||
type: 'success', | ||
url: string, | ||
}; | ||
type InAppBrowseriOSOptions = { | ||
dismissButtonStyle?: 'done' | 'close' | 'cancel', | ||
preferredBarTintColor?: string, | ||
preferredControlTintColor?: string, | ||
readerMode?: boolean, | ||
animated?: boolean, | ||
modalPresentationStyle?: | ||
| 'automatic' | ||
| 'fullScreen' | ||
| 'pageSheet' | ||
| 'formSheet' | ||
| 'currentContext' | ||
| 'custom' | ||
| 'overFullScreen' | ||
| 'overCurrentContext' | ||
| 'popover' | ||
| 'none', | ||
modalTransitionStyle?: | ||
| 'coverVertical' | ||
| 'flipHorizontal' | ||
| 'crossDissolve' | ||
| 'partialCurl', | ||
modalEnabled?: boolean, | ||
enableBarCollapsing?: boolean, | ||
ephemeralWebSession?: boolean, | ||
}; | ||
type InAppBrowserAndroidOptions = { | ||
showTitle?: boolean, | ||
toolbarColor?: string, | ||
secondaryToolbarColor?: string, | ||
enableUrlBarHiding?: boolean, | ||
enableDefaultShare?: boolean, | ||
forceCloseOnRedirection?: boolean, | ||
animations?: { | ||
startEnter: string, | ||
startExit: string, | ||
endEnter: string, | ||
endExit: string, | ||
}, | ||
headers?: { [key: string]: string }, | ||
}; | ||
type InAppBrowserOptions = InAppBrowserAndroidOptions | InAppBrowseriOSOptions; | ||
async function open( | ||
url: string, | ||
options: InAppBrowserOptions = {} | ||
options?: InAppBrowserOptions | ||
): Promise<BrowserResult> { | ||
const inAppBrowserOptions = { | ||
...options, | ||
url, | ||
dismissButtonStyle: options.dismissButtonStyle || 'close', | ||
readerMode: !!options.readerMode, | ||
animated: options.animated !== undefined ? options.animated : true, | ||
modalEnabled: | ||
options.modalEnabled !== undefined ? options.modalEnabled : true, | ||
enableBarCollapsing: !!options.enableBarCollapsing, | ||
preferredBarTintColor: | ||
options.preferredBarTintColor && | ||
processColor(options.preferredBarTintColor), | ||
preferredControlTintColor: | ||
options.preferredControlTintColor && | ||
processColor(options.preferredControlTintColor), | ||
}; | ||
return RNInAppBrowser.open(inAppBrowserOptions); | ||
return openBrowserAsync(url, options); | ||
} | ||
function close(): void { | ||
RNInAppBrowser.close(); | ||
} | ||
type AuthSessionResult = RedirectResult | BrowserResult; | ||
async function openAuth( | ||
url: string, | ||
redirectUrl: string, | ||
options: InAppBrowserOptions = {} | ||
options?: InAppBrowserOptions | ||
): Promise<AuthSessionResult> { | ||
const inAppBrowserOptions = { | ||
...options, | ||
ephemeralWebSession: | ||
options.ephemeralWebSession !== undefined | ||
? options.ephemeralWebSession | ||
: false, | ||
}; | ||
if (_authSessionIsNativelySupported()) { | ||
return RNInAppBrowser.openAuth(url, redirectUrl, inAppBrowserOptions); | ||
if (authSessionIsNativelySupported()) { | ||
return openAuthSessionAsync(url, redirectUrl, options); | ||
} else { | ||
return _openAuthSessionPolyfillAsync(url, redirectUrl, inAppBrowserOptions); | ||
return openAuthSessionPolyfillAsync(url, redirectUrl, options); | ||
} | ||
} | ||
function close(): void { | ||
RNInAppBrowser.close(); | ||
} | ||
function closeAuth(): void { | ||
closeAuthSessionPolyfillAsync(); | ||
if (_authSessionIsNativelySupported()) { | ||
if (authSessionIsNativelySupported()) { | ||
RNInAppBrowser.closeAuth(); | ||
@@ -138,100 +56,7 @@ } else { | ||
/* iOS <= 10 and Android polyfill for SFAuthenticationSession flow */ | ||
function _authSessionIsNativelySupported() { | ||
if (Platform.OS === 'android') { | ||
return false; | ||
} | ||
const versionNumber = parseInt(Platform.Version, 10); | ||
return versionNumber >= 11; | ||
} | ||
let _redirectHandler: ?(event: RedirectEvent) => void; | ||
function closeAuthSessionPolyfillAsync(): void { | ||
if (_redirectHandler) { | ||
Linking.removeEventListener('url', _redirectHandler); | ||
_redirectHandler = null; | ||
} | ||
} | ||
async function _openAuthSessionPolyfillAsync( | ||
startUrl: string, | ||
returnUrl: string, | ||
options: InAppBrowserOptions | ||
): Promise<AuthSessionResult> { | ||
invariant( | ||
!_redirectHandler, | ||
'InAppBrowser.openAuth is in a bad state. _redirectHandler is defined when it should not be.' | ||
); | ||
let response = null; | ||
try { | ||
response = await Promise.race([ | ||
_waitForRedirectAsync(returnUrl), | ||
open(startUrl, options).then(function (result) { | ||
return _checkResultAndReturnUrl(returnUrl, result); | ||
}), | ||
]); | ||
} finally { | ||
closeAuthSessionPolyfillAsync(); | ||
close(); | ||
} | ||
return response; | ||
} | ||
function _waitForRedirectAsync(returnUrl: string): Promise<RedirectResult> { | ||
return new Promise(function (resolve) { | ||
_redirectHandler = (event: RedirectEvent) => { | ||
if (event.url && event.url.startsWith(returnUrl)) { | ||
resolve({ url: event.url, type: 'success' }); | ||
} | ||
}; | ||
Linking.addEventListener('url', _redirectHandler); | ||
}); | ||
} | ||
/** | ||
* Detect Android Activity `OnResume` event once | ||
*/ | ||
function AppStateActiveOnce(): Promise<void> { | ||
return new Promise(function (resolve) { | ||
function _handleAppStateChange(nextAppState: AppStateStatus) { | ||
if (nextAppState === 'active') { | ||
AppState.removeEventListener('change', _handleAppStateChange); | ||
resolve(); | ||
} | ||
} | ||
AppState.addEventListener('change', _handleAppStateChange); | ||
}); | ||
} | ||
async function _checkResultAndReturnUrl( | ||
returnUrl: string, | ||
result: AuthSessionResult | ||
): Promise<AuthSessionResult> { | ||
if (Platform.OS === 'android' && result.type !== 'cancel') { | ||
try { | ||
await AppStateActiveOnce(); | ||
const url = await Linking.getInitialURL(); | ||
return url && url.startsWith(returnUrl) | ||
? { url, type: 'success' } | ||
: result; | ||
} catch { | ||
return result; | ||
} | ||
} else { | ||
return result; | ||
} | ||
} | ||
async function isAvailable(): Promise<boolean> { | ||
if (Platform.OS === 'android') { | ||
return Promise.resolve(true); | ||
} else { | ||
return RNInAppBrowser.isAvailable(); | ||
} | ||
return RNInAppBrowser.isAvailable(); | ||
} | ||
export default { | ||
export const InAppBrowser = { | ||
open, | ||
@@ -243,1 +68,3 @@ openAuth, | ||
}; | ||
export default InAppBrowser; |
{ | ||
"name": "react-native-inappbrowser-reborn", | ||
"version": "3.4.0", | ||
"version": "3.5.0", | ||
"description": "InAppBrowser for React Native", | ||
@@ -55,8 +55,8 @@ "main": "index.js", | ||
"devDependencies": { | ||
"@react-native-community/eslint-config": "1.0.0", | ||
"@react-native-community/eslint-config": "2.0.0", | ||
"babel-core": "^6.26.3", | ||
"eslint": "^6.8.0", | ||
"flow-bin": "^0.122.0", | ||
"react": "16.11.0", | ||
"react-native": "0.62.1" | ||
"eslint": "^7.11.0", | ||
"flow-bin": "^0.135.0", | ||
"react": "16.13.1", | ||
"react-native": "0.63.3" | ||
}, | ||
@@ -63,0 +63,0 @@ "collective": { |
@@ -29,2 +29,3 @@ <p align="center"> | ||
<h1 align="center">InAppBrowser for React Native</h1> | ||
<h3 align="center">Provides access to the system's web browser and supports handling redirects</h3> | ||
<h4 align="center"><a href="https://developer.chrome.com/multidevice/android/customtabs#whatarethey">Chrome Custom Tabs</a> for Android & <a href="https://developer.apple.com/documentation/safariservices">SafariServices</a>/<a href="https://developer.apple.com/documentation/authenticationservices">AuthenticationServices</a> for iOS.</h4> | ||
@@ -161,2 +162,5 @@ | ||
`forceCloseOnRedirection` (Boolean) | Open Custom Tab in a new task to avoid issues redirecting back to app scheme. [`true`/`false`] | ||
`hasBackButton` (Boolean) | Sets a back arrow instead of the default `X` icon to close the custom tab. [`true`/`false`] | ||
`browserPackage` (String) | Package name of a browser to be used to handle Custom Tabs. | ||
`showInRecents` (Boolean) | Determining whether browsed website should be shown as separate entry in Android recents/multitasking view. [`true`/`false`] | ||
@@ -167,3 +171,3 @@ ### Demo | ||
import { Linking } from 'react-native' | ||
import InAppBrowser from 'react-native-inappbrowser-reborn' | ||
import { InAppBrowser } from 'react-native-inappbrowser-reborn' | ||
@@ -182,4 +186,4 @@ ... | ||
animated: true, | ||
modalPresentationStyle: 'overFullScreen', | ||
modalTransitionStyle: 'partialCurl', | ||
modalPresentationStyle: 'fullScreen', | ||
modalTransitionStyle: 'coverVertical', | ||
modalEnabled: true, | ||
@@ -293,3 +297,3 @@ enableBarCollapsing: false, | ||
import { Linking } from 'react-native' | ||
import InAppBrowser from 'react-native-inappbrowser-reborn' | ||
import { InAppBrowser } from 'react-native-inappbrowser-reborn' | ||
import { getDeepLink } from './utilities' | ||
@@ -330,3 +334,3 @@ ... | ||
// Play Lottie Animation :) | ||
// Validate the stored access token (Maybe with a request) | ||
@@ -351,3 +355,3 @@ // Redirect the user to the Home page if the token is still valid | ||
} | ||
async loadUserInfo() { | ||
@@ -469,4 +473,9 @@ const { navigation } = this.props | ||
Support [me](http://www.paypal.me/jdnichollsc/2), if you do too. | ||
[Professionally supported react-native-inappbrowser-reborn is coming soon](https://tidelift.com/subscription/pkg/npm-react-native-inappbrowser-reborn?utm_source=npm-react-native-inappbrowser-reborn&utm_medium=referral&utm_campaign=readme) | ||
## Enterprise 💼 | ||
Available as part of the Tidelift Subscription. | ||
The maintainers of InAppBrowser for React Native and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-react-native-inappbrowser-reborn?utm_source=npm-react-native-inappbrowser-reborn&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) | ||
## Security contact information 🚨 | ||
@@ -473,0 +482,0 @@ To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 8 instances in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
207799
56
480
132
9