From 644bd5af922d6ce60d26f338e28d8fbf5b8e8ba3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Boquet?= Date: Sat, 26 Aug 2023 11:53:26 +0200 Subject: [PATCH] Fix kotlin version --- __tests__/Alert.test.js | 25 - android/build.gradle | 2 +- apple/RNCWKProcessPoolManager.h | 15 - apple/RNCWKProcessPoolManager.m | 36 - apple/RNCWebView.h | 29 - apple/RNCWebView.mm | 528 ----- apple/RNCWebViewDecisionManager.h | 20 - apple/RNCWebViewDecisionManager.m | 47 - apple/RNCWebViewImpl.h | 149 -- apple/RNCWebViewImpl.m | 1832 ----------------- apple/RNCWebViewManager.h | 9 - apple/RNCWebViewManager.mm | 232 --- docs/Contributing.italian.md | 103 - docs/Contributing.md | 105 - docs/Contributing.portuguese.md | 103 - docs/Custom-Android.italian.md | 219 -- docs/Custom-Android.md | 222 -- docs/Custom-Android.portuguese.md | 224 -- docs/Custom-iOS.italian.md | 226 -- docs/Custom-iOS.md | 237 --- docs/Custom-iOS.portuguese.md | 236 --- docs/Debugging.italian.md | 97 - docs/Debugging.md | 91 - docs/Debugging.portuguese.md | 102 - docs/Getting-Started.italian.md | 132 -- docs/Getting-Started.md | 142 -- docs/Getting-Started.portuguese.md | 131 -- docs/Guide.italian.md | 573 ------ docs/Guide.md | 614 ------ docs/Guide.portuguese.md | 553 ----- docs/README.french.md | 78 - docs/README.italian.md | 63 - docs/README.portuguese.md | 109 - docs/Reference.italian.md | 1591 -------------- docs/Reference.md | 1754 ---------------- docs/Reference.portuguese.md | 1624 --------------- example/.gitignore | 14 - example/.watchmanconfig | 1 - example/App.tsx | 304 --- example/android/build.gradle | 15 - example/android/gradle.properties | 45 - .../android/gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - example/android/gradlew | 234 --- example/android/gradlew.bat | 89 - example/android/settings.gradle | 12 - example/app.json | 31 - example/assets/test.html | 9 - example/babel.config.js | 3 - example/examples/Alerts.tsx | 72 - example/examples/ApplePay.tsx | 23 - example/examples/Background.tsx | 54 - example/examples/CustomMenu.tsx | 88 - example/examples/Downloads.tsx | 57 - example/examples/Injection.tsx | 161 -- example/examples/LocalPageLoad.tsx | 16 - example/examples/Messaging.tsx | 73 - example/examples/NativeWebpage.tsx | 29 - example/examples/OpenWindow.tsx | 132 -- example/examples/Scrolling.tsx | 68 - example/examples/Suppress.tsx | 46 - example/examples/Uploads.tsx | 69 - example/index.js | 9 - example/ios/.xcode.env | 1 - example/ios/Podfile | 8 - example/ios/Podfile.lock | 491 ----- example/macos/Podfile | 5 - example/macos/Podfile.lock | 509 ----- example/windows/.gitignore | 34 - example/windows/ExperimentalFeatures.props | 38 - example/windows/Package.appxmanifest | 49 - jest-setups/jest.setup.js | 14 - jest-setups/jest.setup.windows.js | 1 - macos/RNCWebView.xcodeproj/project.pbxproj | 363 ---- windows/.gitignore | 353 ---- windows/ExperimentalFeatures.props | 11 - windows/ReactNativeWebView.sln | 185 -- .../ReactNativeWebView/PropertySheet.props | 16 - .../ReactNativeWebView/ReactNativeWebView.def | 3 - .../ReactNativeWebView.filters | 33 - .../ReactNativeWebView.vcxproj | 198 -- .../ReactPackageProvider.cpp | 22 - .../ReactNativeWebView/ReactPackageProvider.h | 20 - .../ReactPackageProvider.idl | 7 - windows/ReactNativeWebView/ReactWebView.cpp | 175 -- windows/ReactNativeWebView/ReactWebView.h | 46 - windows/ReactNativeWebView/ReactWebView.idl | 22 - windows/ReactNativeWebView/ReactWebView2.cpp | 308 --- windows/ReactNativeWebView/ReactWebView2.h | 54 - .../ReactWebView2Manager.cpp | 179 -- .../ReactNativeWebView/ReactWebView2Manager.h | 57 - .../ReactWebViewManager.cpp | 205 -- .../ReactNativeWebView/ReactWebViewManager.h | 53 - windows/ReactNativeWebView/WebBridge.cpp | 19 - windows/ReactNativeWebView/WebBridge.h | 24 - windows/ReactNativeWebView/WebBridge.idl | 11 - windows/ReactNativeWebView/packages.config | 5 - windows/ReactNativeWebView/pch.cpp | 1 - windows/ReactNativeWebView/pch.h | 33 - 99 files changed, 1 insertion(+), 17464 deletions(-) delete mode 100644 __tests__/Alert.test.js delete mode 100644 apple/RNCWKProcessPoolManager.h delete mode 100644 apple/RNCWKProcessPoolManager.m delete mode 100644 apple/RNCWebView.h delete mode 100644 apple/RNCWebView.mm delete mode 100644 apple/RNCWebViewDecisionManager.h delete mode 100644 apple/RNCWebViewDecisionManager.m delete mode 100644 apple/RNCWebViewImpl.h delete mode 100644 apple/RNCWebViewImpl.m delete mode 100644 apple/RNCWebViewManager.h delete mode 100644 apple/RNCWebViewManager.mm delete mode 100644 docs/Contributing.italian.md delete mode 100644 docs/Contributing.md delete mode 100644 docs/Contributing.portuguese.md delete mode 100644 docs/Custom-Android.italian.md delete mode 100644 docs/Custom-Android.md delete mode 100644 docs/Custom-Android.portuguese.md delete mode 100644 docs/Custom-iOS.italian.md delete mode 100644 docs/Custom-iOS.md delete mode 100644 docs/Custom-iOS.portuguese.md delete mode 100644 docs/Debugging.italian.md delete mode 100644 docs/Debugging.md delete mode 100644 docs/Debugging.portuguese.md delete mode 100644 docs/Getting-Started.italian.md delete mode 100644 docs/Getting-Started.md delete mode 100644 docs/Getting-Started.portuguese.md delete mode 100644 docs/Guide.italian.md delete mode 100644 docs/Guide.md delete mode 100644 docs/Guide.portuguese.md delete mode 100644 docs/README.french.md delete mode 100644 docs/README.italian.md delete mode 100644 docs/README.portuguese.md delete mode 100644 docs/Reference.italian.md delete mode 100644 docs/Reference.md delete mode 100644 docs/Reference.portuguese.md delete mode 100644 example/.gitignore delete mode 100644 example/.watchmanconfig delete mode 100644 example/App.tsx delete mode 100644 example/android/build.gradle delete mode 100644 example/android/gradle.properties delete mode 100644 example/android/gradle/wrapper/gradle-wrapper.jar delete mode 100644 example/android/gradle/wrapper/gradle-wrapper.properties delete mode 100755 example/android/gradlew delete mode 100644 example/android/gradlew.bat delete mode 100644 example/android/settings.gradle delete mode 100644 example/app.json delete mode 100644 example/assets/test.html delete mode 100644 example/babel.config.js delete mode 100644 example/examples/Alerts.tsx delete mode 100644 example/examples/ApplePay.tsx delete mode 100644 example/examples/Background.tsx delete mode 100644 example/examples/CustomMenu.tsx delete mode 100644 example/examples/Downloads.tsx delete mode 100644 example/examples/Injection.tsx delete mode 100644 example/examples/LocalPageLoad.tsx delete mode 100644 example/examples/Messaging.tsx delete mode 100644 example/examples/NativeWebpage.tsx delete mode 100644 example/examples/OpenWindow.tsx delete mode 100644 example/examples/Scrolling.tsx delete mode 100644 example/examples/Suppress.tsx delete mode 100644 example/examples/Uploads.tsx delete mode 100644 example/index.js delete mode 100644 example/ios/.xcode.env delete mode 100644 example/ios/Podfile delete mode 100644 example/ios/Podfile.lock delete mode 100644 example/macos/Podfile delete mode 100644 example/macos/Podfile.lock delete mode 100644 example/windows/.gitignore delete mode 100644 example/windows/ExperimentalFeatures.props delete mode 100644 example/windows/Package.appxmanifest delete mode 100644 jest-setups/jest.setup.js delete mode 100644 jest-setups/jest.setup.windows.js delete mode 100644 macos/RNCWebView.xcodeproj/project.pbxproj delete mode 100644 windows/.gitignore delete mode 100644 windows/ExperimentalFeatures.props delete mode 100644 windows/ReactNativeWebView.sln delete mode 100644 windows/ReactNativeWebView/PropertySheet.props delete mode 100644 windows/ReactNativeWebView/ReactNativeWebView.def delete mode 100644 windows/ReactNativeWebView/ReactNativeWebView.filters delete mode 100644 windows/ReactNativeWebView/ReactNativeWebView.vcxproj delete mode 100644 windows/ReactNativeWebView/ReactPackageProvider.cpp delete mode 100644 windows/ReactNativeWebView/ReactPackageProvider.h delete mode 100644 windows/ReactNativeWebView/ReactPackageProvider.idl delete mode 100644 windows/ReactNativeWebView/ReactWebView.cpp delete mode 100644 windows/ReactNativeWebView/ReactWebView.h delete mode 100644 windows/ReactNativeWebView/ReactWebView.idl delete mode 100644 windows/ReactNativeWebView/ReactWebView2.cpp delete mode 100644 windows/ReactNativeWebView/ReactWebView2.h delete mode 100644 windows/ReactNativeWebView/ReactWebView2Manager.cpp delete mode 100644 windows/ReactNativeWebView/ReactWebView2Manager.h delete mode 100644 windows/ReactNativeWebView/ReactWebViewManager.cpp delete mode 100644 windows/ReactNativeWebView/ReactWebViewManager.h delete mode 100644 windows/ReactNativeWebView/WebBridge.cpp delete mode 100644 windows/ReactNativeWebView/WebBridge.h delete mode 100644 windows/ReactNativeWebView/WebBridge.idl delete mode 100644 windows/ReactNativeWebView/packages.config delete mode 100644 windows/ReactNativeWebView/pch.cpp delete mode 100644 windows/ReactNativeWebView/pch.h diff --git a/__tests__/Alert.test.js b/__tests__/Alert.test.js deleted file mode 100644 index fd958e01b..000000000 --- a/__tests__/Alert.test.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - */ - -import { driver, By2 } from 'selenium-appium' - -const setup = require('../jest-setups/jest.setup'); -jest.setTimeout(150000); - -const WindowsApplicationDriverUrl = "http://127.0.0.1:4723/wd/hub"; - -describe('Alert Tests', () => { - - test('Show Alert', async () => { - await driver.startWithCapabilities(setup.capabilities, WindowsApplicationDriverUrl); - const showAlertButton = By2.nativeName('Show alert'); - await showAlertButton.click(); - await By2.nativeName('Hello! I am an alert box!'); - // await By2.nativeName('OK').click(); All alerts will be automatically dismissed as Windows Webview does not have support for Alerts https://github.com/MicrosoftDocs/winrt-api/blob/docs/windows.ui.xaml.controls/webview.md#use-of-alert - const dismissMessage = By2.nativeName('Alert dismissed!'); - expect(dismissMessage).not.toBeNull(); - await driver.quit(); - }); -}); \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index 3e0dcbcb2..2f13ae95f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -9,7 +9,7 @@ buildscript { gradlePluginPortal() } dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion')}") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.20") classpath("com.android.tools.build:gradle:7.0.4") } } diff --git a/apple/RNCWKProcessPoolManager.h b/apple/RNCWKProcessPoolManager.h deleted file mode 100644 index 6d2d2158c..000000000 --- a/apple/RNCWKProcessPoolManager.h +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import - -@interface RNCWKProcessPoolManager : NSObject - -+ (instancetype) sharedManager; -- (WKProcessPool *)sharedProcessPool; - -@end diff --git a/apple/RNCWKProcessPoolManager.m b/apple/RNCWKProcessPoolManager.m deleted file mode 100644 index 2b38ffe22..000000000 --- a/apple/RNCWKProcessPoolManager.m +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import -#import "RNCWKProcessPoolManager.h" - -@interface RNCWKProcessPoolManager() { - WKProcessPool *_sharedProcessPool; -} -@end - -@implementation RNCWKProcessPoolManager - -+ (id) sharedManager { - static RNCWKProcessPoolManager *_sharedManager = nil; - @synchronized(self) { - if(_sharedManager == nil) { - _sharedManager = [[super alloc] init]; - } - return _sharedManager; - } -} - -- (WKProcessPool *)sharedProcessPool { - if (!_sharedProcessPool) { - _sharedProcessPool = [[WKProcessPool alloc] init]; - } - return _sharedProcessPool; -} - -@end - diff --git a/apple/RNCWebView.h b/apple/RNCWebView.h deleted file mode 100644 index d359365e0..000000000 --- a/apple/RNCWebView.h +++ /dev/null @@ -1,29 +0,0 @@ -// This guard prevent this file to be compiled in the old architecture. -#ifdef RCT_NEW_ARCH_ENABLED -#import -#import -#import -#import -#import - -#ifndef NativeComponentExampleComponentView_h -#define NativeComponentExampleComponentView_h - -NS_ASSUME_NONNULL_BEGIN - -@interface RNCWebView : RCTViewComponentView -@end - -namespace facebook { -namespace react { - bool operator==(const RNCWebViewMenuItemsStruct& a, const RNCWebViewMenuItemsStruct& b) - { - return b.key == a.key && b.label == a.label; - } -} -} - -NS_ASSUME_NONNULL_END - -#endif /* NativeComponentExampleComponentView_h */ -#endif /* RCT_NEW_ARCH_ENABLED */ diff --git a/apple/RNCWebView.mm b/apple/RNCWebView.mm deleted file mode 100644 index 70d5ee4c8..000000000 --- a/apple/RNCWebView.mm +++ /dev/null @@ -1,528 +0,0 @@ -// This guard prevent the code from being compiled in the old architecture -#ifdef RCT_NEW_ARCH_ENABLED -#import "RNCWebView.h" -#import "RNCWebViewImpl.h" - -#import -#import -#import -#import - -#import "RCTFabricComponentsPlugins.h" - -using namespace facebook::react; - -auto stringToOnShouldStartLoadWithRequestNavigationTypeEnum(std::string value) { - if (value == "click") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Click; - if (value == "formsubmit") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Formsubmit; - if (value == "backforward") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Backforward; - if (value == "reload") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Reload; - if (value == "formresubmit") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Formresubmit; - return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Other; -} - -auto stringToOnLoadingStartNavigationTypeEnum(std::string value) { - if (value == "click") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Click; - if (value == "formsubmit") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Formsubmit; - if (value == "backforward") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Backforward; - if (value == "reload") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Reload; - if (value == "formresubmit") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Formresubmit; - return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Other; -} - -auto stringToOnLoadingFinishNavigationTypeEnum(std::string value) { - if (value == "click") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Click; - if (value == "formsubmit") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Formsubmit; - if (value == "backforward") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Backforward; - if (value == "reload") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Reload; - if (value == "formresubmit") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Formresubmit; - return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Other; -} - -@interface RNCWebView () - -@end - -@implementation RNCWebView { - RNCWebViewImpl * _view; -} - -+ (ComponentDescriptorProvider)componentDescriptorProvider -{ - return concreteComponentDescriptorProvider(); -} - -// Reproduce the idea from here: https://github.com/facebook/react-native/blob/8bd3edec88148d0ab1f225d2119435681fbbba33/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryComponentView.mm#L142 -- (void)prepareForRecycle { - [super prepareForRecycle]; - [_view destroyWebView]; -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - - _view = [[RNCWebViewImpl alloc] init]; - - _view.onShouldStartLoadWithRequest = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnShouldStartLoadWithRequest data = { - .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), - .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], - .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), - .navigationType = stringToOnShouldStartLoadWithRequestNavigationTypeEnum(std::string([[dictionary valueForKey:@"navigationType"] UTF8String])), - .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], - .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], - .isTopFrame = [[dictionary valueForKey:@"isTopFrame"] boolValue], - .loading = [[dictionary valueForKey:@"loading"] boolValue], - .mainDocumentURL = std::string([[dictionary valueForKey:@"mainDocumentURL"] UTF8String]) - }; - webViewEventEmitter->onShouldStartLoadWithRequest(data); - }; - }; - _view.onLoadingStart = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnLoadingStart data = { - .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), - .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], - .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), - .navigationType = stringToOnLoadingStartNavigationTypeEnum(std::string([[dictionary valueForKey:@"navigationType"] UTF8String])), - .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], - .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], - .loading = [[dictionary valueForKey:@"loading"] boolValue], - .mainDocumentURL = std::string([[dictionary valueForKey:@"mainDocumentURL"] UTF8String], [[dictionary valueForKey:@"mainDocumentURL"] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) - }; - webViewEventEmitter->onLoadingStart(data); - } - }; - _view.onLoadingError = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnLoadingError data = { - .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), - .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], - .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), - .code = [[dictionary valueForKey:@"code"] intValue], - .description = std::string([[dictionary valueForKey:@"description"] UTF8String]), - .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], - .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], - .loading = [[dictionary valueForKey:@"loading"] boolValue], - .domain = std::string([[dictionary valueForKey:@"domain"] UTF8String]) - }; - webViewEventEmitter->onLoadingError(data); - } - }; - _view.onMessage = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnMessage data = { - .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), - .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], - .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), - .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], - .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], - .loading = [[dictionary valueForKey:@"loading"] boolValue], - .data = std::string([[dictionary valueForKey:@"data"] UTF8String]) - }; - webViewEventEmitter->onMessage(data); - } - }; - _view.onLoadingFinish = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnLoadingFinish data = { - .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), - .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], - .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), - .navigationType = stringToOnLoadingFinishNavigationTypeEnum(std::string([[dictionary valueForKey:@"navigationType"] UTF8String], [[dictionary valueForKey:@"navigationType"] lengthOfBytesUsingEncoding:NSUTF8StringEncoding])), - .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], - .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], - .loading = [[dictionary valueForKey:@"loading"] boolValue], - .mainDocumentURL = std::string([[dictionary valueForKey:@"mainDocumentURL"] UTF8String], [[dictionary valueForKey:@"mainDocumentURL"] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) - }; - webViewEventEmitter->onLoadingFinish(data); - } - }; - _view.onLoadingProgress = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnLoadingProgress data = { - .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), - .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], - .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), - .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], - .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], - .loading = [[dictionary valueForKey:@"loading"] boolValue], - .progress = [[dictionary valueForKey:@"progress"] doubleValue] - }; - webViewEventEmitter->onLoadingProgress(data); - } - }; - _view.onContentProcessDidTerminate = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnContentProcessDidTerminate data = { - .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), - .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], - .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), - .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], - .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], - .loading = [[dictionary valueForKey:@"loading"] boolValue] - }; - webViewEventEmitter->onContentProcessDidTerminate(data); - } - }; - _view.onCustomMenuSelection = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnCustomMenuSelection data = { - .selectedText = std::string([[dictionary valueForKey:@"selectedText"] UTF8String]), - .key = std::string([[dictionary valueForKey:@"key"] UTF8String]), - .label = std::string([[dictionary valueForKey:@"label"] UTF8String]) - - }; - webViewEventEmitter->onCustomMenuSelection(data); - } - }; - _view.onScroll = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - NSDictionary* contentOffset = [dictionary valueForKey:@"contentOffset"]; - NSDictionary* contentInset = [dictionary valueForKey:@"contentInset"]; - NSDictionary* contentSize = [dictionary valueForKey:@"contentSize"]; - NSDictionary* layoutMeasurement = [dictionary valueForKey:@"layoutMeasurement"]; - double zoomScale = [[dictionary valueForKey:@"zoomScale"] doubleValue]; - - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnScroll data = { - .contentOffset = { - .x = [[contentOffset valueForKey:@"x"] doubleValue], - .y = [[contentOffset valueForKey:@"y"] doubleValue] - }, - .contentInset = { - .left = [[contentInset valueForKey:@"left"] doubleValue], - .right = [[contentInset valueForKey:@"right"] doubleValue], - .top = [[contentInset valueForKey:@"top"] doubleValue], - .bottom = [[contentInset valueForKey:@"bottom"] doubleValue] - }, - .contentSize = { - .width = [[contentSize valueForKey:@"width"] doubleValue], - .height = [[contentSize valueForKey:@"height"] doubleValue] - }, - .layoutMeasurement = { - .width = [[layoutMeasurement valueForKey:@"width"] doubleValue], - .height = [[layoutMeasurement valueForKey:@"height"] doubleValue] }, - .zoomScale = zoomScale - }; - webViewEventEmitter->onScroll(data); - } - }; - _view.onHttpError = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnHttpError data = { - .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), - .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], - .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), - .statusCode = [[dictionary valueForKey:@"statusCode"] intValue], - .description = std::string([[dictionary valueForKey:@"description"] UTF8String]), - .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], - .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], - .loading = [[dictionary valueForKey:@"loading"] boolValue] - }; - webViewEventEmitter->onHttpError(data); - } - }; - self.contentView = _view; - } - return self; -} - -- (void)updateEventEmitter:(EventEmitter::Shared const &)eventEmitter -{ - [super updateEventEmitter:eventEmitter]; -} - -- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps -{ - const auto &oldViewProps = *std::static_pointer_cast(_props); - const auto &newViewProps = *std::static_pointer_cast(props); - -#define REMAP_WEBVIEW_PROP(name) \ - if (oldViewProps.name != newViewProps.name) { \ - _view.name = newViewProps.name; \ - } - -#define REMAP_WEBVIEW_STRING_PROP(name) \ - if (oldViewProps.name != newViewProps.name) { \ - _view.name = RCTNSStringFromString(newViewProps.name); \ - } - - REMAP_WEBVIEW_PROP(scrollEnabled) - REMAP_WEBVIEW_STRING_PROP(injectedJavaScript) - REMAP_WEBVIEW_STRING_PROP(injectedJavaScriptBeforeContentLoaded) - REMAP_WEBVIEW_PROP(injectedJavaScriptForMainFrameOnly) - REMAP_WEBVIEW_PROP(injectedJavaScriptBeforeContentLoadedForMainFrameOnly) - REMAP_WEBVIEW_PROP(javaScriptEnabled) - REMAP_WEBVIEW_PROP(javaScriptCanOpenWindowsAutomatically) - REMAP_WEBVIEW_PROP(allowFileAccessFromFileURLs) - REMAP_WEBVIEW_PROP(allowUniversalAccessFromFileURLs) - REMAP_WEBVIEW_PROP(allowsInlineMediaPlayback) - REMAP_WEBVIEW_PROP(webviewDebuggingEnabled) - REMAP_WEBVIEW_PROP(allowsAirPlayForMediaPlayback) - REMAP_WEBVIEW_PROP(mediaPlaybackRequiresUserAction) - REMAP_WEBVIEW_PROP(automaticallyAdjustContentInsets) - REMAP_WEBVIEW_PROP(autoManageStatusBarEnabled) - REMAP_WEBVIEW_PROP(hideKeyboardAccessoryView) - REMAP_WEBVIEW_PROP(allowsBackForwardNavigationGestures) - REMAP_WEBVIEW_PROP(incognito) - REMAP_WEBVIEW_PROP(pagingEnabled) - REMAP_WEBVIEW_STRING_PROP(applicationNameForUserAgent) - REMAP_WEBVIEW_PROP(cacheEnabled) - REMAP_WEBVIEW_PROP(allowsLinkPreview) - REMAP_WEBVIEW_STRING_PROP(allowingReadAccessToURL) - - REMAP_WEBVIEW_PROP(messagingEnabled) - REMAP_WEBVIEW_PROP(fraudulentWebsiteWarningEnabled) - REMAP_WEBVIEW_PROP(enableApplePay) - REMAP_WEBVIEW_PROP(pullToRefreshEnabled) - REMAP_WEBVIEW_PROP(bounces) - REMAP_WEBVIEW_PROP(useSharedProcessPool) - REMAP_WEBVIEW_STRING_PROP(userAgent) - REMAP_WEBVIEW_PROP(sharedCookiesEnabled) - #if !TARGET_OS_OSX - REMAP_WEBVIEW_PROP(decelerationRate) - #endif // !TARGET_OS_OSX - REMAP_WEBVIEW_PROP(directionalLockEnabled) - REMAP_WEBVIEW_PROP(showsHorizontalScrollIndicator) - REMAP_WEBVIEW_PROP(showsVerticalScrollIndicator) - REMAP_WEBVIEW_PROP(keyboardDisplayRequiresUserAction) - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ - REMAP_WEBVIEW_PROP(automaticallyAdjustContentInsets) -#endif -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ - REMAP_WEBVIEW_PROP(limitsNavigationsToAppBoundDomains) -#endif -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140500 /* iOS 14.5 */ - REMAP_WEBVIEW_PROP(textInteractionEnabled) -#endif - - if (oldViewProps.dataDetectorTypes != newViewProps.dataDetectorTypes) { - WKDataDetectorTypes dataDetectorTypes = WKDataDetectorTypeNone; - if (dataDetectorTypes & RNCWebViewDataDetectorTypes::Address) { - dataDetectorTypes |= WKDataDetectorTypeAddress; - } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::Link) { - dataDetectorTypes |= WKDataDetectorTypeLink; - } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::CalendarEvent) { - dataDetectorTypes |= WKDataDetectorTypeCalendarEvent; - } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::TrackingNumber) { - dataDetectorTypes |= WKDataDetectorTypeTrackingNumber; - } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::FlightNumber) { - dataDetectorTypes |= WKDataDetectorTypeFlightNumber; - } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::LookupSuggestion) { - dataDetectorTypes |= WKDataDetectorTypeLookupSuggestion; - } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::PhoneNumber) { - dataDetectorTypes |= WKDataDetectorTypePhoneNumber; - } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::All) { - dataDetectorTypes |= WKDataDetectorTypeAll; - } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::None) { - dataDetectorTypes = WKDataDetectorTypeNone; - } - [_view setDataDetectorTypes:dataDetectorTypes]; - } - if (oldViewProps.contentInset.top != newViewProps.contentInset.top || oldViewProps.contentInset.left != newViewProps.contentInset.left || oldViewProps.contentInset.right != newViewProps.contentInset.right || oldViewProps.contentInset.bottom != newViewProps.contentInset.bottom) { - UIEdgeInsets edgesInsets = { - .top = newViewProps.contentInset.top, - .left = newViewProps.contentInset.left, - .right = newViewProps.contentInset.right, - .bottom = newViewProps.contentInset.bottom - }; - [_view setContentInset: edgesInsets]; - } - - if (oldViewProps.basicAuthCredential.username != newViewProps.basicAuthCredential.username || oldViewProps.basicAuthCredential.password != newViewProps.basicAuthCredential.password) { - [_view setBasicAuthCredential: @{ - @"username": RCTNSStringFromString(newViewProps.basicAuthCredential.username), - @"password": RCTNSStringFromString(newViewProps.basicAuthCredential.password) - }]; - } - if (oldViewProps.contentInsetAdjustmentBehavior != newViewProps.contentInsetAdjustmentBehavior) { - if (newViewProps.contentInsetAdjustmentBehavior == RNCWebViewContentInsetAdjustmentBehavior::Never) { - [_view setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentNever]; - } else if (newViewProps.contentInsetAdjustmentBehavior == RNCWebViewContentInsetAdjustmentBehavior::Automatic) { - [_view setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentAutomatic]; - } else if (newViewProps.contentInsetAdjustmentBehavior == RNCWebViewContentInsetAdjustmentBehavior::ScrollableAxes) { - [_view setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentScrollableAxes]; - } else if (newViewProps.contentInsetAdjustmentBehavior == RNCWebViewContentInsetAdjustmentBehavior::Always) { - [_view setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentAlways]; - } - } - - if (oldViewProps.menuItems != newViewProps.menuItems) { - NSMutableArray *newMenuItems = [NSMutableArray array]; - - for (const auto &menuItem: newViewProps.menuItems) { - [newMenuItems addObject:@{ - @"key": RCTNSStringFromString(menuItem.key), - @"label": RCTNSStringFromString(menuItem.label), - }]; - - } - [_view setMenuItems:newMenuItems]; - } - if(oldViewProps.suppressMenuItems != newViewProps.suppressMenuItems) { - NSMutableArray *suppressMenuItems = [NSMutableArray array]; - - for (const auto &menuItem: newViewProps.suppressMenuItems) { - [suppressMenuItems addObject: RCTNSStringFromString(menuItem)]; - } - - [_view setSuppressMenuItems:suppressMenuItems]; - } - if (oldViewProps.hasOnFileDownload != newViewProps.hasOnFileDownload) { - if (newViewProps.hasOnFileDownload) { - _view.onFileDownload = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnFileDownload data = { - .downloadUrl = std::string([[dictionary valueForKey:@"downloadUrl"] UTF8String]) - }; - webViewEventEmitter->onFileDownload(data); - } - }; - } else { - _view.onFileDownload = nil; - } - } - if (oldViewProps.hasOnOpenWindowEvent != newViewProps.hasOnOpenWindowEvent) { - if (newViewProps.hasOnOpenWindowEvent) { - _view.onOpenWindow = [self](NSDictionary* dictionary) { - if (_eventEmitter) { - auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); - facebook::react::RNCWebViewEventEmitter::OnOpenWindow data = { - .targetUrl = std::string([[dictionary valueForKey:@"targetUrl"] UTF8String]) - }; - webViewEventEmitter->onOpenWindow(data); - } - }; - } else { - _view.onOpenWindow = nil; - } - } -// -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ - if (oldViewProps.contentMode != newViewProps.contentMode) { - if (newViewProps.contentMode == RNCWebViewContentMode::Recommended) { - [_view setContentMode: WKContentModeRecommended]; - } else if (newViewProps.contentMode == RNCWebViewContentMode::Mobile) { - [_view setContentMode:WKContentModeMobile]; - } else if (newViewProps.contentMode == RNCWebViewContentMode::Desktop) { - [_view setContentMode:WKContentModeDesktop]; - } - } -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ - if (oldViewProps.mediaCapturePermissionGrantType != newViewProps.mediaCapturePermissionGrantType) { - if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::Prompt) { - [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_Prompt]; - } else if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::Grant) { - [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_Grant]; - } else if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::Deny) { - [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_Deny]; - }else if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::GrantIfSameHostElsePrompt) { - [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt]; - }else if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::GrantIfSameHostElseDeny) { - [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny]; - } - } -#endif - - NSMutableDictionary* source = [[NSMutableDictionary alloc] init]; - if (!newViewProps.newSource.uri.empty()) { - [source setValue:RCTNSStringFromString(newViewProps.newSource.uri) forKey:@"uri"]; - } - NSMutableDictionary* headers = [[NSMutableDictionary alloc] init]; - for (auto & element : newViewProps.newSource.headers) { - [headers setValue:RCTNSStringFromString(element.value) forKey:RCTNSStringFromString(element.name)]; - } - if (headers.count > 0) { - [source setObject:headers forKey:@"headers"]; - } - if (!newViewProps.newSource.baseUrl.empty()) { - [source setValue:RCTNSStringFromString(newViewProps.newSource.baseUrl) forKey:@"baseUrl"]; - } - if (!newViewProps.newSource.body.empty()) { - [source setValue:RCTNSStringFromString(newViewProps.newSource.body) forKey:@"body"]; - } - if (!newViewProps.newSource.html.empty()) { - [source setValue:RCTNSStringFromString(newViewProps.newSource.html) forKey:@"html"]; - } - if (!newViewProps.newSource.method.empty()) { - [source setValue:RCTNSStringFromString(newViewProps.newSource.method) forKey:@"method"]; - } - [_view setSource:source]; - - [super updateProps:props oldProps:oldProps]; -} - -- (void)handleCommand:(nonnull const NSString *)commandName args:(nonnull const NSArray *)args { - RCTRNCWebViewHandleCommand(self, commandName, args); -} - - -Class RNCWebViewCls(void) -{ - return RNCWebView.class; -} - -- (void)goBack { - [_view goBack]; -} - -- (void)goForward { - [_view goForward]; -} - -- (void)injectJavaScript:(nonnull NSString *)javascript { - [_view injectJavaScript:javascript]; -} - -- (void)loadUrl:(nonnull NSString *)url { - // android only -} - -- (void)postMessage:(nonnull NSString *)data { - [_view postMessage:data]; -} - -- (void)reload { - [_view reload]; -} - -- (void)requestFocus { - [_view requestFocus]; -} - -- (void)stopLoading { - [_view stopLoading]; -} - -- (void)clearFormData { - // android only -} - -- (void)clearCache:(BOOL)includeDiskFiles { - // android only -} - -- (void)clearHistory { - // android only -} - -@end -#endif diff --git a/apple/RNCWebViewDecisionManager.h b/apple/RNCWebViewDecisionManager.h deleted file mode 100644 index da01fba0b..000000000 --- a/apple/RNCWebViewDecisionManager.h +++ /dev/null @@ -1,20 +0,0 @@ -#import -#import -#import - -typedef void (^DecisionBlock)(BOOL); - -@interface RNCWebViewDecisionManager : NSObject { - int nextLockIdentifier; - NSMutableDictionary *decisionHandlers; -} - -@property (nonatomic) int nextLockIdentifier; -@property (nonatomic, retain) NSMutableDictionary *decisionHandlers; - -+ (id) getInstance; - -- (int)setDecisionHandler:(DecisionBlock)handler; -- (void) setResult:(BOOL)shouldStart - forLockIdentifier:(int)lockIdentifier; -@end diff --git a/apple/RNCWebViewDecisionManager.m b/apple/RNCWebViewDecisionManager.m deleted file mode 100644 index aa9054813..000000000 --- a/apple/RNCWebViewDecisionManager.m +++ /dev/null @@ -1,47 +0,0 @@ -#import "RNCWebViewDecisionManager.h" - - - -@implementation RNCWebViewDecisionManager - -@synthesize nextLockIdentifier; -@synthesize decisionHandlers; - -+ (id)getInstance { - static RNCWebViewDecisionManager *lockManager = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - lockManager = [[self alloc] init]; - }); - return lockManager; -} - -- (int)setDecisionHandler:(DecisionBlock)decisionHandler { - int lockIdentifier = self.nextLockIdentifier++; - - [self.decisionHandlers setObject:decisionHandler forKey:@(lockIdentifier)]; - return lockIdentifier; -} - -- (void) setResult:(BOOL)shouldStart - forLockIdentifier:(int)lockIdentifier { - DecisionBlock handler = [self.decisionHandlers objectForKey:@(lockIdentifier)]; - if (handler == nil) { - RCTLogWarn(@"Lock not found"); - return; - } - handler(shouldStart); - [self.decisionHandlers removeObjectForKey:@(lockIdentifier)]; -} - -- (id)init { - if (self = [super init]) { - self.nextLockIdentifier = 1; - self.decisionHandlers = [[NSMutableDictionary alloc] init]; - } - return self; -} - -- (void)dealloc {} - -@end diff --git a/apple/RNCWebViewImpl.h b/apple/RNCWebViewImpl.h deleted file mode 100644 index 7ae0ba959..000000000 --- a/apple/RNCWebViewImpl.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import -#import -#import -#import - -#if !TARGET_OS_OSX -#import -#endif // !TARGET_OS_OSX - -#import "RNCWebViewDecisionManager.h" - -typedef enum RNCWebViewPermissionGrantType : NSUInteger { - RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt, - RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny, - RNCWebViewPermissionGrantType_Deny, - RNCWebViewPermissionGrantType_Grant, - RNCWebViewPermissionGrantType_Prompt -} RNCWebViewPermissionGrantType; - -@class RNCWebViewImpl; - -NS_ASSUME_NONNULL_BEGIN - -@protocol RNCWebViewDelegate - -- (BOOL)webView:(RNCWebViewImpl *)webView -shouldStartLoadForRequest:(NSMutableDictionary *)request - withCallback:(RCTDirectEventBlock)callback; - -@end - -@interface RNCWeakScriptMessageDelegate : NSObject - -@property (nonatomic, weak, nullable) id scriptDelegate; - -- (nullable instancetype)initWithDelegate:(id _Nullable)scriptDelegate; - -@end - -@interface RNCWebViewImpl : RCTView -@property (nonatomic, copy) RCTDirectEventBlock onFileDownload; -@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart; -@property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish; -@property (nonatomic, copy) RCTDirectEventBlock onLoadingError; -@property (nonatomic, copy) RCTDirectEventBlock onLoadingProgress; -@property (nonatomic, copy) RCTDirectEventBlock onShouldStartLoadWithRequest; -@property (nonatomic, copy) RCTDirectEventBlock onHttpError; -@property (nonatomic, copy) RCTDirectEventBlock onMessage; -@property (nonatomic, copy) RCTDirectEventBlock onScroll; -@property (nonatomic, copy) RCTDirectEventBlock onContentProcessDidTerminate; -@property (nonatomic, copy) RCTDirectEventBlock onOpenWindow; - - -@property (nonatomic, weak) id _Nullable delegate; -@property (nonatomic, copy) NSDictionary * _Nullable source; -@property (nonatomic, assign) BOOL messagingEnabled; -@property (nonatomic, copy) NSString * _Nullable injectedJavaScript; -@property (nonatomic, copy) NSString * _Nullable injectedJavaScriptBeforeContentLoaded; -@property (nonatomic, assign) BOOL injectedJavaScriptForMainFrameOnly; -@property (nonatomic, assign) BOOL injectedJavaScriptBeforeContentLoadedForMainFrameOnly; -@property (nonatomic, assign) BOOL scrollEnabled; -@property (nonatomic, assign) BOOL sharedCookiesEnabled; -@property (nonatomic, assign) BOOL autoManageStatusBarEnabled; -@property (nonatomic, assign) BOOL pagingEnabled; -@property (nonatomic, assign) CGFloat decelerationRate; -@property (nonatomic, assign) BOOL allowsInlineMediaPlayback; -@property (nonatomic, assign) BOOL webviewDebuggingEnabled; -@property (nonatomic, assign) BOOL allowsAirPlayForMediaPlayback; -@property (nonatomic, assign) BOOL bounces; -@property (nonatomic, assign) BOOL mediaPlaybackRequiresUserAction; -@property (nonatomic, assign) UIEdgeInsets contentInset; -@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets; -@property (nonatomic, assign) BOOL keyboardDisplayRequiresUserAction; -@property (nonatomic, assign) BOOL hideKeyboardAccessoryView; -@property (nonatomic, assign) BOOL allowsBackForwardNavigationGestures; -@property (nonatomic, assign) BOOL incognito; -@property (nonatomic, assign) BOOL useSharedProcessPool; -@property (nonatomic, copy) NSString * _Nullable userAgent; -@property (nonatomic, copy) NSString * _Nullable applicationNameForUserAgent; -@property (nonatomic, assign) BOOL cacheEnabled; -@property (nonatomic, assign) BOOL javaScriptEnabled; -@property (nonatomic, assign) BOOL javaScriptCanOpenWindowsAutomatically; -@property (nonatomic, assign) BOOL allowFileAccessFromFileURLs; -@property (nonatomic, assign) BOOL allowUniversalAccessFromFileURLs; -@property (nonatomic, assign) BOOL allowsLinkPreview; -@property (nonatomic, assign) BOOL showsHorizontalScrollIndicator; -@property (nonatomic, assign) BOOL showsVerticalScrollIndicator; -@property (nonatomic, assign) BOOL directionalLockEnabled; -@property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch; -@property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL; -@property (nonatomic, copy) NSDictionary * _Nullable basicAuthCredential; -@property (nonatomic, assign) BOOL pullToRefreshEnabled; -@property (nonatomic, assign) BOOL enableApplePay; -@property (nonatomic, copy) NSArray * _Nullable menuItems; -@property (nonatomic, copy) NSArray * _Nullable suppressMenuItems; -@property (nonatomic, copy) RCTDirectEventBlock onCustomMenuSelection; -#if !TARGET_OS_OSX -@property (nonatomic, assign) WKDataDetectorTypes dataDetectorTypes; -@property (nonatomic, weak) UIRefreshControl * _Nullable refreshControl; -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ -@property (nonatomic, assign) WKContentMode contentMode; -@property (nonatomic, assign) BOOL fraudulentWebsiteWarningEnabled; -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ -@property (nonatomic, assign) BOOL limitsNavigationsToAppBoundDomains; -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140500 /* iOS 14.5 */ -@property (nonatomic, assign) BOOL textInteractionEnabled; -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ -@property (nonatomic, assign) RNCWebViewPermissionGrantType mediaCapturePermissionGrantType; -#endif - -#if !TARGET_OS_OSX -- (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)behavior; -#endif // !TARGET_OS_OSX - -+ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential; -+ (void)setCustomCertificatesForHost:(nullable NSDictionary *)certificates; -- (void)postMessage:(NSString *_Nullable)message; -- (void)injectJavaScript:(NSString *_Nullable)script; -- (void)goForward; -- (void)goBack; -- (void)reload; -- (void)stopLoading; -- (void)requestFocus; -#ifdef RCT_NEW_ARCH_ENABLED -- (void)destroyWebView; -#endif -#if !TARGET_OS_OSX -- (void)addPullToRefreshControl; -- (void)pullToRefresh:(UIRefreshControl *)refreshControl; -#endif - -@end - -NS_ASSUME_NONNULL_END diff --git a/apple/RNCWebViewImpl.m b/apple/RNCWebViewImpl.m deleted file mode 100644 index e7737047f..000000000 --- a/apple/RNCWebViewImpl.m +++ /dev/null @@ -1,1832 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import "RNCWebViewImpl.h" -#import -#import -#import "RNCWKProcessPoolManager.h" -#if !TARGET_OS_OSX -#import -#else -#import -#endif // !TARGET_OS_OSX - -#import "objc/runtime.h" - -static NSTimer *keyboardTimer; -static NSString *const HistoryShimName = @"ReactNativeHistoryShim"; -static NSString *const MessageHandlerName = @"ReactNativeWebView"; -static NSURLCredential* clientAuthenticationCredential; -static NSDictionary* customCertificatesForHost; - -NSString *const CUSTOM_SELECTOR = @"_CUSTOM_SELECTOR_"; - -#if !TARGET_OS_OSX -// runtime trick to remove WKWebView keyboard default toolbar -// see: http://stackoverflow.com/questions/19033292/ios-7-uiwebview-keyboard-issue/19042279#19042279 -@interface _SwizzleHelperWK : UIView -@property (nonatomic, copy) WKWebView *webView; -@end -@implementation _SwizzleHelperWK --(id)inputAccessoryView -{ - if (_webView == nil) { - return nil; - } - - if ([_webView respondsToSelector:@selector(inputAssistantItem)]) { - UITextInputAssistantItem *inputAssistantItem = [_webView inputAssistantItem]; - inputAssistantItem.leadingBarButtonGroups = @[]; - inputAssistantItem.trailingBarButtonGroups = @[]; - } - return nil; -} -@end -#endif // !TARGET_OS_OSX - -@interface RNCWKWebView : WKWebView -#if !TARGET_OS_OSX -@property (nonatomic, copy) NSArray * _Nullable menuItems; -@property (nonatomic, copy) NSArray * _Nullable suppressMenuItems; -#endif // !TARGET_OS_OSX -@end -@implementation RNCWKWebView -#if !TARGET_OS_OSX -- (NSString *)stringFromAction:(SEL) action { - NSString *sel = NSStringFromSelector(action); - - NSDictionary *map = @{ - @"cut:": @"cut", - @"copy:": @"copy", - @"paste:": @"paste", - @"delete:": @"delete", - @"select:": @"select", - @"selectAll:": @"selectAll", - @"_promptForReplace:": @"replace", - @"_define:": @"lookup", - @"_translate:": @"translate", - @"toggleBoldface:": @"bold", - @"toggleItalics:": @"italic", - @"toggleUnderline:": @"underline", - @"_share:": @"share", - }; - - return map[sel] ?: sel; -} - -- (BOOL)canPerformAction:(SEL)action - withSender:(id)sender{ - if(self.suppressMenuItems) { - NSString * sel = [self stringFromAction:action]; - if ([self.suppressMenuItems containsObject: sel]) { - return NO; - } - } - - if (!self.menuItems) { - return [super canPerformAction:action withSender:sender]; - } - - return NO; -} -- (void)buildMenuWithBuilder:(id)builder API_AVAILABLE(ios(13.0)) { - if (@available(iOS 16.0, *)) { - if(self.menuItems){ - [builder removeMenuForIdentifier:UIMenuLookup]; - } - } - [super buildMenuWithBuilder:builder]; -} -#else // TARGET_OS_OSX -- (void)scrollWheel:(NSEvent *)theEvent { - RNCWebViewImpl *rncWebView = (RNCWebViewImpl *)[self superview]; - RCTAssert([rncWebView isKindOfClass:[rncWebView class]], @"superview must be an RNCWebViewImpl"); - if (![rncWebView scrollEnabled]) { - [[self nextResponder] scrollWheel:theEvent]; - return; - } - [super scrollWheel:theEvent]; -} -#endif // TARGET_OS_OSX -@end - -@interface RNCWebViewImpl () - -@property (nonatomic, copy) RNCWKWebView *webView; -@property (nonatomic, strong) WKUserScript *postMessageScript; -@property (nonatomic, strong) WKUserScript *atStartScript; -@property (nonatomic, strong) WKUserScript *atEndScript; -@end - -@implementation RNCWebViewImpl -{ -#if !TARGET_OS_OSX - UIColor * _savedBackgroundColor; -#else - RCTUIColor * _savedBackgroundColor; -#endif // !TARGET_OS_OSX - BOOL _savedHideKeyboardAccessoryView; - BOOL _savedKeyboardDisplayRequiresUserAction; - - // Workaround for StatusBar appearance bug for iOS 12 - // https://github.com/react-native-webview/react-native-webview/issues/62 - BOOL _isFullScreenVideoOpen; -#if !TARGET_OS_OSX - UIStatusBarStyle _savedStatusBarStyle; -#endif // !TARGET_OS_OSX - BOOL _savedStatusBarHidden; - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ - UIScrollViewContentInsetAdjustmentBehavior _savedContentInsetAdjustmentBehavior; -#endif -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ - BOOL _savedAutomaticallyAdjustsScrollIndicatorInsets; -#endif -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if ((self = [super initWithFrame:frame])) { -#if !TARGET_OS_OSX - super.backgroundColor = [UIColor clearColor]; -#else - super.backgroundColor = [RCTUIColor clearColor]; -#endif // !TARGET_OS_OSX - _bounces = YES; - _scrollEnabled = YES; - _showsHorizontalScrollIndicator = YES; - _showsVerticalScrollIndicator = YES; - _directionalLockEnabled = YES; - _automaticallyAdjustContentInsets = YES; - _autoManageStatusBarEnabled = YES; - _contentInset = UIEdgeInsetsZero; - _savedKeyboardDisplayRequiresUserAction = YES; -#if !TARGET_OS_OSX - _savedStatusBarStyle = RCTSharedApplication().statusBarStyle; - _savedStatusBarHidden = RCTSharedApplication().statusBarHidden; -#endif // !TARGET_OS_OSX - _injectedJavaScript = nil; - _injectedJavaScriptForMainFrameOnly = YES; - _injectedJavaScriptBeforeContentLoaded = nil; - _injectedJavaScriptBeforeContentLoadedForMainFrameOnly = YES; - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ - _savedContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; -#endif -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ - _savedAutomaticallyAdjustsScrollIndicatorInsets = NO; -#endif - _enableApplePay = NO; -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ - _mediaCapturePermissionGrantType = RNCWebViewPermissionGrantType_Prompt; -#endif - } - -#if !TARGET_OS_OSX - [[NSNotificationCenter defaultCenter]addObserver:self - selector:@selector(appDidBecomeActive) - name:UIApplicationDidBecomeActiveNotification - object:nil]; - - [[NSNotificationCenter defaultCenter]addObserver:self - selector:@selector(appWillResignActive) - name:UIApplicationWillResignActiveNotification - object:nil]; - if (@available(iOS 12.0, *)) { - // Workaround for a keyboard dismissal bug present in iOS 12 - // https://openradar.appspot.com/radar?id=5018321736957952 - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(keyboardWillHide) - name:UIKeyboardWillHideNotification object:nil]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(keyboardWillShow) - name:UIKeyboardWillShowNotification object:nil]; - - // Workaround for StatusBar appearance bug for iOS 12 - // https://github.com/react-native-webview/react-native-webview/issues/62 - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(showFullScreenVideoStatusBars) - name:UIWindowDidBecomeVisibleNotification - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(hideFullScreenVideoStatusBars) - name:UIWindowDidBecomeHiddenNotification - object:nil]; - - } -#endif // !TARGET_OS_OSX - return self; -} - -#if !TARGET_OS_OSX -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { - // Only allow long press gesture - if ([otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) { - return YES; - }else{ - return NO; - } -} - -// Listener for long presses -- (void)startLongPress:(UILongPressGestureRecognizer *)pressSender -{ - if (pressSender.state != UIGestureRecognizerStateEnded || !self.menuItems) { - return; - } - // When a long press ends, bring up our custom UIMenu if defined - if (self.menuItems.count == 0) { - UIMenuController *menuController = [UIMenuController sharedMenuController]; - menuController.menuItems = nil; - [menuController setMenuVisible:NO animated:YES]; - return; - } - UIMenuController *menuController = [UIMenuController sharedMenuController]; - NSMutableArray *menuControllerItems = [NSMutableArray arrayWithCapacity:self.menuItems.count]; - - for(NSDictionary *menuItem in self.menuItems) { - NSString *menuItemLabel = [RCTConvert NSString:menuItem[@"label"]]; - NSString *menuItemKey = [RCTConvert NSString:menuItem[@"key"]]; - NSString *sel = [NSString stringWithFormat:@"%@%@", CUSTOM_SELECTOR, menuItemKey]; - UIMenuItem *item = [[UIMenuItem alloc] initWithTitle: menuItemLabel - action: NSSelectorFromString(sel)]; - [menuControllerItems addObject: item]; - } - - menuController.menuItems = menuControllerItems; - [menuController setMenuVisible:YES animated:YES]; -} - -#endif // !TARGET_OS_OSX - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - if (@available(iOS 11.0, *)) { - [self.webView.configuration.websiteDataStore.httpCookieStore removeObserver:self]; - } -} - -- (void)tappedMenuItem:(NSString *)eventType -{ - // Get the selected text - // NOTE: selecting text in an iframe or shadow DOM will not work - [self.webView evaluateJavaScript: @"window.getSelection().toString()" completionHandler: ^(id result, NSError *error) { - if (error != nil) { - RCTLogWarn(@"%@", [NSString stringWithFormat:@"Error evaluating injectedJavaScript: This is possibly due to an unsupported return type. Try adding true to the end of your injectedJavaScript string. %@", error]); - } else { - if (self.onCustomMenuSelection) { - NSPredicate *filter = [NSPredicate predicateWithFormat:@"key contains[c] %@ ",eventType]; - NSArray *filteredMenuItems = [self.menuItems filteredArrayUsingPredicate:filter]; - NSDictionary *selectedMenuItem = filteredMenuItems[0]; - NSString *label = [RCTConvert NSString:selectedMenuItem[@"label"]]; - self.onCustomMenuSelection(@{ - @"key": eventType, - @"label": label, - @"selectedText": result - }); - } else { - RCTLogWarn(@"Error evaluating onCustomMenuSelection: You must implement an `onCustomMenuSelection` callback when using custom menu items"); - } - } - }]; -} - -// Overwrite method that interprets which action to call upon UIMenu Selection -// https://developer.apple.com/documentation/objectivec/nsobject/1571960-methodsignatureforselector -- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel -{ - NSMethodSignature *existingSelector = [super methodSignatureForSelector:sel]; - if (existingSelector) { - return existingSelector; - } - return [super methodSignatureForSelector:@selector(tappedMenuItem:)]; -} - -// Needed to forward messages to other objects -// https://developer.apple.com/documentation/objectivec/nsobject/1571955-forwardinvocation -- (void)forwardInvocation:(NSInvocation *)invocation -{ - NSString *sel = NSStringFromSelector([invocation selector]); - NSRange match = [sel rangeOfString:CUSTOM_SELECTOR]; - if (match.location == 0) { - [self tappedMenuItem:[sel substringFromIndex:17]]; - } else { - [super forwardInvocation:invocation]; - } -} - -// Allows the instance to respond to UIMenuController Actions -- (BOOL)canBecomeFirstResponder -{ - return YES; -} - -// Control which items show up on the UIMenuController -- (BOOL)canPerformAction:(SEL)action withSender:(id)sender -{ - NSString *sel = NSStringFromSelector(action); - // Do any of them have our custom keys? - NSRange match = [sel rangeOfString:CUSTOM_SELECTOR]; - - if (match.location == 0) { - return YES; - } - return NO; -} - -/** - * See https://stackoverflow.com/questions/25713069/why-is-wkwebview-not-opening-links-with-target-blank/25853806#25853806 for details. - */ -- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures -{ - if (!navigationAction.targetFrame.isMainFrame) { - NSURL *url = navigationAction.request.URL; - - if (_onOpenWindow) { - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary: @{@"targetUrl": url.absoluteString}]; - _onOpenWindow(event); - } else { - [webView loadRequest:navigationAction.request]; - } - } - return nil; -} - -/** - * Enables file input on macos, see https://developer.apple.com/documentation/webkit/wkuidelegate/1641952-webview - */ -#if TARGET_OS_OSX -- (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray *URLs))completionHandler -{ - NSOpenPanel *openPanel = [NSOpenPanel openPanel]; - openPanel.allowsMultipleSelection = parameters.allowsMultipleSelection; - [openPanel beginSheetModalForWindow:webView.window completionHandler:^(NSInteger result) { - if (result == NSModalResponseOK) - completionHandler(openPanel.URLs); - else - completionHandler(nil); - }]; -} -#endif //Target_OS_OSX - -- (WKWebViewConfiguration *)setUpWkWebViewConfig -{ - WKWebViewConfiguration *wkWebViewConfig = [WKWebViewConfiguration new]; - WKPreferences *prefs = [[WKPreferences alloc]init]; - BOOL _prefsUsed = NO; - if (!_javaScriptEnabled) { - prefs.javaScriptEnabled = NO; - _prefsUsed = YES; - } -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ - if (@available(iOS 13.0, *)) { - if (!_fraudulentWebsiteWarningEnabled) { - prefs.fraudulentWebsiteWarningEnabled = NO; - _prefsUsed = YES; - } - } -#endif - if (_allowUniversalAccessFromFileURLs) { - [wkWebViewConfig setValue:@TRUE forKey:@"allowUniversalAccessFromFileURLs"]; - } - if (_allowFileAccessFromFileURLs) { - [prefs setValue:@TRUE forKey:@"allowFileAccessFromFileURLs"]; - _prefsUsed = YES; - } - if (_javaScriptCanOpenWindowsAutomatically) { - [prefs setValue:@TRUE forKey:@"javaScriptCanOpenWindowsAutomatically"]; - _prefsUsed = YES; - } -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140500 /* iOS 14.5 */ - if (@available(iOS 14.5, *)) { - if (!_textInteractionEnabled) { - [prefs setValue:@FALSE forKey:@"textInteractionEnabled"]; - _prefsUsed = YES; - } - } -#endif - if (_prefsUsed) { - wkWebViewConfig.preferences = prefs; - } - if (_incognito) { - wkWebViewConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore]; - } else if (_cacheEnabled) { - wkWebViewConfig.websiteDataStore = [WKWebsiteDataStore defaultDataStore]; - } - if(self.useSharedProcessPool) { - wkWebViewConfig.processPool = [[RNCWKProcessPoolManager sharedManager] sharedProcessPool]; - } - wkWebViewConfig.userContentController = [WKUserContentController new]; - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ - if (@available(iOS 13.0, *)) { - WKWebpagePreferences *pagePrefs = [[WKWebpagePreferences alloc]init]; - pagePrefs.preferredContentMode = _contentMode; - wkWebViewConfig.defaultWebpagePreferences = pagePrefs; - } -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ - if (@available(iOS 14.0, *)) { - if ([wkWebViewConfig respondsToSelector:@selector(limitsNavigationsToAppBoundDomains)]) { - if (_limitsNavigationsToAppBoundDomains) { - wkWebViewConfig.limitsNavigationsToAppBoundDomains = YES; - } - } - } -#endif - - // Shim the HTML5 history API: - [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self] - name:HistoryShimName]; - [self resetupScripts:wkWebViewConfig]; - - if(@available(macos 10.11, ios 9.0, *)) { - wkWebViewConfig.allowsAirPlayForMediaPlayback = _allowsAirPlayForMediaPlayback; - } - -#if !TARGET_OS_OSX - wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback; - wkWebViewConfig.mediaTypesRequiringUserActionForPlayback = _mediaPlaybackRequiresUserAction - ? WKAudiovisualMediaTypeAll - : WKAudiovisualMediaTypeNone; - wkWebViewConfig.dataDetectorTypes = _dataDetectorTypes; -#endif // !TARGET_OS_OSX - - if (_applicationNameForUserAgent) { - wkWebViewConfig.applicationNameForUserAgent = [NSString stringWithFormat:@"%@ %@", wkWebViewConfig.applicationNameForUserAgent, _applicationNameForUserAgent]; - } - - return wkWebViewConfig; -} - -- (void)didMoveToWindow -{ - if (self.window != nil && _webView == nil) { - WKWebViewConfiguration *wkWebViewConfig = [self setUpWkWebViewConfig]; - _webView = [[RNCWKWebView alloc] initWithFrame:self.bounds configuration: wkWebViewConfig]; - [self setBackgroundColor: _savedBackgroundColor]; -#if !TARGET_OS_OSX - _webView.menuItems = _menuItems; - _webView.suppressMenuItems = _suppressMenuItems; - _webView.scrollView.delegate = self; -#endif // !TARGET_OS_OSX - _webView.UIDelegate = self; - _webView.navigationDelegate = self; -#if !TARGET_OS_OSX - if (_pullToRefreshEnabled) { - [self addPullToRefreshControl]; - } - _webView.scrollView.scrollEnabled = _scrollEnabled; - _webView.scrollView.pagingEnabled = _pagingEnabled; - //For UIRefreshControl to work correctly, the bounces should always be true - _webView.scrollView.bounces = _pullToRefreshEnabled || _bounces; - _webView.scrollView.showsHorizontalScrollIndicator = _showsHorizontalScrollIndicator; - _webView.scrollView.showsVerticalScrollIndicator = _showsVerticalScrollIndicator; - _webView.scrollView.directionalLockEnabled = _directionalLockEnabled; -#endif // !TARGET_OS_OSX - _webView.allowsLinkPreview = _allowsLinkPreview; - [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; - _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures; - - _webView.customUserAgent = _userAgent; - -#if !TARGET_OS_OSX - if ([_webView.scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) { - _webView.scrollView.contentInsetAdjustmentBehavior = _savedContentInsetAdjustmentBehavior; - } -#endif // !TARGET_OS_OSX - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ - if (@available(iOS 13.0, *)) { - _webView.scrollView.automaticallyAdjustsScrollIndicatorInsets = _savedAutomaticallyAdjustsScrollIndicatorInsets; - } -#endif - -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 130300 || \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= 160400 || \ - __TV_OS_VERSION_MAX_ALLOWED >= 160400 - if (@available(macOS 13.3, iOS 16.4, tvOS 16.4, *)) - _webView.inspectable = _webviewDebuggingEnabled; -#endif - - [self addSubview:_webView]; - [self setHideKeyboardAccessoryView: _savedHideKeyboardAccessoryView]; - [self setKeyboardDisplayRequiresUserAction: _savedKeyboardDisplayRequiresUserAction]; - [self visitSource]; - } -#if !TARGET_OS_OSX - // Allow this object to recognize gestures - if (self.menuItems != nil) { - UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(startLongPress:)]; - longPress.delegate = self; - - longPress.minimumPressDuration = 0.4f; - longPress.numberOfTouchesRequired = 1; - longPress.cancelsTouchesInView = YES; - [self addGestureRecognizer:longPress]; - } -#endif // !TARGET_OS_OSX -} - -// Update webview property when the component prop changes. -- (void)setAllowsBackForwardNavigationGestures:(BOOL)allowsBackForwardNavigationGestures { - _allowsBackForwardNavigationGestures = allowsBackForwardNavigationGestures; - _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures; -} - -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 130300 || \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= 160400 || \ - __TV_OS_VERSION_MAX_ALLOWED >= 160400 -- (void)setWebviewDebuggingEnabled:(BOOL)webviewDebuggingEnabled { - _webviewDebuggingEnabled = webviewDebuggingEnabled; - if (@available(macOS 13.3, iOS 16.4, tvOS 16.4, *)) - _webView.inspectable = _webviewDebuggingEnabled; -} -#endif - -#ifdef RCT_NEW_ARCH_ENABLED -- (void)destroyWebView -#else -- (void)removeFromSuperview -#endif -{ - if (_webView) { - [_webView.configuration.userContentController removeScriptMessageHandlerForName:HistoryShimName]; - [_webView.configuration.userContentController removeScriptMessageHandlerForName:MessageHandlerName]; - [_webView removeObserver:self forKeyPath:@"estimatedProgress"]; - [_webView removeFromSuperview]; -#if !TARGET_OS_OSX - _webView.scrollView.delegate = nil; - if (_menuItems) { - UIMenuController *menuController = [UIMenuController sharedMenuController]; - menuController.menuItems = nil; - } -#endif // !TARGET_OS_OSX - _webView = nil; - if (_onContentProcessDidTerminate) { - NSMutableDictionary *event = [self baseEvent]; - _onContentProcessDidTerminate(event); - } - } - -#ifndef RCT_NEW_ARCH_ENABLED - [super removeFromSuperview]; -#endif -} - -#if !TARGET_OS_OSX --(void)showFullScreenVideoStatusBars -{ -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - if (!_autoManageStatusBarEnabled) { - return; - } - - _isFullScreenVideoOpen = YES; - RCTUnsafeExecuteOnMainQueueSync(^{ - [RCTSharedApplication() setStatusBarStyle:self->_savedStatusBarStyle animated:YES]; - }); -#pragma clang diagnostic pop -} - --(void)hideFullScreenVideoStatusBars -{ -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - if (!_autoManageStatusBarEnabled) { - return; - } - - _isFullScreenVideoOpen = NO; - RCTUnsafeExecuteOnMainQueueSync(^{ - [RCTSharedApplication() setStatusBarHidden:self->_savedStatusBarHidden animated:YES]; - [RCTSharedApplication() setStatusBarStyle:self->_savedStatusBarStyle animated:YES]; - }); -#pragma clang diagnostic pop -} - --(void)keyboardWillHide -{ - keyboardTimer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(keyboardDisplacementFix) userInfo:nil repeats:false]; - [[NSRunLoop mainRunLoop] addTimer:keyboardTimer forMode:NSRunLoopCommonModes]; -} --(void)keyboardWillShow -{ - if (keyboardTimer != nil) { - [keyboardTimer invalidate]; - } -} --(void)keyboardDisplacementFix -{ - // Additional viewport checks to prevent unintentional scrolls - UIScrollView *scrollView = self.webView.scrollView; - double maxContentOffset = scrollView.contentSize.height - scrollView.frame.size.height; - if (maxContentOffset < 0) { - maxContentOffset = 0; - } - if (scrollView.contentOffset.y > maxContentOffset) { - // https://stackoverflow.com/a/9637807/824966 - [UIView animateWithDuration:.25 animations:^{ - scrollView.contentOffset = CGPointMake(0, maxContentOffset); - }]; - } -} -#endif // !TARGET_OS_OSX - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ - if ([keyPath isEqual:@"estimatedProgress"] && object == self.webView) { - if(_onLoadingProgress){ - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary:@{@"progress":[NSNumber numberWithDouble:self.webView.estimatedProgress]}]; - _onLoadingProgress(event); - } - }else{ - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - } -} - -#if !TARGET_OS_OSX -- (void)setBackgroundColor:(UIColor *)backgroundColor -#else -- (void)setBackgroundColor:(RCTUIColor *)backgroundColor -#endif // !TARGET_OS_OSX -{ - _savedBackgroundColor = backgroundColor; - if (_webView == nil) { - return; - } - - CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor); - BOOL opaque = (alpha == 1.0); -#if !TARGET_OS_OSX - self.opaque = _webView.opaque = opaque; - _webView.scrollView.backgroundColor = backgroundColor; - _webView.backgroundColor = backgroundColor; -#else - // https://stackoverflow.com/questions/40007753/macos-wkwebview-background-transparency - NSOperatingSystemVersion version = { 10, 12, 0 }; - if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]) { - [_webView setValue:@(opaque) forKey: @"drawsBackground"]; - } else { - [_webView setValue:@(!opaque) forKey: @"drawsTransparentBackground"]; - } -#endif // !TARGET_OS_OSX -} - -#if !TARGET_OS_OSX -- (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)behavior -{ - _savedContentInsetAdjustmentBehavior = behavior; - if (_webView == nil) { - return; - } - - if ([_webView.scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) { - CGPoint contentOffset = _webView.scrollView.contentOffset; - _webView.scrollView.contentInsetAdjustmentBehavior = behavior; - _webView.scrollView.contentOffset = contentOffset; - } -} -#endif // !TARGET_OS_OSX - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ -- (void)setAutomaticallyAdjustsScrollIndicatorInsets:(BOOL)automaticallyAdjustsScrollIndicatorInsets{ - _savedAutomaticallyAdjustsScrollIndicatorInsets = automaticallyAdjustsScrollIndicatorInsets; - if (_webView == nil) { - return; - } - if ([_webView.scrollView respondsToSelector:@selector(setAutomaticallyAdjustsScrollIndicatorInsets:)]) { - _webView.scrollView.automaticallyAdjustsScrollIndicatorInsets = automaticallyAdjustsScrollIndicatorInsets; - } -} -#endif - -/** - * This method is called whenever JavaScript running within the web view calls: - * - window.webkit.messageHandlers[MessageHandlerName].postMessage - */ -- (void)userContentController:(WKUserContentController *)userContentController - didReceiveScriptMessage:(WKScriptMessage *)message -{ - if ([message.name isEqualToString:HistoryShimName]) { - if (_onLoadingFinish) { - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary: @{@"navigationType": message.body}]; - _onLoadingFinish(event); - } - } else if ([message.name isEqualToString:MessageHandlerName]) { - if (_onMessage) { - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary: @{@"data": message.body}]; - _onMessage(event); - } - } -} - -- (void)setSource:(NSDictionary *)source -{ - if (![_source isEqualToDictionary:source]) { - _source = [source copy]; - - if (_webView != nil) { - [self visitSource]; - } - } -} - -- (void)setAllowingReadAccessToURL:(NSString *)allowingReadAccessToURL -{ - if (![_allowingReadAccessToURL isEqualToString:allowingReadAccessToURL]) { - _allowingReadAccessToURL = [allowingReadAccessToURL copy]; - - if (_webView != nil) { - [self visitSource]; - } - } -} - -#if !TARGET_OS_OSX -- (void)setContentInset:(UIEdgeInsets)contentInset -{ - _contentInset = contentInset; - [RCTView autoAdjustInsetsForView:self - withScrollView:_webView.scrollView - updateOffset:NO]; -} - -- (void)refreshContentInset -{ - [RCTView autoAdjustInsetsForView:self - withScrollView:_webView.scrollView - updateOffset:YES]; -} -#endif // !TARGET_OS_OSX - -- (void)visitSource -{ - // Check for a static html source first - NSString *html = [RCTConvert NSString:_source[@"html"]]; - if (html) { - NSURL *baseURL = [RCTConvert NSURL:_source[@"baseUrl"]]; - if (!baseURL) { - baseURL = [NSURL URLWithString:@"about:blank"]; - } - [_webView loadHTMLString:html baseURL:baseURL]; - return; - } - // Add cookie for subsequent resource requests sent by page itself, if cookie was set in headers on WebView - NSString *headerCookie = [RCTConvert NSString:_source[@"headers"][@"cookie"]]; - if(headerCookie) { - NSDictionary *headers = [NSDictionary dictionaryWithObjectsAndKeys:headerCookie,@"Set-Cookie",nil]; - NSURL *urlString = [NSURL URLWithString:_source[@"uri"]]; - NSArray *httpCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:urlString]; - [self writeCookiesToWebView:httpCookies completion:nil]; - } - - NSURLRequest *request = [self requestForSource:_source]; - __weak WKWebView *webView = _webView; - NSString *allowingReadAccessToURL = _allowingReadAccessToURL; - - [self syncCookiesToWebView:^{ - // Because of the way React works, as pages redirect, we actually end up - // passing the redirect urls back here, so we ignore them if trying to load - // the same url. We'll expose a call to 'reload' to allow a user to load - // the existing page. - if ([request.URL isEqual:webView.URL]) { - return; - } - if (!request.URL) { - // Clear the webview - [webView loadHTMLString:@"" baseURL:nil]; - return; - } - if (request.URL.host) { - [webView loadRequest:request]; - } - else { - NSURL* readAccessUrl = allowingReadAccessToURL ? [RCTConvert NSURL:allowingReadAccessToURL] : request.URL; - [webView loadFileURL:request.URL allowingReadAccessToURL:readAccessUrl]; - } - }]; -} - -#if !TARGET_OS_OSX --(void)setMenuItems:(NSArray *)menuItems { - _menuItems = menuItems; - _webView.menuItems = menuItems; -} - --(void)setSuppressMenuItems:(NSArray *)suppressMenuItems { - _suppressMenuItems = suppressMenuItems; - _webView.suppressMenuItems = suppressMenuItems; -} - --(void)setKeyboardDisplayRequiresUserAction:(BOOL)keyboardDisplayRequiresUserAction -{ - if (_webView == nil) { - _savedKeyboardDisplayRequiresUserAction = keyboardDisplayRequiresUserAction; - return; - } - - if (_savedKeyboardDisplayRequiresUserAction == true) { - return; - } - - UIView* subview; - - for (UIView* view in _webView.scrollView.subviews) { - if([[view.class description] hasPrefix:@"WK"]) - subview = view; - } - - if(subview == nil) return; - - Class class = subview.class; - - NSOperatingSystemVersion iOS_11_3_0 = (NSOperatingSystemVersion){11, 3, 0}; - NSOperatingSystemVersion iOS_12_2_0 = (NSOperatingSystemVersion){12, 2, 0}; - NSOperatingSystemVersion iOS_13_0_0 = (NSOperatingSystemVersion){13, 0, 0}; - - Method method; - IMP override; - - if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_13_0_0]) { - // iOS 13.0.0 - Future - SEL selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:"); - method = class_getInstanceMethod(class, selector); - IMP original = method_getImplementation(method); - override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) { - ((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4); - }); - } - else if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_12_2_0]) { - // iOS 12.2.0 - iOS 13.0.0 - SEL selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:"); - method = class_getInstanceMethod(class, selector); - IMP original = method_getImplementation(method); - override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) { - ((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4); - }); - } - else if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_11_3_0]) { - // iOS 11.3.0 - 12.2.0 - SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:"); - method = class_getInstanceMethod(class, selector); - IMP original = method_getImplementation(method); - override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) { - ((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4); - }); - } else { - // iOS 9.0 - 11.3.0 - SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:"); - method = class_getInstanceMethod(class, selector); - IMP original = method_getImplementation(method); - override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, id arg3) { - ((void (*)(id, SEL, void*, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3); - }); - } - - method_setImplementation(method, override); -} - --(void)setHideKeyboardAccessoryView:(BOOL)hideKeyboardAccessoryView -{ - if (_webView == nil) { - _savedHideKeyboardAccessoryView = hideKeyboardAccessoryView; - return; - } - - if (_savedHideKeyboardAccessoryView == false) { - return; - } - - UIView* subview; - - for (UIView* view in _webView.scrollView.subviews) { - if([[view.class description] hasPrefix:@"WK"]) - subview = view; - } - - if(subview == nil) return; - - NSString* name = [NSString stringWithFormat:@"%@_SwizzleHelperWK", subview.class.superclass]; - Class newClass = NSClassFromString(name); - - if(newClass == nil) - { - newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0); - if(!newClass) return; - - Method method = class_getInstanceMethod([_SwizzleHelperWK class], @selector(inputAccessoryView)); - class_addMethod(newClass, @selector(inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method)); - - objc_registerClassPair(newClass); - } - - object_setClass(subview, newClass); -} - -// UIScrollViewDelegate method -- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView -{ - scrollView.decelerationRate = _decelerationRate; -} -#endif // !TARGET_OS_OSX - -- (void)setUserAgent:(NSString*)userAgent -{ - _userAgent = userAgent; - _webView.customUserAgent = userAgent; -} - -- (void)setScrollEnabled:(BOOL)scrollEnabled -{ - _scrollEnabled = scrollEnabled; -#if !TARGET_OS_OSX - _webView.scrollView.scrollEnabled = scrollEnabled; -#endif // !TARGET_OS_OSX -} - -#if !TARGET_OS_OSX -// UIScrollViewDelegate method -- (void)scrollViewDidScroll:(UIScrollView *)scrollView -{ - // Don't allow scrolling the scrollView. - if (!_scrollEnabled) { - scrollView.bounds = _webView.bounds; - } - else if (_onScroll != nil) { - NSDictionary *event = @{ - @"contentOffset": @{ - @"x": @(scrollView.contentOffset.x), - @"y": @(scrollView.contentOffset.y) - }, - @"contentInset": @{ - @"top": @(scrollView.contentInset.top), - @"left": @(scrollView.contentInset.left), - @"bottom": @(scrollView.contentInset.bottom), - @"right": @(scrollView.contentInset.right) - }, - @"contentSize": @{ - @"width": @(scrollView.contentSize.width), - @"height": @(scrollView.contentSize.height) - }, - @"layoutMeasurement": @{ - @"width": @(scrollView.frame.size.width), - @"height": @(scrollView.frame.size.height) - }, - @"zoomScale": @(scrollView.zoomScale ?: 1), - }; - _onScroll(event); - } -} - -- (void)setDirectionalLockEnabled:(BOOL)directionalLockEnabled -{ - _directionalLockEnabled = directionalLockEnabled; - _webView.scrollView.directionalLockEnabled = directionalLockEnabled; -} - -- (void)setShowsHorizontalScrollIndicator:(BOOL)showsHorizontalScrollIndicator -{ - _showsHorizontalScrollIndicator = showsHorizontalScrollIndicator; - _webView.scrollView.showsHorizontalScrollIndicator = showsHorizontalScrollIndicator; -} - -- (void)setShowsVerticalScrollIndicator:(BOOL)showsVerticalScrollIndicator -{ - _showsVerticalScrollIndicator = showsVerticalScrollIndicator; - _webView.scrollView.showsVerticalScrollIndicator = showsVerticalScrollIndicator; -} -#endif // !TARGET_OS_OSX - -- (void)postMessage:(NSString *)message -{ - NSDictionary *eventInitDict = @{@"data": message}; - NSString *source = [NSString - stringWithFormat:@"window.dispatchEvent(new MessageEvent('message', %@));", - RCTJSONStringify(eventInitDict, NULL) - ]; - [self injectJavaScript: source]; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - - // Ensure webview takes the position and dimensions of RNCWebViewImpl - _webView.frame = self.bounds; -#if !TARGET_OS_OSX - _webView.scrollView.contentInset = _contentInset; -#endif // !TARGET_OS_OSX -} - -- (NSMutableDictionary *)baseEvent -{ - NSDictionary *event = @{ - @"url": _webView.URL.absoluteString ?: @"", - @"title": _webView.title ?: @"", - @"loading" : @(_webView.loading), - @"canGoBack": @(_webView.canGoBack), - @"canGoForward" : @(_webView.canGoForward) - }; - return [[NSMutableDictionary alloc] initWithDictionary: event]; -} - -+ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential { - clientAuthenticationCredential = credential; -} - -+ (void)setCustomCertificatesForHost:(nullable NSDictionary*)certificates { - customCertificatesForHost = certificates; -} - -- (void) webView:(WKWebView *)webView - didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable))completionHandler -{ - NSString* host = nil; - if (webView.URL != nil) { - host = webView.URL.host; - } - if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) { - completionHandler(NSURLSessionAuthChallengeUseCredential, clientAuthenticationCredential); - return; - } - if ([[challenge protectionSpace] serverTrust] != nil && customCertificatesForHost != nil && host != nil) { - SecCertificateRef localCertificate = (__bridge SecCertificateRef)([customCertificatesForHost objectForKey:host]); - if (localCertificate != nil) { - NSData *localCertificateData = (NSData*) CFBridgingRelease(SecCertificateCopyData(localCertificate)); - SecTrustRef trust = [[challenge protectionSpace] serverTrust]; - long count = SecTrustGetCertificateCount(trust); - for (long i = 0; i < count; i++) { - SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(trust, i); - if (serverCertificate == nil) { continue; } - NSData *serverCertificateData = (NSData *) CFBridgingRelease(SecCertificateCopyData(serverCertificate)); - if ([serverCertificateData isEqualToData:localCertificateData]) { - NSURLCredential *useCredential = [NSURLCredential credentialForTrust:trust]; - if (challenge.sender != nil) { - [challenge.sender useCredential:useCredential forAuthenticationChallenge:challenge]; - } - completionHandler(NSURLSessionAuthChallengeUseCredential, useCredential); - return; - } - } - } - } - if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodHTTPBasic) { - NSString *username = [_basicAuthCredential valueForKey:@"username"]; - NSString *password = [_basicAuthCredential valueForKey:@"password"]; - if (username && password) { - NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceNone]; - completionHandler(NSURLSessionAuthChallengeUseCredential, credential); - return; - } - } - completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); -} - -#pragma mark - WKNavigationDelegate methods - -/** - * alert - */ -- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler -{ -#if !TARGET_OS_OSX - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - completionHandler(); - }]]; - [[self topViewController] presentViewController:alert animated:YES completion:NULL]; -#else - NSAlert *alert = [[NSAlert alloc] init]; - [alert setMessageText:message]; - [alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:^(__unused NSModalResponse response){ - completionHandler(); - }]; -#endif // !TARGET_OS_OSX -} - -/** - * confirm - */ -- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{ -#if !TARGET_OS_OSX - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert]; - [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - completionHandler(YES); - }]]; - [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { - completionHandler(NO); - }]]; - [[self topViewController] presentViewController:alert animated:YES completion:NULL]; -#else - NSAlert *alert = [[NSAlert alloc] init]; - [alert setMessageText:message]; - [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button")]; - [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel button")]; - void (^callbacksHandlers)(NSModalResponse response) = ^void(NSModalResponse response) { - completionHandler(response == NSAlertFirstButtonReturn); - }; - [alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:callbacksHandlers]; -#endif // !TARGET_OS_OSX -} - -/** - * prompt - */ -- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler{ -#if !TARGET_OS_OSX - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:prompt preferredStyle:UIAlertControllerStyleAlert]; - [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { - textField.text = defaultText; - }]; - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - completionHandler([[alert.textFields lastObject] text]); - }]; - [alert addAction:okAction]; - UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { - completionHandler(nil); - }]; - [alert addAction:cancelAction]; - alert.preferredAction = okAction; - [[self topViewController] presentViewController:alert animated:YES completion:NULL]; -#else - NSAlert *alert = [[NSAlert alloc] init]; - [alert setMessageText:prompt]; - - const NSRect RCTSingleTextFieldFrame = NSMakeRect(0.0, 0.0, 275.0, 22.0); - NSTextField *textField = [[NSTextField alloc] initWithFrame:RCTSingleTextFieldFrame]; - textField.cell.scrollable = YES; - if (@available(macOS 10.11, *)) { - textField.maximumNumberOfLines = 1; - } - textField.stringValue = defaultText; - [alert setAccessoryView:textField]; - - [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button")]; - [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel button")]; - [alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:^(NSModalResponse response) { - if (response == NSAlertFirstButtonReturn) { - completionHandler([textField stringValue]); - } else { - completionHandler(nil); - } - }]; -#endif // !TARGET_OS_OSX -} - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ -/** - * Media capture permissions (prevent multiple prompts) - */ -- (void) webView:(WKWebView *)webView - requestMediaCapturePermissionForOrigin:(WKSecurityOrigin *)origin - initiatedByFrame:(WKFrameInfo *)frame - type:(WKMediaCaptureType)type - decisionHandler:(void (^)(WKPermissionDecision decision))decisionHandler { - if (_mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt || _mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny) { - if ([origin.host isEqualToString:webView.URL.host]) { - decisionHandler(WKPermissionDecisionGrant); - } else { - WKPermissionDecision decision = _mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt ? WKPermissionDecisionPrompt : WKPermissionDecisionDeny; - decisionHandler(decision); - } - } else if (_mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_Deny) { - decisionHandler(WKPermissionDecisionDeny); - } else if (_mediaCapturePermissionGrantType == RNCWebViewPermissionGrantType_Grant) { - decisionHandler(WKPermissionDecisionGrant); - } else { - decisionHandler(WKPermissionDecisionPrompt); - } -} -#endif - -#if !TARGET_OS_OSX -/** - * topViewController - */ --(UIViewController *)topViewController{ - return RCTPresentedViewController(); -} - -#endif // !TARGET_OS_OSX - -/** - * Decides whether to allow or cancel a navigation. - * @see https://fburl.com/42r9fxob - */ -- (void) webView:(WKWebView *)webView - decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction - decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler -{ - static NSDictionary *navigationTypes; - static dispatch_once_t onceToken; - - dispatch_once(&onceToken, ^{ - navigationTypes = @{ - @(WKNavigationTypeLinkActivated): @"click", - @(WKNavigationTypeFormSubmitted): @"formsubmit", - @(WKNavigationTypeBackForward): @"backforward", - @(WKNavigationTypeReload): @"reload", - @(WKNavigationTypeFormResubmitted): @"formresubmit", - @(WKNavigationTypeOther): @"other", - }; - }); - - WKNavigationType navigationType = navigationAction.navigationType; - NSURLRequest *request = navigationAction.request; - BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL]; - BOOL hasTargetFrame = navigationAction.targetFrame != nil; - - if (_onOpenWindow && !hasTargetFrame) { - // When OnOpenWindow should be called, we want to prevent the navigation - // If not prevented, the `decisionHandler` is called first and after that `createWebViewWithConfiguration` is called - // In that order the WebView's ref would be updated with the target URL even if `createWebViewWithConfiguration` does not call `loadRequest` - // So the WebView's document stays on the current URL, but the WebView's ref is replaced by the target URL - // By preventing the navigation here, we also prevent the WebView's ref mutation - // The counterpart is that we have to manually call `_onOpenWindow` here, because no navigation means no call to `createWebViewWithConfiguration` - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary: @{@"targetUrl": request.URL.absoluteString}]; - decisionHandler(WKNavigationActionPolicyCancel); - _onOpenWindow(event); - return; - } - - if (_onShouldStartLoadWithRequest) { - NSMutableDictionary *event = [self baseEvent]; - int lockIdentifier = [[RNCWebViewDecisionManager getInstance] setDecisionHandler: ^(BOOL shouldStart){ - dispatch_async(dispatch_get_main_queue(), ^{ - if (!shouldStart) { - decisionHandler(WKNavigationActionPolicyCancel); - return; - } - if (self->_onLoadingStart) { - // We have this check to filter out iframe requests and whatnot - if (isTopFrame) { - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary: @{ - @"url": (request.URL).absoluteString, - @"navigationType": navigationTypes[@(navigationType)] - }]; - self->_onLoadingStart(event); - } - } - - // Allow all navigation by default - decisionHandler(WKNavigationActionPolicyAllow); - }); - - }]; - if (request.mainDocumentURL) { - [event addEntriesFromDictionary: @{ - @"mainDocumentURL": (request.mainDocumentURL).absoluteString, - }]; - } - [event addEntriesFromDictionary: @{ - @"url": (request.URL).absoluteString, - @"navigationType": navigationTypes[@(navigationType)], - @"isTopFrame": @(isTopFrame), - @"hasTargetFrame": @(hasTargetFrame), - @"lockIdentifier": @(lockIdentifier) - }]; - _onShouldStartLoadWithRequest(event); - // decisionHandler(WKNavigationActionPolicyAllow); - return; - } - - if (_onLoadingStart) { - // We have this check to filter out iframe requests and whatnot - if (isTopFrame) { - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary: @{ - @"url": (request.URL).absoluteString, - @"navigationType": navigationTypes[@(navigationType)] - }]; - _onLoadingStart(event); - } - } - - // Allow all navigation by default - decisionHandler(WKNavigationActionPolicyAllow); -} - -/** - * Called when the web view’s content process is terminated. - * @see https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455639-webviewwebcontentprocessdidtermi?language=objc - */ -- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView -{ - RCTLogWarn(@"Webview Process Terminated"); - if (_onContentProcessDidTerminate) { - NSMutableDictionary *event = [self baseEvent]; - _onContentProcessDidTerminate(event); - } -} - -/** - * Decides whether to allow or cancel a navigation after its response is known. - * @see https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview?language=objc - */ -- (void) webView:(WKWebView *)webView - decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse - decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler -{ - WKNavigationResponsePolicy policy = WKNavigationResponsePolicyAllow; - if (_onHttpError && navigationResponse.forMainFrame) { - if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { - NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response; - NSInteger statusCode = response.statusCode; - - if (statusCode >= 400) { - NSMutableDictionary *httpErrorEvent = [self baseEvent]; - [httpErrorEvent addEntriesFromDictionary: @{ - @"url": response.URL.absoluteString, - @"statusCode": @(statusCode) - }]; - - _onHttpError(httpErrorEvent); - } - - NSString *disposition = nil; - if (@available(iOS 13, macOS 10.15, *)) { - disposition = [response valueForHTTPHeaderField:@"Content-Disposition"]; - } - BOOL isAttachment = disposition != nil && [disposition hasPrefix:@"attachment"]; - if (isAttachment || !navigationResponse.canShowMIMEType) { - if (_onFileDownload) { - policy = WKNavigationResponsePolicyCancel; - - NSMutableDictionary *downloadEvent = [self baseEvent]; - [downloadEvent addEntriesFromDictionary: @{ - @"downloadUrl": (response.URL).absoluteString, - }]; - _onFileDownload(downloadEvent); - } - } - } - } - - decisionHandler(policy); -} - -/** - * Called when an error occurs while the web view is loading content. - * @see https://fburl.com/km6vqenw - */ -- (void) webView:(WKWebView *)webView - didFailProvisionalNavigation:(WKNavigation *)navigation - withError:(NSError *)error -{ - if (_onLoadingError) { - if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) { - // NSURLErrorCancelled is reported when a page has a redirect OR if you load - // a new URL in the WebView before the previous one came back. We can just - // ignore these since they aren't real errors. - // http://stackoverflow.com/questions/1024748/how-do-i-fix-nsurlerrordomain-error-999-in-iphone-3-0-os - return; - } - - if ([error.domain isEqualToString:@"WebKitErrorDomain"] && - (error.code == 102 || error.code == 101)) { - // Error code 102 "Frame load interrupted" is raised by the WKWebView - // when the URL is from an http redirect. This is a common pattern when - // implementing OAuth with a WebView. - return; - } - - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary:@{ - @"didFailProvisionalNavigation": @YES, - @"domain": error.domain, - @"code": @(error.code), - @"description": error.localizedDescription, - }]; - _onLoadingError(event); - } -} - -- (void)evaluateJS:(NSString *)js - thenCall: (void (^)(NSString*)) callback -{ - if (self.enableApplePay) { - RCTLogWarn(@"Cannot run javascript when apple pay is enabled"); - return; - } - [self.webView evaluateJavaScript: js completionHandler: ^(id result, NSError *error) { - if (callback != nil) { - callback([NSString stringWithFormat:@"%@", result]); - } - if (error != nil) { - RCTLogWarn(@"%@", [NSString stringWithFormat:@"Error evaluating injectedJavaScript: This is possibly due to an unsupported return type. Try adding true to the end of your injectedJavaScript string. %@", error]); - } - }]; -} - --(void)forceIgnoreSilentHardwareSwitch:(BOOL)initialSetup -{ - NSString *mp3Str = @"data:audio/mp3;base64,//tAxAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAAFAAAESAAzMzMzMzMzMzMzMzMzMzMzMzMzZmZmZmZmZmZmZmZmZmZmZmZmZmaZmZmZmZmZmZmZmZmZmZmZmZmZmczMzMzMzMzMzMzMzMzMzMzMzMzM//////////////////////////8AAAA5TEFNRTMuMTAwAZYAAAAAAAAAABQ4JAMGQgAAOAAABEhNIZS0AAAAAAD/+0DEAAPH3Yz0AAR8CPqyIEABp6AxjG/4x/XiInE4lfQDFwIIRE+uBgZoW4RL0OLMDFn6E5v+/u5ehf76bu7/6bu5+gAiIQGAABQIUJ0QolFghEn/9PhZQpcUTpXMjo0OGzRCZXyKxoIQzB2KhCtGobpT9TRVj/3Pmfp+f8X7Pu1B04sTnc3s0XhOlXoGVCMNo9X//9/r6a10TZEY5DsxqvO7mO5qFvpFCmKIjhpSItGsUYcRO//7QsQRgEiljQIAgLFJAbIhNBCa+JmorCbOi5q9nVd2dKnusTMQg4MFUlD6DQ4OFijwGAijRMfLbHG4nLVTjydyPlJTj8pfPflf9/5GD950A5e+jsrmNZSjSirjs1R7hnkia8vr//l/7Nb+crvr9Ok5ZJOylUKRxf/P9Zn0j2P4pJYXyKkeuy5wUYtdmOu6uobEtFqhIJViLEKIjGxchGev/L3Y0O3bwrIOszTBAZ7Ih28EUaSOZf/7QsQfg8fpjQIADN0JHbGgQBAZ8T//y//t/7d/2+f5m7MdCeo/9tdkMtGLbt1tqnabRroO1Qfvh20yEbei8nfDXP7btW7f9/uO9tbe5IvHQbLlxpf3DkAk0ojYcv///5/u3/7PTfGjPEPUvt5D6f+/3Lea4lz4tc4TnM/mFPrmalWbboeNiNyeyr+vufttZuvrVrt/WYv3T74JFo8qEDiJqJrmDTs///v99xDku2xG02jjunrICP/7QsQtA8kpkQAAgNMA/7FgQAGnobgfghgqA+uXwWQ3XFmGimSbe2X3ksY//KzK1a2k6cnNWOPJnPWUsYbKqkh8RJzrVf///P///////4vyhLKHLrCb5nIrYIUss4cthigL1lQ1wwNAc6C1pf1TIKRSkt+a//z+yLVcwlXKSqeSuCVQFLng2h4AFAFgTkH+Z/8jTX/zr//zsJV/5f//5UX/0ZNCNCCaf5lTCTRkaEdhNP//n/KUjf/7QsQ5AEhdiwAAjN7I6jGddBCO+WGTQ1mXrYatSAgaykxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqg=="; - NSString *scr; - if (initialSetup) { - scr = [NSString stringWithFormat:@"var s=new Audio('%@');s.id='wkwebviewAudio';s.controls=false;s.loop=true;s.play();document.body.appendChild(s);true", mp3Str]; - } else { - scr = [NSString stringWithFormat:@"var s=document.getElementById('wkwebviewAudio');s.src=null;s.parentNode.removeChild(s);s=null;s=new Audio('%@');s.id='wkwebviewAudio';s.controls=false;s.loop=true;s.play();document.body.appendChild(s);true", mp3Str]; - } - [self evaluateJS: scr thenCall: nil]; -} - --(void)disableIgnoreSilentSwitch -{ - [self evaluateJS: @"document.getElementById('wkwebviewAudio').src=null;true" thenCall: nil]; -} - --(void)appDidBecomeActive -{ - if (_ignoreSilentHardwareSwitch) { - [self forceIgnoreSilentHardwareSwitch:false]; - } -} - --(void)appWillResignActive -{ - if (_ignoreSilentHardwareSwitch) { - [self disableIgnoreSilentSwitch]; - } -} - -/** - * Called when the navigation is complete. - * @see https://fburl.com/rtys6jlb - */ -- (void)webView:(WKWebView *)webView -didFinishNavigation:(WKNavigation *)navigation -{ - if (_ignoreSilentHardwareSwitch) { - [self forceIgnoreSilentHardwareSwitch:true]; - } - - if (_onLoadingFinish) { - _onLoadingFinish([self baseEvent]); - } -} - -- (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore -{ - if (@available(iOS 11.0, *)) { - if(_sharedCookiesEnabled) { - // Write all cookies from WKWebView back to sharedHTTPCookieStorage - [cookieStore getAllCookies:^(NSArray* cookies) { - for (NSHTTPCookie *cookie in cookies) { - [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie]; - } - }]; - } - } -} - -- (void)injectJavaScript:(NSString *)script -{ - [self evaluateJS: script thenCall: nil]; -} - -- (void)goForward -{ - [_webView goForward]; -} - -- (void)goBack -{ - [_webView goBack]; -} - -- (void)reload -{ - /** - * When the initial load fails due to network connectivity issues, - * [_webView reload] doesn't reload the webpage. Therefore, we must - * manually call [_webView loadRequest:request]. - */ - NSURLRequest *request = [self requestForSource:self.source]; - - if (request.URL && !_webView.URL.absoluteString.length) { - [_webView loadRequest:request]; - } else { - [_webView reload]; - } -} -#if !TARGET_OS_OSX -- (void)addPullToRefreshControl -{ - UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; - _refreshControl = refreshControl; - [_webView.scrollView addSubview: refreshControl]; - [refreshControl addTarget:self action:@selector(pullToRefresh:) forControlEvents: UIControlEventValueChanged]; -} - -- (void)pullToRefresh:(UIRefreshControl *)refreshControl -{ - [self reload]; - [refreshControl endRefreshing]; -} - - -- (void)setPullToRefreshEnabled:(BOOL)pullToRefreshEnabled -{ - _pullToRefreshEnabled = pullToRefreshEnabled; - - if (pullToRefreshEnabled) { - [self addPullToRefreshControl]; - } else { - [_refreshControl removeFromSuperview]; - } - - [self setBounces:_bounces]; -} -#endif // !TARGET_OS_OSX - -- (void)stopLoading -{ - [_webView stopLoading]; -} - -- (void)requestFocus -{ -#if !TARGET_OS_OSX - [_webView becomeFirstResponder]; -#endif // !TARGET_OS_OSX -} - -#if !TARGET_OS_OSX -- (void)setBounces:(BOOL)bounces -{ - _bounces = bounces; - //For UIRefreshControl to work correctly, the bounces should always be true - _webView.scrollView.bounces = _pullToRefreshEnabled || bounces; -} -#endif // !TARGET_OS_OSX - -- (void)setInjectedJavaScript:(NSString *)source { - _injectedJavaScript = source; - - self.atEndScript = source == nil ? nil : [[WKUserScript alloc] initWithSource:source - injectionTime:WKUserScriptInjectionTimeAtDocumentEnd - forMainFrameOnly:_injectedJavaScriptForMainFrameOnly]; - - if(_webView != nil){ - [self resetupScripts:_webView.configuration]; - } -} - -- (void)setEnableApplePay:(BOOL)enableApplePay { - _enableApplePay = enableApplePay; - if(_webView != nil){ - [self resetupScripts:_webView.configuration]; - } -} - -- (void)setInjectedJavaScriptBeforeContentLoaded:(NSString *)source { - _injectedJavaScriptBeforeContentLoaded = source; - - self.atStartScript = source == nil ? nil : [[WKUserScript alloc] initWithSource:source - injectionTime:WKUserScriptInjectionTimeAtDocumentStart - forMainFrameOnly:_injectedJavaScriptBeforeContentLoadedForMainFrameOnly]; - - if(_webView != nil){ - [self resetupScripts:_webView.configuration]; - } -} - -- (void)setInjectedJavaScriptForMainFrameOnly:(BOOL)mainFrameOnly { - _injectedJavaScriptForMainFrameOnly = mainFrameOnly; - [self setInjectedJavaScript:_injectedJavaScript]; -} - -- (void)setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly:(BOOL)mainFrameOnly { - _injectedJavaScriptBeforeContentLoadedForMainFrameOnly = mainFrameOnly; - [self setInjectedJavaScriptBeforeContentLoaded:_injectedJavaScriptBeforeContentLoaded]; -} - -- (void)setMessagingEnabled:(BOOL)messagingEnabled { - _messagingEnabled = messagingEnabled; - - self.postMessageScript = _messagingEnabled ? - [ - [WKUserScript alloc] - initWithSource: [ - NSString - stringWithFormat: - @"window.%@ = {" - " postMessage: function (data) {" - " window.webkit.messageHandlers.%@.postMessage(String(data));" - " }" - "};", MessageHandlerName, MessageHandlerName - ] - injectionTime:WKUserScriptInjectionTimeAtDocumentStart - /* TODO: For a separate (minor) PR: use logic like this (as react-native-wkwebview does) so that messaging can be used in all frames if desired. - * I am keeping it as YES for consistency with previous behaviour. */ - // forMainFrameOnly:_messagingEnabledForMainFrameOnly - forMainFrameOnly:YES - ] : - nil; - - if(_webView != nil){ - [self resetupScripts:_webView.configuration]; - } -} - -- (void)writeCookiesToWebView:(NSArray*)cookies completion:(void (^)(void))completion { - // The required cookie APIs only became available on iOS 11 - if (@available(iOS 11.0, *)) { - if (_sharedCookiesEnabled) { - __weak WKWebView *webView = _webView; - dispatch_async(dispatch_get_main_queue(), ^{ - dispatch_group_t group = dispatch_group_create(); - for (NSHTTPCookie *cookie in cookies) { - dispatch_group_enter(group); - [webView.configuration.websiteDataStore.httpCookieStore setCookie:cookie completionHandler:^{ - dispatch_group_leave(group); - }]; - } - dispatch_group_notify(group, dispatch_get_main_queue(), ^{ - if (completion) { - completion(); - } - }); - }); - return; - } - } - - if (completion) { - completion(); - } -} - -- (void)syncCookiesToWebView:(void (^)(void))completion { - NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; - [self writeCookiesToWebView:cookies completion:completion]; -} - -- (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig { - [wkWebViewConfig.userContentController removeAllUserScripts]; - [wkWebViewConfig.userContentController removeScriptMessageHandlerForName:MessageHandlerName]; - if(self.enableApplePay){ - if (self.postMessageScript){ - [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self] - name:MessageHandlerName]; - } - return; - } - - NSString *html5HistoryAPIShimSource = [NSString stringWithFormat: - @"(function(history) {\n" - " function notify(type) {\n" - " setTimeout(function() {\n" - " window.webkit.messageHandlers.%@.postMessage(type)\n" - " }, 0)\n" - " }\n" - " function shim(f) {\n" - " return function pushState() {\n" - " notify('other')\n" - " return f.apply(history, arguments)\n" - " }\n" - " }\n" - " history.pushState = shim(history.pushState)\n" - " history.replaceState = shim(history.replaceState)\n" - " window.addEventListener('popstate', function() {\n" - " notify('backforward')\n" - " })\n" - "})(window.history)\n", HistoryShimName - ]; - WKUserScript *script = [[WKUserScript alloc] initWithSource:html5HistoryAPIShimSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]; - [wkWebViewConfig.userContentController addUserScript:script]; - - if(_sharedCookiesEnabled) { - // More info to sending cookies with WKWebView - // https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303 - if (@available(iOS 11.0, *)) { - // Set Cookies in iOS 11 and above, initialize websiteDataStore before setting cookies - // See also https://forums.developer.apple.com/thread/97194 - // check if websiteDataStore has not been initialized before - if(!_incognito && !_cacheEnabled) { - wkWebViewConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore]; - } - [self syncCookiesToWebView:^{ - [wkWebViewConfig.websiteDataStore.httpCookieStore addObserver:self]; - }]; - } else { - NSMutableString *script = [NSMutableString string]; - - // Clear all existing cookies in a direct called function. This ensures that no - // javascript error will break the web content javascript. - // We keep this code here, if someone requires that Cookies are also removed within the - // the WebView and want to extends the current sharedCookiesEnabled option with an - // additional property. - // Generates JS: document.cookie = "key=; Expires=Thu, 01 Jan 1970 00:00:01 GMT;" - // for each cookie which is already available in the WebView context. - /* - [script appendString:@"(function () {\n"]; - [script appendString:@" var cookies = document.cookie.split('; ');\n"]; - [script appendString:@" for (var i = 0; i < cookies.length; i++) {\n"]; - [script appendString:@" if (cookies[i].indexOf('=') !== -1) {\n"]; - [script appendString:@" document.cookie = cookies[i].split('=')[0] + '=; Expires=Thu, 01 Jan 1970 00:00:01 GMT';\n"]; - [script appendString:@" }\n"]; - [script appendString:@" }\n"]; - [script appendString:@"})();\n\n"]; - */ - - // Set cookies in a direct called function. This ensures that no - // javascript error will break the web content javascript. - // Generates JS: document.cookie = "key=value; Path=/; Expires=Thu, 01 Jan 20xx 00:00:01 GMT;" - // for each cookie which is available in the application context. - [script appendString:@"(function () {\n"]; - for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) { - [script appendFormat:@"document.cookie = %@ + '=' + %@", - RCTJSONStringify(cookie.name, NULL), - RCTJSONStringify(cookie.value, NULL)]; - if (cookie.path) { - [script appendFormat:@" + '; Path=' + %@", RCTJSONStringify(cookie.path, NULL)]; - } - if (cookie.expiresDate) { - [script appendFormat:@" + '; Expires=' + new Date(%f).toUTCString()", - cookie.expiresDate.timeIntervalSince1970 * 1000 - ]; - } - [script appendString:@";\n"]; - } - [script appendString:@"})();\n"]; - - WKUserScript* cookieInScript = [[WKUserScript alloc] initWithSource:script - injectionTime:WKUserScriptInjectionTimeAtDocumentStart - forMainFrameOnly:YES]; - [wkWebViewConfig.userContentController addUserScript:cookieInScript]; - } - } - - if(_messagingEnabled){ - if (self.postMessageScript){ - [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self] - name:MessageHandlerName]; - [wkWebViewConfig.userContentController addUserScript:self.postMessageScript]; - } - if (self.atEndScript) { - [wkWebViewConfig.userContentController addUserScript:self.atEndScript]; - } - } - // Whether or not messaging is enabled, add the startup script if it exists. - if (self.atStartScript) { - [wkWebViewConfig.userContentController addUserScript:self.atStartScript]; - } -} - -- (NSURLRequest *)requestForSource:(id)json { - NSURLRequest *request = [RCTConvert NSURLRequest:self.source]; - - // If sharedCookiesEnabled we automatically add all application cookies to the - // http request. This is automatically done on iOS 11+ in the WebView constructor. - // Se we need to manually add these shared cookies here only for iOS versions < 11. - if (_sharedCookiesEnabled) { - if (@available(iOS 11.0, *)) { - // see WKWebView initialization for added cookies - } else if (request != nil) { - NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:request.URL]; - NSDictionary *cookieHeader = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies]; - NSMutableURLRequest *mutableRequest = [request mutableCopy]; - [mutableRequest setAllHTTPHeaderFields:cookieHeader]; - return mutableRequest; - } - } - return request; -} - -@end - -@implementation RNCWeakScriptMessageDelegate - -- (instancetype)initWithDelegate:(id)scriptDelegate { - self = [super init]; - if (self) { - _scriptDelegate = scriptDelegate; - } - return self; -} - -- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { - [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message]; -} - -@end diff --git a/apple/RNCWebViewManager.h b/apple/RNCWebViewManager.h deleted file mode 100644 index af000be5c..000000000 --- a/apple/RNCWebViewManager.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef RNCWebViewManager_h -#define RNCWebViewManager_h - -#import - -@interface RNCWebViewManager : RCTViewManager -@end - -#endif /* RNCWebViewManager_h */ diff --git a/apple/RNCWebViewManager.mm b/apple/RNCWebViewManager.mm deleted file mode 100644 index a6232f9e7..000000000 --- a/apple/RNCWebViewManager.mm +++ /dev/null @@ -1,232 +0,0 @@ -#import - -#import "RNCWebViewManager.h" -#import "RNCWebViewImpl.h" -#import "RNCWebViewDecisionManager.h" -#ifdef RCT_NEW_ARCH_ENABLED -#import "RNCWebViewSpec/RNCWebViewSpec.h" -#endif - -#if TARGET_OS_OSX -#define RNCView NSView -@class NSView; -#else -#define RNCView UIView -@class UIView; -#endif // TARGET_OS_OSX - -@implementation RCTConvert (WKWebView) -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ -RCT_ENUM_CONVERTER(WKContentMode, (@{ - @"recommended": @(WKContentModeRecommended), - @"mobile": @(WKContentModeMobile), - @"desktop": @(WKContentModeDesktop), -}), WKContentModeRecommended, integerValue) -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ -RCT_ENUM_CONVERTER(RNCWebViewPermissionGrantType, (@{ - @"grantIfSameHostElsePrompt": @(RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt), - @"grantIfSameHostElseDeny": @(RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny), - @"deny": @(RNCWebViewPermissionGrantType_Deny), - @"grant": @(RNCWebViewPermissionGrantType_Grant), - @"prompt": @(RNCWebViewPermissionGrantType_Prompt), -}), RNCWebViewPermissionGrantType_Prompt, integerValue) -#endif -@end - - -@implementation RNCWebViewManager { - NSConditionLock *_shouldStartLoadLock; - BOOL _shouldStartLoad; -} - -RCT_EXPORT_MODULE(RNCWebView) - -- (RNCView *)view -{ - return [[RNCWebViewImpl alloc] init]; -} - -RCT_EXPORT_VIEW_PROPERTY(source, NSDictionary) -// New arch only -RCT_CUSTOM_VIEW_PROPERTY(newSource, NSDictionary, RNCWebViewImpl) {} -RCT_EXPORT_VIEW_PROPERTY(onFileDownload, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onLoadingStart, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onLoadingFinish, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onLoadingError, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onLoadingProgress, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onHttpError, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onContentProcessDidTerminate, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onOpenWindow, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString) -RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptBeforeContentLoaded, NSString) -RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptForMainFrameOnly, BOOL) -RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptBeforeContentLoadedForMainFrameOnly, BOOL) -RCT_EXPORT_VIEW_PROPERTY(javaScriptEnabled, BOOL) -RCT_EXPORT_VIEW_PROPERTY(javaScriptCanOpenWindowsAutomatically, BOOL) -RCT_EXPORT_VIEW_PROPERTY(allowFileAccessFromFileURLs, BOOL) -RCT_EXPORT_VIEW_PROPERTY(allowUniversalAccessFromFileURLs, BOOL) -RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL) -RCT_EXPORT_VIEW_PROPERTY(webviewDebuggingEnabled, BOOL) -RCT_EXPORT_VIEW_PROPERTY(allowsAirPlayForMediaPlayback, BOOL) -RCT_EXPORT_VIEW_PROPERTY(mediaPlaybackRequiresUserAction, BOOL) -RCT_EXPORT_VIEW_PROPERTY(dataDetectorTypes, WKDataDetectorTypes) -RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets) -RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL) -RCT_EXPORT_VIEW_PROPERTY(autoManageStatusBarEnabled, BOOL) -RCT_EXPORT_VIEW_PROPERTY(hideKeyboardAccessoryView, BOOL) -RCT_EXPORT_VIEW_PROPERTY(allowsBackForwardNavigationGestures, BOOL) -RCT_EXPORT_VIEW_PROPERTY(incognito, BOOL) -RCT_EXPORT_VIEW_PROPERTY(pagingEnabled, BOOL) -RCT_EXPORT_VIEW_PROPERTY(applicationNameForUserAgent, NSString) -RCT_EXPORT_VIEW_PROPERTY(cacheEnabled, BOOL) -RCT_EXPORT_VIEW_PROPERTY(allowsLinkPreview, BOOL) -RCT_EXPORT_VIEW_PROPERTY(allowingReadAccessToURL, NSString) -RCT_EXPORT_VIEW_PROPERTY(basicAuthCredential, NSDictionary) - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ -RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior) -#endif -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ -RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustsScrollIndicatorInsets, BOOL) -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ -RCT_EXPORT_VIEW_PROPERTY(contentMode, WKContentMode) -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ -RCT_EXPORT_VIEW_PROPERTY(limitsNavigationsToAppBoundDomains, BOOL) -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140500 /* iOS 14.5 */ -RCT_EXPORT_VIEW_PROPERTY(textInteractionEnabled, BOOL) -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ -RCT_EXPORT_VIEW_PROPERTY(mediaCapturePermissionGrantType, RNCWebViewPermissionGrantType) -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ -RCT_EXPORT_VIEW_PROPERTY(fraudulentWebsiteWarningEnabled, BOOL) -#endif - -/** - * Expose methods to enable messaging the webview. - */ -RCT_EXPORT_VIEW_PROPERTY(messagingEnabled, BOOL) -RCT_EXPORT_VIEW_PROPERTY(onMessage, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(enableApplePay, BOOL) -RCT_EXPORT_VIEW_PROPERTY(menuItems, NSArray); -RCT_EXPORT_VIEW_PROPERTY(suppressMenuItems, NSArray); - -// New arch only -RCT_CUSTOM_VIEW_PROPERTY(hasOnFileDownload, BOOL, RNCWebViewImpl) {} -RCT_CUSTOM_VIEW_PROPERTY(hasOnOpenWindowEvent, BOOL, RNCWebViewImpl) {} - -RCT_EXPORT_VIEW_PROPERTY(onCustomMenuSelection, RCTDirectEventBlock) -RCT_CUSTOM_VIEW_PROPERTY(pullToRefreshEnabled, BOOL, RNCWebViewImpl) { - view.pullToRefreshEnabled = json == nil ? false : [RCTConvert BOOL: json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RNCWebViewImpl) { - view.bounces = json == nil ? true : [RCTConvert BOOL: json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(useSharedProcessPool, BOOL, RNCWebViewImpl) { - view.useSharedProcessPool = json == nil ? true : [RCTConvert BOOL: json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(userAgent, NSString, RNCWebViewImpl) { - view.userAgent = [RCTConvert NSString: json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(scrollEnabled, BOOL, RNCWebViewImpl) { - view.scrollEnabled = json == nil ? true : [RCTConvert BOOL: json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(sharedCookiesEnabled, BOOL, RNCWebViewImpl) { - view.sharedCookiesEnabled = json == nil ? false : [RCTConvert BOOL: json]; -} - -#if !TARGET_OS_OSX -RCT_CUSTOM_VIEW_PROPERTY(decelerationRate, CGFloat, RNCWebViewImpl) { - view.decelerationRate = json == nil ? UIScrollViewDecelerationRateNormal : [RCTConvert CGFloat: json]; -} -#endif // !TARGET_OS_OSX - -RCT_CUSTOM_VIEW_PROPERTY(directionalLockEnabled, BOOL, RNCWebViewImpl) { - view.directionalLockEnabled = json == nil ? true : [RCTConvert BOOL: json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(showsHorizontalScrollIndicator, BOOL, RNCWebViewImpl) { - view.showsHorizontalScrollIndicator = json == nil ? true : [RCTConvert BOOL: json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL, RNCWebViewImpl) { - view.showsVerticalScrollIndicator = json == nil ? true : [RCTConvert BOOL: json]; -} - -RCT_CUSTOM_VIEW_PROPERTY(keyboardDisplayRequiresUserAction, BOOL, RNCWebViewImpl) { - view.keyboardDisplayRequiresUserAction = json == nil ? true : [RCTConvert BOOL: json]; -} - -#if !TARGET_OS_OSX - #define BASE_VIEW_PER_OS() UIView -#else - #define BASE_VIEW_PER_OS() NSView -#endif - -#define QUICK_RCT_EXPORT_COMMAND_METHOD(name) \ -RCT_EXPORT_METHOD(name:(nonnull NSNumber *)reactTag) \ -{ \ -[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { \ - RNCWebViewImpl *view = (RNCWebViewImpl *)viewRegistry[reactTag]; \ - if (![view isKindOfClass:[RNCWebViewImpl class]]) { \ - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); \ - } else { \ - [view name]; \ - } \ - }]; \ -} -#define QUICK_RCT_EXPORT_COMMAND_METHOD_PARAMS(name, in_param, out_param) \ -RCT_EXPORT_METHOD(name:(nonnull NSNumber *)reactTag in_param) \ -{ \ -[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { \ - RNCWebViewImpl *view = (RNCWebViewImpl *)viewRegistry[reactTag]; \ - if (![view isKindOfClass:[RNCWebViewImpl class]]) { \ - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); \ - } else { \ - [view name:out_param]; \ - } \ - }]; \ -} - -QUICK_RCT_EXPORT_COMMAND_METHOD(reload) -QUICK_RCT_EXPORT_COMMAND_METHOD(goBack) -QUICK_RCT_EXPORT_COMMAND_METHOD(goForward) -QUICK_RCT_EXPORT_COMMAND_METHOD(stopLoading) -QUICK_RCT_EXPORT_COMMAND_METHOD(requestFocus) - -QUICK_RCT_EXPORT_COMMAND_METHOD_PARAMS(postMessage, message:(NSString *)message, message) -QUICK_RCT_EXPORT_COMMAND_METHOD_PARAMS(injectJavaScript, script:(NSString *)script, script) - -RCT_EXPORT_METHOD(shouldStartLoadWithLockIdentifier:(BOOL)shouldStart - lockIdentifier:(double)lockIdentifier) -{ - [[RNCWebViewDecisionManager getInstance] setResult:shouldStart forLockIdentifier:(int)lockIdentifier]; -} - -// Thanks to this guard, we won't compile this code when we build for the old architecture. -#ifdef RCT_NEW_ARCH_ENABLED -- (std::shared_ptr)getTurboModule: - (const facebook::react::ObjCTurboModule::InitParams &)params -{ - return std::make_shared(params); -} -#endif - -@end diff --git a/docs/Contributing.italian.md b/docs/Contributing.italian.md deleted file mode 100644 index 1376aaa19..000000000 --- a/docs/Contributing.italian.md +++ /dev/null @@ -1,103 +0,0 @@ -# Contribuire a React Native WebView - -Innanzitutto, _grazie_ per aver considerato di contribuire alla comunità di React Native. I pacchetti supportati dalla comunità sono possibili solo grazie a persone straordinarie come te. - -In secondo luogo, desideriamo che l'esperienza di contribuzione sia il migliore possibile. Nonostante siamo un piccolo team composto interamente da volontari, siamo felici di ricevere feedback sulla tua esperienza e se possiamo migliorare la documentazione o l'esperienza, ti preghiamo di farcelo sapere. - -## Come testare le modifiche - -Dopo aver forkato il reposito, clonalo sulla tuo computer e apporta le modifiche. Successivamente, potrai testarle in un'applicazione. - -Ci sono due metodi per testare: -1) testare all'interno di una copia di react-native-webview; -2) testare in un nuovo progetto creato con `react-native init`. - -### Testare in react-native-webview - -#### Per tutte le piattaforme: - -```sh -yarn install -``` - -#### Per Android: - -```sh -yarn android -``` - -L'applicazione di esempio per Android verrà compilata, Metro bundler si avvierà e l'applicazione verrà installata e avviata nell'emulatore Android. - -#### Per iOS: - -```sh -pod install --project-directory=example/ios -yarn ios -``` - -L'app di esempio per iOS verrà compilata, Metro bundler verrà avviato e l'app verrà installata e avviata nel simulatore. - -#### Per macOS: - -```sh -pod install --project-directory=example/macos -yarn macos -``` - -L'app di esempio per macOS verrà compilata, Metro bundler verrà avviato e l'app verrà installata e avviata. - -#### Per Windows: - -```sh -yarn windows -``` - -L'app di esempio per Windows verrà compilata, Metro bundler verrà avviato e l'app verrà installata e avviata. - -### Testare in un nuovo progetto con `react-native init` - -In un nuovo progetto `react-native init`, fai quanto segue: - -``` -$ yarn add -``` - -Potresti riscontrare un problema in cui la mappatura dei moduli `jest-haste-map` segnala che react-native è stato aggiunto due volte. - -``` -Loading dependency graph...(node:32651) UnhandledPromiseRejectionWarning: Error: jest-haste-map: Haste module naming collision: - Duplicate module name: react-native - Paths: /Users/myuser/TestApp/node_modules/react-native/package.json collides with /Users/myuser/TestApp/node_modules/react-native-webview/node_modules/react-native/package.json -``` - -In tal caso rimuovi il secondo path in questo modo: - -``` -$ rm -rf ./node_modules/react-native-webview/node_modules/react-native -``` - -E fai ripartire il packager assicurandoti di passare la flag per resettare la cache: - -``` -$ react-native start --reset-cache -``` - -Potresti anche visualizzare un avviso sulla console riguardante "Invalid hook call", seguito da un errore di interpretazione che indica "null is not an object (evaluating 'dispatcher.useRef')." Per risolvere questo problema, segui la stessa procedura di prima, ma questa volta elimina la cartella `react-native-webview/node_modules/react`. - -(se cancelli `react` prima di `react-native`, potresti incappare in un altro errore: "View config getter callback for component 'RNCWebView' must be a function," per risolvere il problema elimina anche `react-native`) - -Quando apporti una modifica, molto probabilmente dovrai rimuovere e aggiungere nuovamente `react-native-webview`: - -``` -$ yarn remove react-native-webview -$ yarn add ../react-native-webview -``` - -## Note -- Usiamo TypeScript. -- Dopo aver scaricato quest repo e installato tutte le dipendenze, puoi eseguire i test usando il comando: `yarn ci`. - -### Traduzioni -Questo file è disponibile nelle seguenti lingue: -- [Inglese](Contributing.md) -- [Portoghese brasiliano](Contributing.portuguese.md) \ No newline at end of file diff --git a/docs/Contributing.md b/docs/Contributing.md deleted file mode 100644 index 9f16711d6..000000000 --- a/docs/Contributing.md +++ /dev/null @@ -1,105 +0,0 @@ -# Contributing to React Native WebView - -First off, _thank you_ for considering contributing to the React Native Community. The community-supported packages are only possible because of amazing people like you. - -Secondly, we'd like the contribution experience to be as good as possible. While we are a small all-volunteer team, we are happy to hear feedback about your experience, and if we can make the docs or experience better please let us know. - -## How to test changes - -After you fork the repo, clone it to your machine, and make your changes, you'll want to test them in an app. - -There are two methods of testing: -1) Testing within a clone of react-native-webview -2) Testing in a new `react-native init` project - -### Testing within react-native-webview - -#### For all platforms: - -```sh -yarn install -``` - -#### For Android: - -```sh -yarn android -``` - -The Android example app will built, the Metro bundler will launch, and the example app will be installed and started in the Android emulator. - -#### For iOS: - -```sh -pod install --project-directory=example/ios -yarn ios -``` - -The iOS example app will be built, the Metro bundler will launch, and the example app will be installed and started in the Simulator. - -#### For macOS: - -```sh -pod install --project-directory=macos -yarn macos -``` - -The macOS example app will be built, the Metro bundler will launch, and the example app will be installed and started. - -#### For Windows: - -```sh -yarn windows -``` - -The Windows example app will be built, the Metro bundler will launch, and the example app will be installed and started. - -### Testing in a new `react-native init` project - -In a new `react-native init` project, do this: - -``` -$ yarn add -``` - -You may run into a problem where the `jest-haste-map` module map says react-native was added twice: - -``` -Loading dependency graph...(node:32651) UnhandledPromiseRejectionWarning: Error: jest-haste-map: Haste module naming collision: - Duplicate module name: react-native - Paths: /Users/myuser/TestApp/node_modules/react-native/package.json collides with /Users/myuser/TestApp/node_modules/react-native-webview/node_modules/react-native/package.json -``` - -Just remove the second path like this: - -``` -$ rm -rf ./node_modules/react-native-webview/node_modules/react-native -``` - -And then re-run the packager: - -``` -$ react-native start --reset-cache -``` - -You may also see a console warning about "Invalid hook call," followed by a render error that "null is not an object (evaluating 'dispatcher.useRef')." Resolving this is similar to the above, but this time remove `react-native-webview/node_modules/react`. - -(if you remove `react` before `react-native`, you may see another render error for "View config getter callback for component 'RNCWebView' must be a function," just remove `react-native` as well to fix this) - -When you make a change, you'll probably need to remove and re-add `react-native-webview`: - -``` -$ yarn remove react-native-webview -$ yarn add ../react-native-webview -``` - -## Notes - -- We use TypeScript. -- After pulling this repo and installing all dependencies, you can run tests using the command: `yarn ci` - -## Translations -This file is available in: - -- [Brazilian portuguese](Contributing.portuguese.md) -- [Italian](Contributing.italian.md) diff --git a/docs/Contributing.portuguese.md b/docs/Contributing.portuguese.md deleted file mode 100644 index 7da82d39b..000000000 --- a/docs/Contributing.portuguese.md +++ /dev/null @@ -1,103 +0,0 @@ -# Contribuindo com o React Native WebView - -Primeiramente, _obrigado_ por considerar contribuir para a Comunidade do React Native. Os pacotes mantidos pela comunidade só são possíveis por causa de pessoas incríveis como você. - -Em segundo lugar, gostaríamos que a experiência de contribuição fosse a melhor possível. Embora sejamos uma pequena equipe de voluntários, ficamos felizes em receber comentários sobre suas experiências e se pudermos melhorar os documentos ou a experiência, informe-nos. - -## Como testar as alterações - -Após fazer um fork do repositório, cloná-lo em sua máquina e fazer suas alterações, você deverar testá-las em uma aplicação. - -Existem dois métodos de teste: -1) Rodando os testes do react-native-webview -2) Testando em um projeto `react-native init` - -### Rodando os testes dentro do react-native-webview - -#### Para todas as plataformas: - -```sh -yarn install -``` - -#### Para Android: - -```sh -yarn android -``` - -O aplicativo de exemplo do Android será compilado, o Metro Bundler será iniciado e o aplicativo de exemplo será instalado e iniciado no emulador do Android. - -#### Para iOS: - -```sh -pod install --project-directory=example/ios -yarn ios -``` - -O aplicativo de exemplo para iOS será compilado, o empacotador Metro será iniciado e o aplicativo de exemplo será instalado e iniciado no Simulador. - -#### Para macOS: - -```sh -pod install --project-directory=example/macos -yarn macos -``` - -O aplicativo de exemplo para macOS será compilado, o empacotador Metro será iniciado e o aplicativo de exemplo será instalado e iniciado. - -#### Para Windows: - -```sh -yarn windows -``` - -O aplicativo de exemplo para Windows será compilado, o empacotador Metro será iniciado e o aplicativo de exemplo será instalado e iniciado. - -### Testando em um novo projeto `react-native init` - -Em um novo projeto `react-native init`, faça o seguinte: - -``` -$ yarn add ../react-native-webview -$ react-native link react-native-webview -``` - -Você pode encontrar um problema em que o mapa do módulo `jest-haste-map` diz que react-native foi adicionado duas vezes: - -``` -Loading dependency graph...(node:32651) UnhandledPromiseRejectionWarning: Error: jest-haste-map: Haste module naming collision: - Duplicate module name: react-native - Paths: /Users/myuser/TestApp/node_modules/react-native/package.json collides with /Users/myuser/TestApp/node_modules/react-native-webview/node_modules/react-native/package.json -``` - -Basta remover seguindo o caminho abaixo: - -``` -$ rm -rf ./node_modules/react-native-webview/node_modules/react-native -``` - -E, em seguida, execute novamente o comando: - -``` -$ react-native start --reset-cache -``` - -Ao fazer uma alteração, você provavelmente precisará desvincular, remover, adicionar novamente e vincular novamente o `react-native-webview`: - -``` -$ react-native unlink react-native-webview && yarn remove react-native-webview -$ yarn add ../react-native-webview && react-native link react-native-webview -``` - -## Notas - -- Usamos TypeScript. -- Depois de puxar este repositório e instalar todas as dependências, você pode executar testes usando o comando: `yarn ci` - -## Traduções - -Esse arquivo está disponível em: - -- [Inglês](Contributing.md) -- [Italiano](Contributing.italian.md) diff --git a/docs/Custom-Android.italian.md b/docs/Custom-Android.italian.md deleted file mode 100644 index b402d599f..000000000 --- a/docs/Custom-Android.italian.md +++ /dev/null @@ -1,219 +0,0 @@ -Nonostante la web view integrata disponga di molte funzionalità, non è possibile gestire tutti i casi d'uso in React Native. Tuttavia, è possibile estendere la web view con codice nativo senza dover forkare React Native o duplicare l'intero codice esistente della web view. - -Prima di procedere, è consigliabile avere un'idea di base dei concetti legati ai [native UI components](https://reactnative.dev/docs/native-components-android) (componenti dell'interfaccia utente nativi). Inoltre, è opportuno familiarizzarsi con il [native code for web views](https://github.com/react-native-webview/react-native-webview/blob/master/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java) (codice nativo per le web view), poiché sarà necessario farvi riferimento durante l'implementazione delle nuove funzionalità, anche se non è richiesta una conoscenza approfondita. - -## Codice nativo -Per iniziare, dovrai creare una sottoclasse di `RNCWebViewManager`, `RNCWebView` e `RNCWebViewClient`. Poi, nel gestore della view, sovrascrivi i seguenti metodi: - -- `createReactWebViewInstance` -- `getName` -- `addEventEmitters` - -```java -@ReactModule(name = CustomWebViewManager.REACT_CLASS) -public class CustomWebViewManager extends RNCWebViewManager { - /* Il nome usato qua deve essere identico a quello usato in JS. */ - protected static final String REACT_CLASS = "RCTCustomWebView"; - - protected static class CustomWebViewClient extends RNCWebViewClient { } - - protected static class CustomWebView extends RNCWebView { - public CustomWebView(ThemedReactContext reactContext) { - super(reactContext); - } - } - - @Override - protected RNCWebView createViewInstance(ThemedReactContext reactContext) { - return super.createViewInstance(reactContext, new CustomWebView(reactContext)); - } - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - protected void addEventEmitters(ThemedReactContext reactContext, RNCWebView view) { - view.setWebViewClient(new CustomWebViewClient()); - } -} -``` - -Poi dovrai seguire i soliti passaggi per [register the module](https://reactnative.dev/docs/native-modules-android#register-the-module-android-specific) (registrare il modulo Android). - -### Aggiungere nuove proprietà -Per aggiungere una nuova proprietà, è necessario includerla in `CustomWebView` e successivamente esporla tramite `CustomWebViewManager`. - -```java -public class CustomWebViewManager extends RNCWebViewManager { - ... - - protected static class CustomWebView extends RNCWebView { - public CustomWebView(ThemedReactContext reactContext) { - super(reactContext); - } - - protected @Nullable String mFinalUrl; - - public void setFinalUrl(String url) { - mFinalUrl = url; - } - - public String getFinalUrl() { - return mFinalUrl; - } - } - - ... - - @ReactProp(name = "finalUrl") - public void setFinalUrl(WebView view, String url) { - ((CustomWebView) view).setFinalUrl(url); - } -} -``` - -### Aggiungere nuovi eventi -Per gli eventi, dovrai prima creare una sottoclasse degli eventi. - -```java -// NavigationCompletedEvent.java -public class NavigationCompletedEvent extends Event { - private WritableMap mParams; - - public NavigationCompletedEvent(int viewTag, WritableMap params) { - super(viewTag); - this.mParams = params; - } - - @Override - public String getEventName() { - return "navigationCompleted"; - } - - @Override - public void dispatch(RCTEventEmitter rctEventEmitter) { - init(getViewTag()); - rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams); - } -} -``` - -Puoi far partire l'evento nel tuo client della web view. Puoi anche collegare handler già esistenti se i tuoi eventi si basano su di essi. - -Fai riferimento al file [RNCWebViewManager.java](https://github.com/react-native-webview/react-native-webview/blob/master/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java) nel codice sorgente di `react-native-webview` per vedere quali handler sono disponibili e come sono implementati. Puoi estendere qualsiasi metodo qui per fornire funzionalità aggiuntive. - -```java -public class NavigationCompletedEvent extends Event { - private WritableMap mParams; - - public NavigationCompletedEvent(int viewTag, WritableMap params) { - super(viewTag); - this.mParams = params; - } - - @Override - public String getEventName() { - return "navigationCompleted"; - } - - @Override - public void dispatch(RCTEventEmitter rctEventEmitter) { - init(getViewTag()); - rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams); - } -} - -// CustomWebViewManager.java -protected static class CustomWebViewClient extends RNCWebViewClient { - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - boolean shouldOverride = super.shouldOverrideUrlLoading(view, url); - String finalUrl = ((CustomWebView) view).getFinalUrl(); - - if (!shouldOverride && url != null && finalUrl != null && new String(url).equals(finalUrl)) { - final WritableMap params = Arguments.createMap(); - dispatchEvent(view, new NavigationCompletedEvent(view.getId(), params)); - } - - return shouldOverride; - } -} -``` - -Infine, esponi gli eventi in `CustomWebViewManager` attraverso `getExportedCustomDirectEventTypeConstants`. Nota che attualmente l'implementazione predefinita restituisce `null`, ma questo potrebbe cambiare in futuro. - -```java -public class CustomWebViewManager extends RNCWebViewManager { - ... - - @Override - public @Nullable - Map getExportedCustomDirectEventTypeConstants() { - Map export = super.getExportedCustomDirectEventTypeConstants(); - if (export == null) { - export = MapBuilder.newHashMap(); - } - export.put("navigationCompleted", MapBuilder.of("registrationName", "onNavigationCompleted")); - return export; - } -} -``` - -## Interfaccia JavaScript - -Per usufruire della tua web view personalizzata, è consigliabile creare una classe dedicata che restituisca un componente `WebView` con la prop `nativeConfig.component` impostata sul tuo componente nativo (come dimostrato di seguito). - -Per richiamare il tuo componente nativo, puoi usare il metodo `requireNativeComponent`, come di consueto per i componenti personalizzati. - -```javascript -import React, { Component } from 'react'; -import { requireNativeComponent } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class CustomWebView extends Component { - render() { - return ( - - ); - } -} - -const RCTCustomWebView = requireNativeComponent('RCTCustomWebView'); -``` - -Se desideri aggiungere props personalizzate al tuo componente nativo, puoi utilizzare `nativeConfig.props` sulla web view. - -Per gli eventi, l'handler deve essere sempre una funzione. Ciò significa che non è sicuro chiamare l'handler direttamente da `this.props`, poiché l'utente potrebbe non averne fornito uno. L'approccio di base consiste nel creare un handler delle'evento nella tua classe, per poi invocarlo solamente se l'handler fornito da `this.props` esiste. - -Se non sei sicuro su come qualcosa debba essere implementato nel lato JS, dai un'occhiata al file [WebView.android.tsx](https://github.com/react-native-webview/react-native-webview/blob/master/src/WebView.android.tsx) nel codice sorgente di React Native WebView. - -```javascript -export default class CustomWebView extends Component { - _onNavigationCompleted = (event) => { - const { onNavigationCompleted } = this.props; - onNavigationCompleted && onNavigationCompleted(event); - }; - - render() { - return ( - - ); - } -} -``` - -### Traduzioni -Questo file è disponibile nelle seguenti lingue: -- [Inglese](Custom-Android.md) -- [Portoghese brasiliano](Custom-Android.portuguese.md) \ No newline at end of file diff --git a/docs/Custom-Android.md b/docs/Custom-Android.md deleted file mode 100644 index 918689966..000000000 --- a/docs/Custom-Android.md +++ /dev/null @@ -1,222 +0,0 @@ -While the built-in web view has a lot of features, it is not possible to handle every use-case in React Native. You can, however, extend the web view with native code without forking React Native or duplicating all the existing web view code. - -Before you do this, you should be familiar with the concepts in [native UI components](https://reactnative.dev/docs/native-components-android). You should also familiarise yourself with the [native code for web views](https://github.com/react-native-webview/react-native-webview/blob/master/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java), as you will have to use this as a reference when implementing new features—although a deep understanding is not required. - -## Native Code - -To get started, you'll need to create a subclass of `RNCWebViewManager`, `RNCWebView`, and `RNCWebViewClient`. In your view manager, you'll then need to override: - -- `createReactWebViewInstance` -- `getName` -- `addEventEmitters` - -```java -@ReactModule(name = CustomWebViewManager.REACT_CLASS) -public class CustomWebViewManager extends RNCWebViewManager { - /* This name must match what we're referring to in JS */ - protected static final String REACT_CLASS = "RCTCustomWebView"; - - protected static class CustomWebViewClient extends RNCWebViewClient { } - - protected static class CustomWebView extends RNCWebView { - public CustomWebView(ThemedReactContext reactContext) { - super(reactContext); - } - } - - @Override - protected RNCWebView createViewInstance(ThemedReactContext reactContext) { - return super.createViewInstance(reactContext, new CustomWebView(reactContext)); - } - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - protected void addEventEmitters(ThemedReactContext reactContext, RNCWebView view) { - view.setWebViewClient(new CustomWebViewClient()); - } -} -``` - -You'll need to follow the usual steps to [register the module](https://reactnative.dev/docs/native-modules-android#register-the-module-android-specific). - -### Adding New Properties - -To add a new property, you'll need to add it to `CustomWebView`, and then expose it in `CustomWebViewManager`. - -```java -public class CustomWebViewManager extends RNCWebViewManager { - ... - - protected static class CustomWebView extends RNCWebView { - public CustomWebView(ThemedReactContext reactContext) { - super(reactContext); - } - - protected @Nullable String mFinalUrl; - - public void setFinalUrl(String url) { - mFinalUrl = url; - } - - public String getFinalUrl() { - return mFinalUrl; - } - } - - ... - - @ReactProp(name = "finalUrl") - public void setFinalUrl(WebView view, String url) { - ((CustomWebView) view).setFinalUrl(url); - } -} -``` - -### Adding New Events - -For events, you'll first need to make create event subclass. - -```java -// NavigationCompletedEvent.java -public class NavigationCompletedEvent extends Event { - private WritableMap mParams; - - public NavigationCompletedEvent(int viewTag, WritableMap params) { - super(viewTag); - this.mParams = params; - } - - @Override - public String getEventName() { - return "navigationCompleted"; - } - - @Override - public void dispatch(RCTEventEmitter rctEventEmitter) { - init(getViewTag()); - rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams); - } -} -``` - -You can trigger the event in your web view client. You can hook existing handlers if your events are based on them. - -You should refer to [RNCWebViewManager.java](https://github.com/react-native-webview/react-native-webview/blob/master/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java) in the react-native-webview codebase to see what handlers are available and how they are implemented. You can extend any methods here to provide extra functionality. - -```java -public class NavigationCompletedEvent extends Event { - private WritableMap mParams; - - public NavigationCompletedEvent(int viewTag, WritableMap params) { - super(viewTag); - this.mParams = params; - } - - @Override - public String getEventName() { - return "navigationCompleted"; - } - - @Override - public void dispatch(RCTEventEmitter rctEventEmitter) { - init(getViewTag()); - rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams); - } -} - -// CustomWebViewManager.java -protected static class CustomWebViewClient extends RNCWebViewClient { - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - boolean shouldOverride = super.shouldOverrideUrlLoading(view, url); - String finalUrl = ((CustomWebView) view).getFinalUrl(); - - if (!shouldOverride && url != null && finalUrl != null && new String(url).equals(finalUrl)) { - final WritableMap params = Arguments.createMap(); - dispatchEvent(view, new NavigationCompletedEvent(view.getId(), params)); - } - - return shouldOverride; - } -} -``` - -Finally, you'll need to expose the events in `CustomWebViewManager` through `getExportedCustomDirectEventTypeConstants`. Note that currently, the default implementation returns `null`, but this may change in the future. - -```java -public class CustomWebViewManager extends RNCWebViewManager { - ... - - @Override - public @Nullable - Map getExportedCustomDirectEventTypeConstants() { - Map export = super.getExportedCustomDirectEventTypeConstants(); - if (export == null) { - export = MapBuilder.newHashMap(); - } - export.put("navigationCompleted", MapBuilder.of("registrationName", "onNavigationCompleted")); - return export; - } -} -``` - -## JavaScript Interface - -To use your custom web view, you may want to create a class for it. Your class must return a `WebView` component with the prop `nativeConfig.component` set to your native component (see below). - -To get your native component, you must use `requireNativeComponent`: the same as for regular custom components. - -```javascript -import React, { Component } from 'react'; -import { requireNativeComponent } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class CustomWebView extends Component { - render() { - return ( - - ); - } -} - -const RCTCustomWebView = requireNativeComponent('RCTCustomWebView'); -``` - -If you want to add custom props to your native component, you can use `nativeConfig.props` on the web view. - -For events, the event handler must always be set to a function. This means it isn't safe to use the event handler directly from `this.props`, as the user might not have provided one. The standard approach is to create a event handler in your class, and then invoking the event handler given in `this.props` if it exists. - -If you are unsure how something should be implemented from the JS side, look at [WebView.android.tsx](https://github.com/react-native-webview/react-native-webview/blob/master/src/WebView.android.tsx) in the React Native WebView source. - -```javascript -export default class CustomWebView extends Component { - _onNavigationCompleted = (event) => { - const { onNavigationCompleted } = this.props; - onNavigationCompleted && onNavigationCompleted(event); - }; - - render() { - return ( - - ); - } -} -``` -## Translations - -This file is available in: -- [Brazilian portuguese](Custom-Android.portuguese.md) -- [Italian](Custom-Android.italian.md) \ No newline at end of file diff --git a/docs/Custom-Android.portuguese.md b/docs/Custom-Android.portuguese.md deleted file mode 100644 index 3bdb141cf..000000000 --- a/docs/Custom-Android.portuguese.md +++ /dev/null @@ -1,224 +0,0 @@ -Embora a visualização da Web integrada tenha muitos recursos, não é possível lidar com todos os casos de uso no React Native. Você pode, no entanto, estender a visualização da web com código nativo sem bifurcar o React Native ou duplicar todo o código de visualização da web existente. - -Antes de fazer isso, você deve estar familiarizado com os conceitos de [componentes de interface do usuário nativos](https://reactnative.dev/docs/native-components-android). Você também deve se familiarizar com o [código nativo para visualizações da web](https://github.com/react-native-webview/react-native-webview/blob/master/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java), pois você terá que usar isso como referência ao implementar novos recursos, embora não seja necessária uma compreensão profunda. - -## Código Nativo - -Para começar, você precisará criar uma subclasse de `RNCWebViewManager`, `RNCWebView` e `RNCWebViewClient`. Em seu gerenciador de visualizações, você precisará substituir: - -- `createReactWebViewInstance` -- `getName` -- `addEventEmitters` - -```java -@ReactModule(name = CustomWebViewManager.REACT_CLASS) -public class CustomWebViewManager extends RNCWebViewManager { - /* Este nome deve corresponder ao que estamos nos referindo em JS */ - protected static final String REACT_CLASS = "RCTCustomWebView"; - - protected static class CustomWebViewClient extends RNCWebViewClient { } - - protected static class CustomWebView extends RNCWebView { - public CustomWebView(ThemedReactContext reactContext) { - super(reactContext); - } - } - - @Override - protected RNCWebView createRNCWebViewInstance(ThemedReactContext reactContext) { - return new CustomWebView(reactContext); - } - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - protected void addEventEmitters(ThemedReactContext reactContext, WebView view) { - view.setWebViewClient(new CustomWebViewClient()); - } -} -``` - -Você precisará seguir as etapas usuais para [registrar o módulo](https://reactnative.dev/docs/native-modules-android#register-the-module-android-specific). - -### Adicionando novas propriedades - -Para adicionar uma nova propriedade, você precisará adicioná-la a `CustomWebView` e depois expô-la em `CustomWebViewManager`. - -```java -public class CustomWebViewManager extends RNCWebViewManager { - ... - - protected static class CustomWebView extends RNCWebView { - public CustomWebView(ThemedReactContext reactContext) { - super(reactContext); - } - - protected @Nullable String mFinalUrl; - - public void setFinalUrl(String url) { - mFinalUrl = url; - } - - public String getFinalUrl() { - return mFinalUrl; - } - } - - ... - - @ReactProp(name = "finalUrl") - public void setFinalUrl(WebView view, String url) { - ((CustomWebView) view).setFinalUrl(url); - } -} -``` - -### Adicionando novos eventos - -Para eventos, primeiro você precisará criar uma subclasse de evento. - -```java -// NavigationCompletedEvent.java -public class NavigationCompletedEvent extends Event { - private WritableMap mParams; - - public NavigationCompletedEvent(int viewTag, WritableMap params) { - super(viewTag); - this.mParams = params; - } - - @Override - public String getEventName() { - return "navigationCompleted"; - } - - @Override - public void dispatch(RCTEventEmitter rctEventEmitter) { - init(getViewTag()); - rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams); - } -} -``` - -Você pode acionar o evento em seu cliente de visualização da web. Você pode conectar manipuladores existentes se seus eventos forem baseados neles. - -Você deve consultar [RNCWebViewManager.java](https://github.com/react-native-webview/react-native-webview/blob/master/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java) na base de código react-native-webview para ver quais manipuladores estão disponíveis e como eles são implementados. Você pode estender quaisquer métodos aqui para fornecer funcionalidade extra. - -```java -public class NavigationCompletedEvent extends Event { - private WritableMap mParams; - - public NavigationCompletedEvent(int viewTag, WritableMap params) { - super(viewTag); - this.mParams = params; - } - - @Override - public String getEventName() { - return "navigationCompleted"; - } - - @Override - public void dispatch(RCTEventEmitter rctEventEmitter) { - init(getViewTag()); - rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams); - } -} - -// CustomWebViewManager.java -protected static class CustomWebViewClient extends RNCWebViewClient { - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - boolean shouldOverride = super.shouldOverrideUrlLoading(view, url); - String finalUrl = ((CustomWebView) view).getFinalUrl(); - - if (!shouldOverride && url != null && finalUrl != null && new String(url).equals(finalUrl)) { - final WritableMap params = Arguments.createMap(); - dispatchEvent(view, new NavigationCompletedEvent(view.getId(), params)); - } - - return shouldOverride; - } -} -``` - -Finalmente, você precisará expor os eventos em `CustomWebViewManager` através de `getExportedCustomDirectEventTypeConstants`. Observe que atualmente, a implementação padrão retorna `null`, mas isso pode mudar no futuro. - -```java -public class CustomWebViewManager extends RNCWebViewManager { - ... - - @Override - public @Nullable - Map getExportedCustomDirectEventTypeConstants() { - Map export = super.getExportedCustomDirectEventTypeConstants(); - if (export == null) { - export = MapBuilder.newHashMap(); - } - export.put("navigationCompleted", MapBuilder.of("registrationName", "onNavigationCompleted")); - return export; - } -} -``` - -## Interface JavaScript - -Para usar sua visualização da Web personalizada, você pode criar uma classe para ela. Sua classe deve retornar um componente `WebView` com o prop `nativeConfig.component` definido para seu componente nativo (veja abaixo). - -Para obter seu componente nativo, você deve usar `requireNativeComponent`: o mesmo que para componentes personalizados regulares. - -```javascript -import React, { Component } from 'react'; -import { requireNativeComponent } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class CustomWebView extends Component { - render() { - return ( - - ); - } -} - -const RCTCustomWebView = requireNativeComponent('RCTCustomWebView'); -``` - -Se você quiser adicionar props customizadas ao seu componente nativo, você pode usar `nativeConfig.props` na visualização da web. - -Para eventos, o manipulador de eventos deve sempre ser definido para uma função. Isso significa que não é seguro usar o manipulador de eventos diretamente de `this.props`, pois o usuário pode não ter fornecido um. A abordagem padrão é criar um manipulador de eventos em sua classe e, em seguida, invocar o manipulador de eventos fornecido em `this.props` se ele existir. - -Se você não tiver certeza de como algo deve ser implementado do lado do JS, consulte [WebView.android.tsx](https://github.com/react-native-webview/react-native-webview/blob/master/src/WebView.android.tsx) na fonte React Native WebView. - -```javascript -export default class CustomWebView extends Component { - _onNavigationCompleted = (event) => { - const { onNavigationCompleted } = this.props; - onNavigationCompleted && onNavigationCompleted(event); - }; - - render() { - return ( - - ); - } -} -``` - -## Traduções - -Esse arquivo está disponível em: - -- [Inglês](Custom-Android.md) -- [Italiano](Custom-Android.italian.md) \ No newline at end of file diff --git a/docs/Custom-iOS.italian.md b/docs/Custom-iOS.italian.md deleted file mode 100644 index 4f1c32f25..000000000 --- a/docs/Custom-iOS.italian.md +++ /dev/null @@ -1,226 +0,0 @@ -**NOTA: Questo documento è stato importato dalla [documentazione originale di WebView](https://github.com/facebook/react-native-website/blob/7d3e9e120e38a7ba928f6b173eb98f88b6f2f85f/docs/custom-webview-ios.md). Sebbene possa risultare utile, non è stato ancora adattato a React Native WebView.** - -Nonostante la web view integrata disponga di molte funzionalità, non è possibile gestire tutti i casi d'uso in React Native. Tuttavia, è possibile estendere la web view con codice nativo senza dover forkare React Native o duplicare l'intero codice esistente della web view. - -Prima di procedere, è consigliabile avere un'idea di base dei concetti legati ai [native UI components](native-components-ios) (componenti dell'interfaccia utente nativi). Inoltre, è opportuno familiarizzarsi con il [native code for web views](https://github.com/react-native-webview/react-native-webview/blob/master/apple/RNCWebViewManager.m) (codice nativo per le web view), poiché sarà necessario farvi riferimento durante l'implementazione delle nuove funzionalità, anche se non è richiesta una conoscenza approfondita. - -## Codice nativo -Come per i componenti nativi regolari, è necessario un gestore della view e una web view. - -Per la view, è necessario creare una sottoclasse di `RCTWebView`. - -```objc -// RCTCustomWebView.h -#import - -@interface RCTCustomWebView : RCTWebView - -@end - -// RCTCustomWebView.m -#import "RCTCustomWebView.h" - -@interface RCTCustomWebView () - -@end - -@implementation RCTCustomWebView { } - -@end -``` - -Per il gestore della view, è necessario creare una sottoclasse di RCTWebViewManager. Devi includere: -* `(UIView *)view` che restituisce la tua view personalizzata; -* la funzione macro `RCT_EXPORT_MODULE()`. - -```objc -// RCTCustomWebViewManager.h -#import - -@interface RCTCustomWebViewManager : RCTWebViewManager - -@end -``` - -```objc -// RCTCustomWebViewManager.m -#import "RCTCustomWebViewManager.h" -#import "RCTCustomWebView.h" - -@interface RCTCustomWebViewManager () - -@end - -@implementation RCTCustomWebViewManager { } - -RCT_EXPORT_MODULE() - -- (UIView *)view -{ - RCTCustomWebView *webView = [RCTCustomWebView new]; - webView.delegate = self; - return webView; -} - -@end -``` - -### Aggiungere nuovi eventi e proprietà -L'aggiunta di nuove proprietà ed eventi è simile ai componenti UI tradizionali. Per le proprietà, definisci una `@property` nell'header. Per gli eventi, definisci un `RCTDirectEventBlock` nell'`@interface` della view. - -```objc -// RCTCustomWebView.h -@property (nonatomic, copy) NSString *finalUrl; -``` - -```objc -// RCTCustomWebView.m -@interface RCTCustomWebView () - -@property (nonatomic, copy) RCTDirectEventBlock onNavigationCompleted; - -@end -``` - -Successivamente, esponilo nell'`@implementation` del gestore della view. - -```objc -// RCTCustomWebViewManager.m -RCT_EXPORT_VIEW_PROPERTY(onNavigationCompleted, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(finalUrl, NSString) -``` - - -### Estensione degli eventi esistenti -Riferisciti a [RCTWebView.m](https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m) nel codice sorgente di React Native per vedere quali handler sono disponibili e come sono implementati. Puoi estendere qualsiasi metodo qui per fornire funzionalità aggiuntive. - -In generale, la maggior parte dei metodi all'interno di RCTWebView non sono resi accessibili. Tuttavia, nel caso in cui tu abbia la necessità di utilizzarli, è possibile creare una [categoria in Objective-C](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html) e successivamente esporre tutti i metodi specifici che desideri usare. - -```objc -// RCTWebView+Custom.h -#import - -@interface RCTWebView (Custom) -- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; -- (NSMutableDictionary *)baseEvent; -@end -``` - -Una volta esposti i metodi, puoi farvi riferimento nella tua classe di web view personalizzata. - -```objc -// RCTCustomWebView.m - -// Ricorda di importare il file di categoria. -#import "RCTWebView+Custom.h" - -- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request - navigationType:(UIWebViewNavigationType)navigationType -{ - BOOL allowed = [super webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; - - if (allowed) { - NSString* url = request.URL.absoluteString; - if (url && [url isEqualToString:_finalUrl]) { - if (_onNavigationCompleted) { - NSMutableDictionary *event = [self baseEvent]; - _onNavigationCompleted(event); - } - } - } - - return allowed; -} -``` - -### Impostazione delle credenziali di autenticazione del certificato client -Se si aprono pagine web che richiedono un certificato client per l'autenticazione, è possibile creare una credenziale e passarla alla webview: - -``` -[RNCWebView setClientAuthenticationCredential:credential]; -``` - -Ciò può essere abbinato a una chiamata da JavaScript per passare una stringa etichetta per il certificato memorizzato nel portachiavi iCloud (Keychain) e utilizzare chiamate native per recuperare il certificato e creare un oggetto di credenziale. Questa chiamata può essere effettuata ovunque abbia senso per la tua applicazione (e.g. come parte dello stack di autenticazione dell'utente). L'unico requisito è effettuare questa chiamata prima di visualizzare qualsiasi webview. - -### Consenti CA personalizzate (Certificati di Autorità) e abilita l'SSL Pinning -Se è necessario connettersi a un server che ha un certificato firmato o se si desidera eseguire l'SSL Pinning sulle richieste della webview, è necessario passare un dizionario con l'host come chiave e il certificato come valore di ciascun elemento: - -```objc --(void)installCerts { - - // Usa il bundle in cui sono presenti i certificati nel formato DER. - NSBundle *bundle = [NSBundle mainBundle]; - - NSMutableDictionary* certMap = [NSMutableDictionary new]; - - NSData *rootCertData = [NSData dataWithContentsOfFile:[bundle pathForResource:@"example_ca" ofType:@"der"]]; - - SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (CFDataRef) rootCertData); - - OSStatus err = SecItemAdd((CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys:(id) kSecClassCertificate, kSecClass, certificate, kSecValueRef, nil], NULL); - - [certMap setObject:(__bridge id _Nonnull)(certificate) forKey:@"example.com"]; - - [RNCWebView setCustomCertificatesForHost:certMap]; -} - -``` - -È possibile aggiungere più host al dizionario, ma è consentito un solo certificato per ogni host. La verifica avrà successo se uno qualsiasi dei certificati nella catena della richiesta corrisponde a quello definito per l'host della richiesta. - -## Interfaccia JavaScript - -Per usufruire della tua web view personalizzata, è consigliabile creare una classe dedicata che restituisca un componente `WebView` con la prop `nativeConfig.component` impostata sul tuo componente nativo (come dimostrato di seguito). - -Per richiamare il tuo componente nativo, puoi usare il metodo `requireNativeComponent`, come di consueto per i componenti personalizzati. - -```javascript -import React, { Component } from 'react'; -import { requireNativeComponent } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class CustomWebView extends Component { - render() { - return ( - - ); - } -} - -const RCTCustomWebView = requireNativeComponent('RCTCustomWebView'); -``` - -Se desideri aggiungere props personalizzate al tuo componente nativo, puoi utilizzare `nativeConfig.props` sulla web view. - -Per gli eventi, l'handler deve essere sempre una funzione. Ciò significa che non è sicuro chiamare l'handler direttamente da `this.props`, poiché l'utente potrebbe non averne fornito uno. L'approccio di base consiste nel creare un handler delle'evento nella tua classe, per poi invocarlo solamente se l'handler fornito da `this.props` esiste. - -Se non sei sicuro su come qualcosa debba essere implementato nel lato JS, dai un'occhiata al file [WebView.android.tsx](https://github.com/react-native-webview/react-native-webview/blob/master/src/WebView.ios.tsx) nel codice sorgente di React Native WebView. - -```javascript -export default class CustomWebView extends Component { - _onNavigationCompleted = (event) => { - const { onNavigationCompleted } = this.props; - onNavigationCompleted && onNavigationCompleted(event); - }; - - render() { - return ( - - ); - } -} -``` - -### Traduzioni -Questo file è disponibile nelle seguenti lingue: -- [Inglese](Custom-iOS.md) -- [Portoghese brasiliano](Custom-iOS.portuguese.md) \ No newline at end of file diff --git a/docs/Custom-iOS.md b/docs/Custom-iOS.md deleted file mode 100644 index 8fbbcf9b6..000000000 --- a/docs/Custom-iOS.md +++ /dev/null @@ -1,237 +0,0 @@ -**NOTE: This document was imported from [the original WebView documentation](https://github.com/facebook/react-native-website/blob/7d3e9e120e38a7ba928f6b173eb98f88b6f2f85f/docs/custom-webview-ios.md). While it may prove useful, it has not been adapted to React Native WebView yet.** - -While the built-in web view has a lot of features, it is not possible to handle every use-case in React Native. You can, however, extend the web view with native code without forking React Native or duplicating all the existing web view code. - -Before you do this, you should be familiar with the concepts in [native UI components](native-components-ios). You should also familiarise yourself with the [native code for web views](https://github.com/react-native-webview/react-native-webview/blob/master/apple/RNCWebViewManager.m), as you will have to use this as a reference when implementing new features—although a deep understanding is not required. - -## Native Code - -Like for regular native components, you need a view manager and an web view. - -For the view, you'll need to make a subclass of `RCTWebView`. - -```objc -// RCTCustomWebView.h -#import - -@interface RCTCustomWebView : RCTWebView - -@end - -// RCTCustomWebView.m -#import "RCTCustomWebView.h" - -@interface RCTCustomWebView () - -@end - -@implementation RCTCustomWebView { } - -@end -``` - -For the view manager, you need to make a subclass `RCTWebViewManager`. You must still include: - -* `(UIView *)view` that returns your custom view -* The `RCT_EXPORT_MODULE()` tag - -```objc -// RCTCustomWebViewManager.h -#import - -@interface RCTCustomWebViewManager : RCTWebViewManager - -@end - -// RCTCustomWebViewManager.m -#import "RCTCustomWebViewManager.h" -#import "RCTCustomWebView.h" - -@interface RCTCustomWebViewManager () - -@end - -@implementation RCTCustomWebViewManager { } - -RCT_EXPORT_MODULE() - -- (UIView *)view -{ - RCTCustomWebView *webView = [RCTCustomWebView new]; - webView.delegate = self; - return webView; -} - -@end -``` - -### Adding New Events and Properties - -Adding new properties and events is the same as regular UI components. For properties, you define an `@property` in the header. For events, you define a `RCTDirectEventBlock` in the view's `@interface`. - -```objc -// RCTCustomWebView.h -@property (nonatomic, copy) NSString *finalUrl; - -// RCTCustomWebView.m -@interface RCTCustomWebView () - -@property (nonatomic, copy) RCTDirectEventBlock onNavigationCompleted; - -@end -``` - -Then expose it in the view manager's `@implementation`. - -```objc -// RCTCustomWebViewManager.m -RCT_EXPORT_VIEW_PROPERTY(onNavigationCompleted, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(finalUrl, NSString) -``` - -### Extending Existing Events - -You should refer to [RCTWebView.m](https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m) in the React Native codebase to see what handlers are available and how they are implemented. You can extend any methods here to provide extra functionality. - -By default, most methods aren't exposed from RCTWebView. If you need to expose them, you need to create an [Objective-C category](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html), and then expose all the methods you need to use. - -```objc -// RCTWebView+Custom.h -#import - -@interface RCTWebView (Custom) -- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; -- (NSMutableDictionary *)baseEvent; -@end -``` - -Once these are exposed, you can reference them in your custom web view class. - -```objc -// RCTCustomWebView.m - -// Remember to import the category file. -#import "RCTWebView+Custom.h" - -- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request - navigationType:(UIWebViewNavigationType)navigationType -{ - BOOL allowed = [super webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; - - if (allowed) { - NSString* url = request.URL.absoluteString; - if (url && [url isEqualToString:_finalUrl]) { - if (_onNavigationCompleted) { - NSMutableDictionary *event = [self baseEvent]; - _onNavigationCompleted(event); - } - } - } - - return allowed; -} -``` - -### Setting Client Certificate Authentication Credential - -If you open webpages that needs a Client Certificate for Authentication, you can create a credential and pass it to the webview: - -``` -[RNCWebView setClientAuthenticationCredential:credential]; -``` - -This can be paired with a call from Javascript to pass a string label for the certificate stored in keychain and use native calls to fetch the certificate to create a credential object. This call can be made anywhere that makes sense for your application (e.g. as part of the user authentication stack). The only requirement is to make this call before displaying any webviews. - -### Allowing custom CAs (Certificate Authorities) and enabling SSL Pinning - -If you need to connect to a server which has a self signed certificate, or want to perform SSL Pinning on the webview requests, you need to pass a dictionary with the host as the key, and the certificate as the value of each item: - - -```objc --(void)installCerts { - - // Get the bundle where the certificates in DER format are present. - NSBundle *bundle = [NSBundle mainBundle]; - - NSMutableDictionary* certMap = [NSMutableDictionary new]; - - NSData *rootCertData = [NSData dataWithContentsOfFile:[bundle pathForResource:@"example_ca" ofType:@"der"]]; - - SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (CFDataRef) rootCertData); - - OSStatus err = SecItemAdd((CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys:(id) kSecClassCertificate, kSecClass, certificate, kSecValueRef, nil], NULL); - - [certMap setObject:(__bridge id _Nonnull)(certificate) forKey:@"example.com"]; - - [RNCWebView setCustomCertificatesForHost:certMap]; -} - -``` - -Multiple hosts can be added to the dictionary, and only one certificate for a host is allowed. The verification will succeed if any of the certificates in the chain of the request matches the one defined for the request's host. - - -## JavaScript Interface - -To use your custom web view, you may want to create a class for it. Your class must return a `WebView` component with the prop `nativeConfig.component` set to your native component (see below). - -To get your native component, you must use `requireNativeComponent`: the same as for regular custom components. - -```javascript -import React, {Component} from 'react'; -import {WebView, requireNativeComponent, NativeModules} from 'react-native'; -const {CustomWebViewManager} = NativeModules; - -export default class CustomWebView extends Component { - render() { - return ( - - ); - } -} - -const RCTCustomWebView = requireNativeComponent('RCTCustomWebView'); -``` - -If you want to add custom props to your native component, you can use `nativeConfig.props` on the web view. For iOS, you should also set the `nativeConfig.viewManager` prop with your custom WebView ViewManager as in the example above. - -For events, the event handler must always be set to a function. This means it isn't safe to use the event handler directly from `this.props`, as the user might not have provided one. The standard approach is to create a event handler in your class, and then invoking the event handler given in `this.props` if it exists. - -If you are unsure how something should be implemented from the JS side, look at [WebView.ios.tsx](https://github.com/react-native-webview/react-native-webview/blob/master/src/WebView.ios.tsx) in the React Native WebView source. - -```javascript -export default class CustomWebView extends Component { - _onNavigationCompleted = (event) => { - const {onNavigationCompleted} = this.props; - onNavigationCompleted && onNavigationCompleted(event); - }; - - render() { - return ( - - ); - } -} -``` -## Translations - -This file is available at: - -- [Brazilian portuguese](Custom-iOS.portuguese.md) -- [Italian](Contributing.italian.md) \ No newline at end of file diff --git a/docs/Custom-iOS.portuguese.md b/docs/Custom-iOS.portuguese.md deleted file mode 100644 index dee138f57..000000000 --- a/docs/Custom-iOS.portuguese.md +++ /dev/null @@ -1,236 +0,0 @@ -**OBSERVAÇÃO: este documento foi importado da [documentação original do WebView](https://github.com/facebook/react-native-website/blob/7d3e9e120e38a7ba928f6b173eb98f88b6f2f85f/docs/custom-webview-ios.md). Embora possa ser útil, ainda não foi adaptado ao React Native WebView.** - -Embora a visualização da Web integrada tenha muitos recursos, não é possível lidar com todos os casos de uso no React Native. Você pode, no entanto, estender a visualização da web com código nativo sem bifurcar o React Native ou duplicar todo o código de visualização da web existente. - -Antes de fazer isso, você deve estar familiarizado com os conceitos em [componentes nativos da interface do usuário](native-components-ios). Você também deve se familiarizar com o [código nativo para visualizações da web](https://github.com/react-native-webview/react-native-webview/blob/master/apple/RNCWebViewManager.m), pois você terá para usar isso como referência ao implementar novos recursos, embora não seja necessário um entendimento profundo. - -## Código Nativo - -Como para componentes nativos regulares, você precisa de um gerenciador de visualização e uma visualização da web. - -Para a visualização, você precisará criar uma subclasse de `RCTWebView`. - -```objc -// RCTCustomWebView.h -#import - -@interface RCTCustomWebView : RCTWebView - -@end - -// RCTCustomWebView.m -#import "RCTCustomWebView.h" - -@interface RCTCustomWebView () - -@end - -@implementation RCTCustomWebView { } - -@end -``` - -Para o gerenciador de visualização, você precisa criar uma subclasse `RCTWebViewManager`. Você ainda deve incluir: - -* `(UIView *)view` retorna sua visualização personalizada -* A tag `RCT_EXPORT_MODULE()` - -```objc -// RCTCustomWebViewManager.h -#import - -@interface RCTCustomWebViewManager : RCTWebViewManager - -@end - -// RCTCustomWebViewManager.m -#import "RCTCustomWebViewManager.h" -#import "RCTCustomWebView.h" - -@interface RCTCustomWebViewManager () - -@end - -@implementation RCTCustomWebViewManager { } - -RCT_EXPORT_MODULE() - -- (UIView *)view -{ - RCTCustomWebView *webView = [RCTCustomWebView new]; - webView.delegate = self; - return webView; -} - -@end -``` - -### Adicionando novos eventos e propriedades - -Adicionar novas propriedades e eventos é o mesmo que os componentes de interface do usuário regulares. Para propriedades, você define um `@property` no cabeçalho. Para eventos, você define um `RCTDirectEventBlock` na `@interface` da visualização. - -```objc -// RCTCustomWebView.h -@property (nonatomic, copy) NSString *finalUrl; - -// RCTCustomWebView.m -@interface RCTCustomWebView () - -@property (nonatomic, copy) RCTDirectEventBlock onNavigationCompleted; - -@end -``` - -Em seguida, exponha-o no `@implementation` do gerenciador de visualização. - -```objc -// RCTCustomWebViewManager.m -RCT_EXPORT_VIEW_PROPERTY(onNavigationCompleted, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(finalUrl, NSString) -``` - -### Estendendo eventos existentes - -Você deve consultar [RCTWebView.m](https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m) na base de código React Native para ver quais manipuladores estão disponíveis e como eles são implementados. Você pode estender quaisquer métodos aqui para fornecer funcionalidade extra. - -Por padrão, a maioria dos métodos não são expostos do RCTWebView. Se você precisar expô-los, precisará criar uma [Classe em Object C](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html) e, em seguida, expor todos os métodos que você precisa usar. - -```objc -// RCTWebView+Custom.h -#import - -@interface RCTWebView (Custom) -- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; -- (NSMutableDictionary *)baseEvent; -@end -``` - -Depois que eles forem expostos, você poderá referenciá-los em sua classe de visualização da Web personalizada. - -```objc -// RCTCustomWebView.m - -// Lembre-se de importar o arquivo de categoria. -#import "RCTWebView+Custom.h" - -- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request - navigationType:(UIWebViewNavigationType)navigationType -{ - BOOL allowed = [super webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; - - if (allowed) { - NSString* url = request.URL.absoluteString; - if (url && [url isEqualToString:_finalUrl]) { - if (_onNavigationCompleted) { - NSMutableDictionary *event = [self baseEvent]; - _onNavigationCompleted(event); - } - } - } - - return allowed; -} -``` - -### Configurando o certificado e a credencial de autenticação do cliente - -Se você abrir páginas da Web que precisam de um Certificado de Cliente para Autenticação, poderá criar uma credencial e passá-la para a visualização da Web: - -``` -[RNCWebView setClientAuthenticationCredential:credential]; -``` - -Isso pode ser combinado com uma chamada do Javascript para passar um rótulo de texto para o certificado armazenado no chaveiro e usar chamadas nativas para buscar o certificado e criar um objeto de credencial. Essa chamada pode ser feita em qualquer lugar que faça sentido para seu aplicativo (por exemplo, como parte da pilha de autenticação do usuário). O único requisito é fazer essa chamada antes de exibir qualquer webview. - -### Permitir CAs personalizadas (autoridades de certificação) e habilitar a fixação de SSL - -Se você precisa se conectar a um servidor que possui um certificado autoassinado, ou deseja realizar SSL Pinning nas solicitações de webview, você precisa passar um dicionário com o host como chave e o certificado como o valor de cada item: - - -```objc --(void)installCerts { - - // Get the bundle where the certificates in DER format are present. - NSBundle *bundle = [NSBundle mainBundle]; - - NSMutableDictionary* certMap = [NSMutableDictionary new]; - - NSData *rootCertData = [NSData dataWithContentsOfFile:[bundle pathForResource:@"example_ca" ofType:@"der"]]; - - SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (CFDataRef) rootCertData); - - OSStatus err = SecItemAdd((CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys:(id) kSecClassCertificate, kSecClass, certificate, kSecValueRef, nil], NULL); - - [certMap setObject:(__bridge id _Nonnull)(certificate) forKey:@"example.com"]; - - [RNCWebView setCustomCertificatesForHost:certMap]; -} - -``` - -Vários hosts podem ser adicionados ao dicionário e apenas um certificado para um host é permitido. A verificação será bem-sucedida se algum dos certificados na cadeia da solicitação corresponder ao definido para o host da solicitação. - -## Interface JavaScript - -Para usar sua visualização da Web personalizada, você pode criar uma classe para ela. Sua classe deve retornar um componente `WebView` com o prop `nativeConfig.component` definido para seu componente nativo (veja abaixo). - -Para obter seu componente nativo, você deve usar `requireNativeComponent`: o mesmo que para componentes personalizados regulares. - -```javascript -import React, {Component} from 'react'; -import {WebView, requireNativeComponent, NativeModules} from 'react-native'; -const {CustomWebViewManager} = NativeModules; - -export default class CustomWebView extends Component { - render() { - return ( - - ); - } -} - -const RCTCustomWebView = requireNativeComponent('RCTCustomWebView'); -``` - -Se você quiser adicionar props customizadas ao seu componente nativo, você pode usar `nativeConfig.props` na visualização da web. Para iOS, você também deve definir o prop `nativeConfig.viewManager` com seu WebView ViewManager personalizado como no exemplo acima. - -Para eventos, o manipulador de eventos deve sempre ser definido para uma função. Isso significa que não é seguro usar o manipulador de eventos diretamente de `this.props`, pois o usuário pode não ter fornecido um. A abordagem padrão é criar um manipulador de eventos em sua classe e, em seguida, invocar o manipulador de eventos fornecido em `this.props` se ele existir. - -Se você não tiver certeza de como algo deve ser implementado do lado do JS, consulte [WebView.ios.tsx](https://github.com/react-native-webview/react-native-webview/blob/master/src/WebView.ios.tsx) na fonte React Native WebView. - -```javascript -export default class CustomWebView extends Component { - _onNavigationCompleted = (event) => { - const {onNavigationCompleted} = this.props; - onNavigationCompleted && onNavigationCompleted(event); - }; - - render() { - return ( - - ); - } -} -``` -## Traduções - -Esse arquivo está disponível em: - -- [Inglês](Custom-iOS.md) -- [Italiano](Custom-iOS.italian.md) \ No newline at end of file diff --git a/docs/Debugging.italian.md b/docs/Debugging.italian.md deleted file mode 100644 index 916415014..000000000 --- a/docs/Debugging.italian.md +++ /dev/null @@ -1,97 +0,0 @@ -# Guida al Debugging di React Native WebView -Ecco alcuni utili consigli per il debugging di React Native WebView. - -## Errori di Script -Può essere difficile risolvere errori di sintassi e altri errori di script in WebView, poiché gli errori di solito non vengono visualizzati in una console di default. - -Un'opzione (se stai caricando HTML da una fonte esterna) è quella di iniettare un handler degli errori prima del caricamento del contenuto. - -```js - -``` - -Questo mostrerà una finestra di avviso con (si spera) informazioni utili per il debug. - -Se stai iniettando del JavaScript, potrebbe verificarsi un errore `Script error` senza altre informazioni utili. Un modo semplice per debuggare questo problema è quello di avvolgere il JavaScript iniettato in un blocco try/catch, come mostrato di seguito: - -```js -const js = ` - try { - // Qui il tuo codice - } catch(e) { - alert(e) - } - true; -`; -``` - -Questo mostrerà un avviso (alert) con l'errore come messaggio, che potrebbe essere utile o meno. - -Se non riesci a individuare il bug con questi due semplici metodi, prova a utilizzare la prossima tecnica! - -## Debugging dei contenuti nella WebView - -### iOS & Safari - -È possibile eseguire il debug dei contenuti di WebView nel simulatore iOS o su un dispositivo utilizzando gli strumenti per gli sviluppatori di Safari. - -#### Procedura: - -1. Apri le preferenze di Safari -> sezione "Avanzate" -> abilita la voce "Mostra menu Sviluppo nella barra dei menu". -2. Avvia l'app con React Native WebView nel simulatore iOS o sul dispositivo iOS. -3. Safari -> Sviluppo -> [nome del dispositivo] -> [nome dell'app] -> [URL - titolo]. -4. Ora puoi risolvere i problemi dei contenuti di WebView come faresti normalmente su web. - -##### Note: - -Quando esegui il debug su dispositivo, devi abilitare l'ispettore web nelle impostazioni del dispositivo: - -Impostazioni -> Safari -> Avanzate -> Web Inspector - -Inoltre, se non vedi il tuo dispositivo nel menu Sviluppo e hai avviato Safari prima di avviare il simulatore, prova a riavviare Safari. - -### Android & Chrome - -È possibile eseguire il debug dei contenuti WebView nell'emulatore Android o su un dispositivo utilizzando Chrome DevTools. - -1. Dovrai apportare la seguente modifica a MainApplication.java per abilitare il debug dei contenuti Web: -```java - import android.webkit.WebView; - - @Override - public void onCreate() { - super.onCreate(); - ... - WebView.setWebContentsDebuggingEnabled(true); - } -``` -2. Avvia l'applicazione con React Native WebView nell'emulatore Android o sul dispositivo Android. -3. Apri `chrome://inspect/#devices` su Chrome (Riferimento: [Debug remoto dei dispositivi Android](https://developer.chrome.com/docs/devtools/remote-debugging/)). -4. Seleziona il tuo dispositivo sulla sinistra e seleziona "Inspect" sui contenuti WebView che desideri ispezionare. -5. Ora puoi eseguire il debug dei contenuti WebView proprio come faresti normalmente sul web. - -![image](https://user-images.githubusercontent.com/1479215/47129785-9476e480-d24b-11e8-8cb1-fba77ee1c072.png) - -##### Note: - -Quando si esegue il debug su un dispositivo, è necessario abilitare il debug USB nelle impostazioni del dispositivo: - -Impostazioni -> Sistema -> Informazioni sul telefono -> Opzioni sviluppatore -> abilita il debug USB - - -### Traduzioni -Questo file è disponibile nelle seguenti lingue: -- [Inglese](Debugging.md) -- [Portoghese brasiliano](Debugging.portuguese.md) \ No newline at end of file diff --git a/docs/Debugging.md b/docs/Debugging.md deleted file mode 100644 index 03aa55b2c..000000000 --- a/docs/Debugging.md +++ /dev/null @@ -1,91 +0,0 @@ -# React Native WebView Debugging Guide - -Here are some helpful React Native WebView debugging tips. - -## Script Errors - -It can be difficult to debug syntax errors and other script errors in WebView, since errors don't show up in a console by default. - -One option (if you're loading HTML from an external source) is to inject an error handler before the content is loaded. - -```js - -``` - -This will provide an Alert box with (hopefully) useful debugging information. - -If you're injecting JavaScript, this may fail with `Script error` and no other useful information. One simple way to debug this is to wrap your injected JavaScript in a try/catch, like so: - -```js -const js = ` - try { - // your code here - } catch(e) { - alert(e) - } - true; -`; -``` - -This will bring up an alert with the error message, which may or may not be helpful. - -If these two simple methods fail to uncover the bug, try using the next technique! - -## Debugging WebView Contents - -### iOS & Safari - -It's possible to debug WebView contents in the iOS simulator or on a device using Safari Developer Toolkit. - -#### Steps: - -1. Mark the WebView as being "inspectable" using the [`webviewDebuggingEnabled`](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md#webviewDebuggingEnabled) prop -1. Open Safari Preferences -> "Advanced" tab -> enable checkbox "Show Develop menu in menu bar" -2. Start app with React Native WebView in iOS simulator or iOS device -3. Safari -> Develop -> [device name] -> [app name] -> [url - title] -4. You can now debug the WebView contents just as you would on the web - -##### Notes: - -When debugging on device you must enable Web Inspector in your device settings: - -Settings -> Safari -> Advanced -> Web Inspector - -Also, if you don't see your device in the Develop menu, and you started Safari before you started your simulator, try restarting Safari. - -### Android & Chrome - -It's possible to debug WebView contents in the Android emulator or on a device using Chrome DevTools. - -1. You will need to set the [`webviewDebuggingEnabled`](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md#webviewDebuggingEnabled) prop on the WebView -2. Start app with React Native WebView in Android emulator or Android device -3. Open `chrome://inspect/#devices` on Chrome (Reference: [Remote debug Android devices](https://developer.chrome.com/docs/devtools/remote-debugging/)) -4. Select your device on the left and select "Inspect" on the WebView contents you'd like to inspect -5. You can now debug the WebView contents just as you would on the web - -![image](https://user-images.githubusercontent.com/1479215/47129785-9476e480-d24b-11e8-8cb1-fba77ee1c072.png) - -##### Note: - -When debugging on device you must enable USB debugging in your device settings: - -Settings -> System -> About Phone -> Developer options -> enable USB debugging - -## Translations - -This file is available in: - -- [Brazilian portuguese](Debugging.portuguese.md) -- [Italian](Debugging.italian.md) \ No newline at end of file diff --git a/docs/Debugging.portuguese.md b/docs/Debugging.portuguese.md deleted file mode 100644 index a5b84d950..000000000 --- a/docs/Debugging.portuguese.md +++ /dev/null @@ -1,102 +0,0 @@ -# Guia de depuração do React Native WebView - -Aqui estão algumas dicas úteis de depuração do React Native WebView. - -## Scripts de error - -Pode ser difícil depurar erros de sintaxe e outros erros de script no WebView, pois os erros não aparecem em um console por padrão. - -Uma opção (se você estiver carregando HTML de uma fonte externa) é injetar um manipulador de erros antes que o conteúdo seja carregado. - -```js - -``` - -Isso fornecerá uma caixa de alerta com (espero) informações úteis de depuração. - -Se você estiver injetando JavaScript, isso pode falhar com `script de erro` e nenhuma outra informação útil. Uma maneira simples de depurar isso é envolver seu JavaScript injetado em um try/catch, assim: - -```js -const js = ` - try { - // your code here - } catch(e) { - alert(e) - } - true; -`; -``` - -Isso exibirá um alerta com a mensagem de erro, que pode ou não ser útil. - -Se esses dois métodos simples falharem em descobrir o bug, tente usar a próxima técnica! - -## Depurando o conteúdo do WebView - -### iOS & Safari - -É possível depurar o conteúdo do WebView no simulador iOS ou em um dispositivo usando o Safari Developer Toolkit. - -#### Passos: - -1. Abra as Preferências do Safari -> guia "Avançado" -> marque a caixa de seleção "Mostrar menu de Desenvolvedor na barra de menus" -2. Inicie o aplicativo com o React Native WebView no simulador iOS ou dispositivo iOS -3. Safari -> Desenvolver -> [nome do dispositivo] -> [nome do app] -> [url - titulo] -4. Agora você pode depurar o conteúdo do WebView exatamente como faria na web - -##### Notas: - -Ao depurar no dispositivo, você deve habilitar o Inspetor Web nas configurações do dispositivo: - -Configurações -> Safari -> Avançado -> Inspetor Web - -Além disso, se você não vir seu dispositivo no menu Desenvolver e tiver iniciado o Safari antes de iniciar o simulador, tente reiniciar o Safari. - -### Android & Chrome - -É possível depurar o conteúdo do WebView no emulador do Android ou em um dispositivo usando o Chrome DevTools. - -1. Você precisará fazer a seguinte alteração em `MainApplication.java` para habilitar a depuração de conteúdo da web: - -```java - import android.webkit.WebView; - - @Override - public void onCreate() { - super.onCreate(); - ... - WebView.setWebContentsDebuggingEnabled(true); - } -``` - -2. Inicie o aplicativo com React Native WebView no emulador Android ou dispositivo Android -3. Abra `chrome://inspect/#devices` no Chrome (Referência: [Depuração remota de dispositivos Android](https://developer.chrome.com/docs/devtools/remote-debugging/)) -4. Selecione seu dispositivo à esquerda e selecione "Inspecionar" no conteúdo do WebView que você deseja inspecionar -5. Agora você pode depurar o conteúdo do WebView exatamente como faria na web - -![image](https://user-images.githubusercontent.com/1479215/47129785-9476e480-d24b-11e8-8cb1-fba77ee1c072.png) - -##### Observação: - -Ao depurar no dispositivo, você deve habilitar a depuração USB nas configurações do dispositivo: - -Settings -> Configurações -> Sobre telefone -> Opções de desenvolvedor -> ativar o USB depuração - -## Traduções - -Esse arquivo está disponível em: - -- [Inglês](Debugging.md) -- [Italiano](Debugging.italian.md) \ No newline at end of file diff --git a/docs/Getting-Started.italian.md b/docs/Getting-Started.italian.md deleted file mode 100644 index baaba3865..000000000 --- a/docs/Getting-Started.italian.md +++ /dev/null @@ -1,132 +0,0 @@ -# Guida introduttiva a React Native WebView -Ecco come iniziare rapidamente con React Native WebView. - -## 1. Aggiungi react-native-webview alle tue dipendenze - -``` -$ yarn add react-native-webview -``` - -(oppure) - -Per uso con npm - -``` -$ npm install --save react-native-webview -``` - -## 2. Linking dei moduli native -A partire da react-native 0.60, il collegamento (linking) delle librerie viene gestito automaticamente (autolinking). Tuttavia, è necessario eseguire `pod install` per garantire che le dipendenze siano correttamente integrate nel progetto. - -I moduli React Native che contengono codice nativo Objective-C, Swift, Java o Kotlin devono essere "linkati" affinché possano essere inclusi correttamente nell'applicazione durante la fase di compilazione. - -``` -$ react-native link react-native-webview -``` - -_NOTA: Quando disinstalli React Native WebView, esegui `react-native unlink react-native-webview` per rimuoverne il collegamento._ - -### iOS & macOS: -Se usi CocoaPods, nella directory `ios/` o `macos/` esegui: - -``` -$ pod install -``` - -Anche se è possibile eseguire il collegamento manuale seguendo il vecchio metodo tramite il tutorial di [react-native](https://reactnative.dev/docs/linking-libraries-ios), troviamo più semplice utilizzare CocoaPods. Se desideri usare CocoaPods e non lo hai ancora configurato, ti invitiamo a fare riferimento a [quest'articolo](https://engineering.brigad.co/demystifying-react-native-modules-linking-ae6c017a6b4a). - -### Android: -Android - react-native-webview **versione <6**: -Questo modulo non richiede alcun passaggio aggiuntivo dopo aver eseguito il comando di collegamento 🎉 - -Android - react-native-webview **versione >=6.X.X**: -Assicurati che AndroidX sia abilitato nel tuo progetto modificando il file `android/gradle.properties` e aggiungendo queste due righe: - -``` -android.useAndroidX=true -android.enableJetifier=true -``` - -Per l'installazione manuale su Android, ti suggeriamo di consultare [questo articolo](https://engineering.brigad.co/demystifying-react-native-modules-linking-964399ec731b) dove troverai passaggi dettagliati su come collegare qualsiasi progetto react-native. - -### Windows: -L'autolinking è supportato per React Native Windows **v0.63 e versioni successive**. Se la tua app utilizza una versione di React Native Windows che non supporta l'autolinking, effettua manualmente le seguenti aggiunte ai file indicati: - -#### **windows/myapp.sln** - -Aggiungi il progetto `ReactNativeWebView` alla tua soluzione. - -1. Apri la soluzione in Visual Studio 2019. -2. Fai clic con il pulsante destro del mouse sull'icona della soluzione nell'Esplora soluzioni > Aggiungi > Progetto esistente. - Seleziona `node_modules\react-native-webview\windows\ReactNativeWebView\ReactNativeWebView.vcxproj`. - -#### **windows/myapp/myapp.vcxproj** - -Aggiungi un riferimento a `ReactNativeWebView` al tuo progetto principale dell'applicazione. Da Visual Studio 2019: - -1. Clicca col destro sul progetto principale dell'applicazione > Aggiungi > Riferimento... - Seleziona `ReactNativeWebView` dai Progetti della soluzione. - -2. Modifica i file seguenti per aggiungere i provider del pacchetto al tuo progetto principale dell'applicazione. - -#### **pch.h** -Aggiungi `#include "winrt/ReactNativeWebView.h"`. - -#### **app.cpp** -Aggiungi `PackageProviders().Append(winrt::ReactNativeWebView::ReactPackageProvider());` prima di `InitializeComponent();`. - -Nota che se desideri abilitare lo scroll tramite touch per il componente WebView, devi disabilitare la prospettiva per la tua app tramite [ReactRootView.IsPerspectiveEnabled](https://microsoft.github.io/react-native-windows/docs/ReactRootView#isperspectiveenabled). - -## 3. Supporto per WebView2 -Il controllo WebView2 è un controllo [WinUI](https://learn.microsoft.com/it-it/windows/apps/winui/) che renderizza contenuti web utilizzando il motore di rendering di Microsoft Edge (Chromium). Abbiamo aggiunto il supporto per il controllo WebView2 al modulo della comunità react-native-webview nella versione 11.18.0. -Se la tua app utilizza RNW v0.68 o versioni successive, segui questi passaggi: - -1. Lascia che l'autolinking si occupi di aggiungere il progetto `ReactNativeWebView` alla tua app. - -2. Personalizza la versione di WinUI 2.x della tua app alla versione 2.8.0-prerelease.210927001 o successiva. Consulta [questo](https://microsoft.github.io/react-native-windows/docs/customizing-sdk-versions) per istruzioni. Il supporto WinUI 2.x per WebView2 non è ancora disponibile nelle versioni "stabile", quindi per ora dovrai utilizzare una versione prerelease. - -3. Potrebbe essere necessario specificare il pacchetto `Microsoft.Web.WebView2` nel file `packages.config` della tua app. Facendo ciò, riceverai un errore di compilazione che elenca la versione del pacchetto che devi specificare. Aggiungi semplicemente il pacchetto al tuo `packages.config` e dovresti essere pronto per continuare. - -Ora puoi accedere al controllo WebView2 di WinUI da JavaScript della tua app tramite la prop `useWebView2`. - -## 4. Importa la webview nel tuo componente -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ( - - ); - } -} -``` - -Esempio minimo usando HTML inline: - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyInlineWeb extends Component { - render() { - return ( - Ciao mondo' }} - /> - ); - } -} -``` - -Per saperne di più, dai un'occhiata al [Riferimento API](Reference.italian.md) o alla [Guida Approfondita](Guide.italian.md). - -### Traduzioni -Questo file è disponibile nelle seguenti lingue: -- [Inglese](Getting-Started.md) -- [Portoghese brasiliano](Getting-Started.portuguese.md) \ No newline at end of file diff --git a/docs/Getting-Started.md b/docs/Getting-Started.md deleted file mode 100644 index 2f3b72874..000000000 --- a/docs/Getting-Started.md +++ /dev/null @@ -1,142 +0,0 @@ -# React Native WebView Getting Started Guide - -Here's how to get started quickly with the React Native WebView. - -## 1. Add react-native-webview to your dependencies - -``` -$ yarn add react-native-webview -``` - -(or) - -For npm use - -``` -$ npm install --save react-native-webview -``` - -## 2. Link native dependencies - -From react-native 0.60 autolinking will take care of the link step but don't forget to run `pod install` - -React Native modules that include native Objective-C, Swift, Java, or Kotlin code have to be "linked" so that the compiler knows to include them in the app. - -``` -$ react-native link react-native-webview -``` - -_NOTE: If you ever need to uninstall React Native WebView, run `react-native unlink react-native-webview` to unlink it._ - -### iOS & macOS: - -If using CocoaPods, in the `ios/` or `macos/` directory run: - -``` -$ pod install -``` - -While you can manually link the old way using [react-native own tutorial](https://reactnative.dev/docs/linking-libraries-ios), we find it easier to use CocoaPods. -If you wish to use CocoaPods and haven't set it up yet, please instead refer to [that article](https://engineering.brigad.co/demystifying-react-native-modules-linking-ae6c017a6b4a). - -### Android: - -Android - react-native-webview version <6: -This module does not require any extra step after running the link command 🎉 - -Android - react-native-webview version >=6.X.X: -Please make sure AndroidX is enabled in your project by editing `android/gradle.properties` and adding 2 lines: - -``` -android.useAndroidX=true -android.enableJetifier=true -``` - -For Android manual installation, please refer to [this article](https://engineering.brigad.co/demystifying-react-native-modules-linking-964399ec731b) where you can find detailed step on how to link any react-native project. - -### Windows: - -Autolinking is supported for React Native Windows v0.63 and higher. If your app uses a React Native Windows version that does not have autolinking support, make the following additions to the given files manually: - -#### **windows/myapp.sln** - -Add the `ReactNativeWebView` project to your solution. - -1. Open the solution in Visual Studio 2019 -2. Right-click Solution icon in Solution Explorer > Add > Existing Project - Select `node_modules\react-native-webview\windows\ReactNativeWebView\ReactNativeWebView.vcxproj` - -#### **windows/myapp/myapp.vcxproj** - -Add a reference to `ReactNativeWebView` to your main application project. From Visual Studio 2019: - -1. Right-click main application project > Add > Reference... - Check `ReactNativeWebView` from Solution Projects. - -2. Modify files below to add the package providers to your main application project - -#### **pch.h** - -Add `#include "winrt/ReactNativeWebView.h"`. - -#### **app.cpp** - -Add `PackageProviders().Append(winrt::ReactNativeWebView::ReactPackageProvider());` before `InitializeComponent();`. - -Note if you want to enable scroll with Touch for the WebView component you must disable perspective for your app using [ReactRootView.IsPerspectiveEnabled](https://microsoft.github.io/react-native-windows/docs/ReactRootView#isperspectiveenabled). - -## 3. WebView2 Support -The WebView2 control is a [WinUI](https://docs.microsoft.com/windows/apps/winui/) control that renders web content using the Microsoft Edge (Chromium) rendering engine. We have added support for the WebView2 control to the react-native-webview community module in v11.18.0. -If your app is RNW v0.68 or higher, follow these steps: - - i. Let autolinking handle adding the `ReactNativeWebView` project to your app. - - ii. Customize your app's WinUI 2.x version to version 2.8.0-prerelease.210927001 or higher. See [here](https://microsoft.github.io/react-native-windows/docs/customizing-sdk-versions) for instructions. The WinUI 2.x support for WebView2 is not yet available in "stable" releases, so for now you will need to use a prerelease version. - - iii. You may need to specify the `Microsoft.Web.WebView2` package in your app's `packages.config` file. If this is needed, you will get a build error listing the version of the package that you needed to specify. Simply add the package to your `packages.config`, and you should be good to go. - -Now you can access the WinUI WebView2 control from your app's JavaScript via the `useWebView2` prop. - -## 4. Import the webview into your component - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ( - - ); - } -} -``` - -Minimal example with inline HTML: - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyInlineWeb extends Component { - render() { - return ( - Hello world' }} - /> - ); - } -} -``` - -Next, check out the [API Reference](Reference.md) or [In-Depth Guide](Guide.md). - -## Translations - -This file is available in: -- [Brazilian portuguese](Getting-Started.portuguese.md) -- [Italian](Getting-Started.italian.md) \ No newline at end of file diff --git a/docs/Getting-Started.portuguese.md b/docs/Getting-Started.portuguese.md deleted file mode 100644 index f00909315..000000000 --- a/docs/Getting-Started.portuguese.md +++ /dev/null @@ -1,131 +0,0 @@ -# Guia de introdução ao React Native WebView - -Veja como começar rapidamente com o React Native WebView. - -## 1. Adicione react-native-webview às suas dependências - -``` -$ yarn add react-native-webview -``` - -(ou) - -Para caso use o npm - -``` -$ npm install --save react-native-webview -``` - -## 2. Vincular dependências nativas - -A partir do react-native 0.60, o autolinking cuidará da etapa do link, mas não se esqueça de executar o `pod install` - -Os módulos React Native que incluem código nativo Objective-C, Swift, Java ou Kotlin precisam ser "vinculados" para que o compilador saiba incluí-los no aplicativo. - -``` -$ react-native link react-native-webview -``` - -_NOTA: Se você precisar desinstalar o React Native WebView, execute `react-native unlink react-native-webview` para desvinculá-lo._ - -### iOS & macOS: - -Se estiver usando CocoaPods, no diretório `ios/` ou `macos/` execute: - -``` -$ pod install -``` -Embora você possa vincular manualmente da maneira antiga usando [tutorial do react-native](https://reactnative.dev/docs/linking-libraries-ios), achamos mais fácil usar o CocoaPods. -Se você deseja usar o CocoaPods e ainda não o configurou, consulte [esse artigo](https://engineering.brigad.co/demystifying-react-native-modules-linking-ae6c017a6b4a). - - -### Android: - -Android - react-native-webview versão < 6: -Este módulo não requer nenhuma etapa extra após executar o comando link 🎉 - -Android - react-native-webview versão >=6.X.X: -Verifique se o AndroidX está ativado em seu projeto editando `android/gradle.properties` e adicionando 2 linhas: - -``` -android.useAndroidX=true -android.enableJetifier=true -``` -Para instalação manual no Android, consulte [este artigo](https://engineering.brigad.co/demystifying-react-native-modules-linking-964399ec731b), onde você pode encontrar as etapas detalhadas sobre como vincular qualquer projeto react-native. - -### Windows: - -A vinculação automática ainda não é compatível com ReactNativeWindows. Faça as seguintes adições aos arquivos fornecidos manualmente: - -#### **windows/myapp.sln** - -Adicione ao projeto `ReactNativeWebView` e `WebViewBridgeComponent` à sua solução. - -1. Abra a solução no Visual Studio 2019 -2. Clique com o botão direito do mouse no ícone Soluções > Gerenciador de Soluções > Adicionar > Projeto Existente - Selecione `node_modules\react-native-webview\windows\ReactNativeWebView\ReactNativeWebView.vcxproj` - Selecione `node_modules\react-native-webview\windows\WebViewBridgeComponent\WebViewBridgeComponent.vcxproj` - -#### **windows/myapp/myapp.vcxproj** - -Adicione uma referência a `ReactNativeWebView` ao seu projeto de aplicativo principal. Do Visual Studio 2019: - -1. Clique com o botão direito do mouse no projeto do aplicativo principal > Adicionar > Referências... - Verifique se `ReactNativeWebView` em soluções de Projeto. - -2. Modifique os arquivos abaixo para adicionar os provedores de pacotes ao seu projeto de aplicativo principal - -#### **pch.h** - -Adicione `#include "winrt/ReactNativeWebView.h"`. - -#### **app.cpp** - -Adicione `PackageProviders().Append(winrt::ReactNativeWebView::ReactPackageProvider());` antes de `InitializeComponent();`. - -Observe que se você deseja habilitar a rolagem com o Touch para o componente WebView, você deve desabilitar a perspectiva do seu aplicativo usando [ReactRootView.IsPerspectiveEnabled](https://microsoft.github.io/react-native-windows/docs/ReactRootView#isperspectiveenabled). - -## 3. Importe a visualização da web para seu componente - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ( - - ); - } -} -``` - -Exemplo mínimo com HTML: - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyInlineWeb extends Component { - render() { - return ( - Hello world' }} - /> - ); - } -} -``` - -Em seguida, confira o [Referência da API](Reference.portuguese.md) ou o [Guia detalhado](Guide.portuguese.md). - -## Traduções - -Esse arquivo está disponível em: - -- [Inglês](Getting-Started.md) -- [Italiano](Getting-Started.italian.md) diff --git a/docs/Guide.italian.md b/docs/Guide.italian.md deleted file mode 100644 index f4aa9d3ac..000000000 --- a/docs/Guide.italian.md +++ /dev/null @@ -1,573 +0,0 @@ -# Guida a React Native WebView - -Questo documento ti guida attraverso i casi d'uso più comuni per React Native WebView. Non copre [l'intera API](Reference.italian.md). Dopo aver letto il documento e analizzato gli esempi di codice forniti, acquisirai una solida comprensione del funzionamento del WebView e dei modelli di utilizzo più comuni. - -_Attenzione: questa guida è attualmente in fase di sviluppo._ - -## Indice della guida -- [HTML inline di base](Guide.italian.md#html-inline-di-base) -- [URL di base con Source](Guide.italian.md#url-di-base-con-source) -- [Caricamento dei file HTML locali](Guide.italian.md#caricamento-dei-file-html-locali) -- [Controllo dei cambiamenti di state della navigazione](Guide.italian.md#controllo-dei-cambiamenti-di-state-della-navigazione) -- [Aggiunta del supporto per il caricamento dei file](Guide.italian.md#aggiunta-del-supporto-per-il-caricamento-dei-file) -- [Caricamento di più file](Guide.italian.md#caricamento-di-più-file) -- [Aggiunta del supporto per il download dei file](Guide.italian.md#aggiunta-del-supporto-per-il-download-dei-file) -- [Comunicazione tra JS e Native](Guide.italian.md#comunicazione-tra-js-e-native) -- [Lavorare con header personalizzate, sessioni e cookie](Guide.italian.md#lavorare-con-header-personalizzate-sessioni-e-cookie) -- [Supporto per la navigazione gestuale e a pulsanti](Guide.italian.md#supporto-per-la-navigazione-gestuale-e-a-pulsanti) - -### HTML inline di base -Il modo più semplice per usare la WebView è passare l'HTML che si desidera renderizzare. Tieni conto che impostare una source `html` richiede che la prop [originWhiteList](Reference.italian.md#originWhiteList) sia settata su `['*']`. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyInlineWeb extends Component { - render() { - return ( - Questo è source con HTML statico!' }} - /> - ); - } -} -``` - -Passare una nuova source HTML statica causerà il rendering del WebView. - - -### URL di base con Source -Questo è l'uso più comune per una WebView. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ; - } -} -``` - -### Caricamento dei file HTML locali -N.B.: Attualmente, questo non funziona come discusso in [#428](https://github.com/react-native-webview/react-native-webview/issues/428) e [#518](https://github.com/react-native-webview/react-native-webview/issues/518). Possibili soluzioni alternative includono l'incorporazione di tutti gli asset con webpack o bundler simili, oppure con l'esecuzione di un [web server locale](https://github.com/futurepress/react-native-static-server). - -
Mostra metodo non funzionante - -A volte potresti avere incluso un file HTML insieme all'app e desideri caricare l'HTML nella WebView. Per far ciò su iOS e Windows, è sufficiente importare il file HTML come qualsiasi altro asset, come mostrato di seguito. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -const myHtmlFile = require('./my-asset-folder/local-site.html'); - -class MyWeb extends Component { - render() { - return ; - } -} -``` - -Tuttavia, su Android, è necessario mettere il file HTML all'interno della cartella degli asset del progetto Android. Ad esempio, se `local-site.html` è il tuo file HTML e desideri caricarlo nella WebView, devi spostare il file nella cartella degli asset del progetto Android, che è `nome-del-progetto/android/app/src/main/assets/`. Successivamente, puoi caricare il file HTML come mostrato nel seguente blocco di codice. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ( - - ); - } -} -``` -
- -### Controllo dei cambiamenti di state della navigazione -A volte si desidera intercettare quando l'utente preme un link nella WebView e fare qualcosa di diverso anziché navigare direttamente a quella pagina nella WebView. Ecco un esempio di codice su come potresti farlo usando la funzione `onNavigationStateChange`. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - webview = null; - - render() { - return ( - (this.webview = ref)} - source={{ uri: 'https://reactnative.dev/' }} - onNavigationStateChange={this.handleWebViewNavigationStateChange} - /> - ); - } - - handleWebViewNavigationStateChange = (newNavState) => { - // newNavState potrebbe avere una struttura simile a questa: - // { - // url?: string; - // title?: string; - // loading?: boolean; - // canGoBack?: boolean; - // canGoForward?: boolean; - // } - const { url } = newNavState; - if (!url) return; - - // Giostra determinati tipi di documenti. - if (url.includes('.pdf')) { - this.webview.stopLoading(); - // Arpi una modal con il lettore di PDF. - } - - // Gestisci l'invio di un form andato a buon fine, usando le stringhe di query. - if (url.includes('?message=success')) { - this.webview.stopLoading(); - // Poi potresti chiudere questa view. - } - - // Un modo per gestire gli errori tramite le stringhe di query. - if (url.includes('?errors=true')) { - this.webview.stopLoading(); - } - - // Reindirizzare verso un'altra destinazione. - if (url.includes('google.com')) { - const newURL = 'https://reactnative.dev/'; - const redirectTo = 'window.location = "' + newURL + '"'; - this.webview.injectJavaScript(redirectTo); - } - }; -} -``` - -### Aggiunta del supporto per il caricamento dei file -##### iOS -Per iOS, l'unica cosa che devi fare è specificare i permessi nel file `ios/[progetto]/Info.plist`: - -Scattare una foto: -``` -NSCameraUsageDescription -Fai foto per determinate attività -``` - -Selezionare dalla galleria: -``` -NSPhotoLibraryUsageDescription -Seleziona immagini per determinate attività -``` - -Registra video: -``` -NSMicrophoneUsageDescription -È necessario l'accesso al microfono per registrare i video -``` - -##### Android -Aggiungi i permessi nel file AndroidManifest.xml: - -```xml - - ...... - - - - - ...... - -``` - -###### L'opzione della fotocamera per l'upload è disponibile su Android. -Se l'input del file indica che si desiderano immagini o video tramite l'attributo [`accept`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept), la WebView cercherà di dare all'utente opzioni per usare la fotocamera per scattare una foto o registrare un video. - -Normalmente, le app che non hanno il permesso di accesso alla fotocamera possono richiedere all'utente di utilizzare un'app esterna in modo che l'app richiedente non abbia bisogno del permesso. Su Android, c'è un'eccezione speciale per l'accesso alla fotocamera al fine di evitare confusione agli utenti. Se un'app ha dichiarato il permesso di utilizzare la fotocamera, ma l'utente non ha ancora concesso tale permesso, l'app potrebbe non avviare un'azione che richiede l'uso della fotocamera, come la cattura di immagini (`MediaStore.ACTION_IMAGE_CAPTURE`) o la registrazione di video (`MediaStore.ACTION_VIDEO_CAPTURE`). In questo caso, è responsabilità dello sviluppatore richiedere esplicitamente il permesso di accesso alla fotocamera prima di effettuare un caricamento diretto di file utilizzando la fotocamera. - -##### Verifica la compatibilità del caricamento dei file utilizzando il metodo `static isFileUploadSupported()`. - -Il caricamento dei file tramite l'elemento `` non è supportato su Android 4.4 KitKat (vedi [dettagli](https://github.com/delight-im/Android-AdvancedWebView/issues/4#issuecomment-70372146)): - -```jsx -import { WebView } from "react-native-webview"; - -WebView.isFileUploadSupported().then(res => { - if (res === true) { - // Il caricamento del file è supportato - } else { - // Il caricamento del file non è supportato - } -}); -``` - -##### MacOS -Aggiungi l'accesso in lettura per il `User Selected File` nella scheda `Signing & Capabilities` sotto `App Sandbox`: - -Screenshot della sezione Signing & Capabilities in XCode - -Nota: Tentare di aprire un elemento di input file senza questo permesso farà crashare la webview. - -### Caricamento di più file -Puoi controllare la selezione di singoli o molteplici file specificando l'attributo [`multiple`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#multiple) sul tuo elemento `input`: - -```jsx -// Selezione di più file - - -// Selezione di un singolo file - -``` - -### Aggiunta del supporto per il download dei file -##### iOS -Su iOS, dovrai fornire il tuo codice per il download dei file. Puoi passare una callback `onFileDownload` al componente WebView come prop. Se RNCWebView determina che è necessario effettuare un download del file, l'URL da cui è possibile scaricare il file verrà passato a `onFileDownload`. Puoi quindi usare questa callback per scaricare il file nel modo desiderato. - -NOTA: È necessario iOS 13 o versione successiva per aver la miglior esperienza di download. Con iOS 13, Apple ha aggiunto un'API per accedere agli header di risposta HTTP, che viene utilizzata per determinare se una risposta HTTP dev'essere scaricata. Su iOS 12 o versioni precedenti, solo i tipi MIME che non possono essere visualizzati nel WebView triggeranno chiamate a `onFileDownload`. - -Esempio: -```javascript -onFileDownload = ({ nativeEvent }) => { - const { downloadUrl } = nativeEvent; - // --> Il codice per il download va qui <-- -}; -``` - -Per poter salvare le immagini nella galleria, è necessario specificare questo permesso nel file `ios/[progetto]/Info.plist`: -``` -NSPhotoLibraryAddUsageDescription -Ci serve il permesso per salvare le immagini per determinate attività. -``` - -##### Android -Sul sistema Android, l'integrazione con il DownloadManager è integrata di default. -Aggiungi questa autorizzazione nel file AndroidManifest.xml (necessaria solo se la tua app supporta versioni di Android precedenti alla 10): - -```xml - - ...... - - - - - ...... - -``` - -### Comunicazione tra JS e Native -Spesso ti troverai nella situazione di voler fare del passaggio dati inviando messaggi alle pagine web caricate tramite le tue webview e ricevendo messaggi da esse. - -Per realizzare ciò, React Native WebView offre tre diverse opzioni: -1. React Native -> Web: La prop `injectedJavaScript` -2. React Native -> Web: Il metodo `injectJavaScript` -3. Web -> React Native: Il metodo `postMessage` e la prop `onMessage` - -#### La prop `injectedJavaScript` -Questo è uno script che viene eseguito immediatamente dopo il caricamento iniziale della pagina web. Viene eseguito una sola volta, anche se la pagina viene ricaricata o abbandonata. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - // Crea il blocco di JS da passare nella WebView. Pensa al contenuto di questo template string - // come se fosse un file JS caricato nella pagina web finale. - const runFirst = ` - document.body.style.backgroundColor = 'red'; - setTimeout(function() { window.alert('hi') }, 2000); - true; // Nota: Questo è necessario, altrimenti potrebbero verificarsi errori silenziosi. - `; - return ( - - {}} - injectedJavaScript={runFirst} - /> - - ); - } -} -``` - -Questo esegue il codice JavaScript nella stringa `runFirst` una volta che la pagina è stata caricata. In questo caso, è possibile vedere che lo stile del body è stato modificato in rosso e l'avviso è comparso dopo 2 secondi. È anche necessario avere un evento `onMessage` per iniettare il codice JavaScript nel WebView, in questo caso abbiamo passato un oggetto vuoto. - -Impostando `injectedJavaScriptForMainFrameOnly: false`, l'iniezione del JavaScript avverrà su tutti i frame (non solo il frame principale) se supportato dalla piattaforma specifica. Ad esempio, se una pagina contiene un iframe, il JavaScript verrà iniettato anche nell'iframe se questa opzione è impostata su `false`. (Nota: ciò non è supportato su Android.) È disponibile anche `injectedJavaScriptBeforeContentLoadedForMainFrameOnly` per l'iniezione prima del caricamento del contenuto. Per ulteriori informazioni, leggi nella [Referenza delle API](./Reference.italian.md#injectedjavascriptformainframeonly). - - -Screenshot del repo su Github - -_Roba da smanettoni_ -> Su iOS, ~~`injectedJavaScript` esegue un metodo su WebView chiamato `evaluateJavaScript:completionHandler:`~~ - questa affermazione non è più valida a partire dalla versione `8.2.0`. Invece, utilizziamo un `WKUserScript` con un tempo di iniezione `WKUserScriptInjectionTimeAtDocumentEnd`. Di conseguenza, `injectedJavaScript` non restituisce più un valore di valutazione né genera un avviso nella console. Nel caso improbabile in cui la tua app dipenda da questo comportamento, consulta i passaggi di migrazione [qui](https://github.com/react-native-webview/react-native-webview/pull/1119#issuecomment-574919464) per mantenere un comportamento equivalente. -> Su Android, `injectedJavaScript` esegue un metodo sulla WebView di Android chiamato `evaluateJavascriptWithFallback`. -> Su Windows, `injectedJavaScript` esegue un metodo sulla WebView WinRT/C++ chiamato `InvokeScriptAsync`. - -#### La prop `injectedJavaScriptBeforeContentLoaded` -Questo è uno script che viene eseguito **prima** del caricamento della pagina web per la prima volta. Viene eseguito solo una volta, anche se la pagina viene ricaricata o navigata altrove. Questo è utile se desideri iniettare qualcosa nella finestra, nel localStorage o nel documento prima dell'esecuzione del codice web. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const runFirst = ` - window.isNativeApp = true; - true; // Nota: Questo è necessario, altrimenti potrebbero verificarsi errori silenziosi. - `; - return ( - - - - ); - } -} -``` - -Questo esegue il JavaScript nella stringa `runFirst` prima del caricamento della pagina. In questo caso, il valore di `window.isNativeApp` verrà impostato su `true` prima dell'esecuzione del codice web. - -> **Attenzione** -> Su Android, questo funziona, ma non è del tutto affidabile al 100% (vedi [#1609](https://github.com/react-native-webview/react-native-webview/issues/1609) e [#1099](https://github.com/react-native-webview/react-native-webview/pull/1099)). - -Impostando `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false`, l'iniezione di JavaScript avverrà su tutti i frame (non solo il frame principale) se supportato dalla piattaforma specifica. Tuttavia, sebbene il supporto per `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false` sia stato implementato per iOS e macOS, non è chiaro che sia effettivamente possibile iniettare JS negli iframe in questo punto del ciclo di vita della pagina, quindi non è consigliato far affidamento sul comportamento atteso di questa prop quando è impostata su `false`. - -> Su iOS, ~~`injectedJavaScriptBeforeContentLoaded` esegue un metodo su WebView chiamato `evaluateJavaScript:completionHandler:`~~ - questo non è più vero a partire dalla versione `8.2.0`. Invece, utilizziamo un `WKUserScript` con il tempo di iniezione `WKUserScriptInjectionTimeAtDocumentStart`. Di conseguenza, `injectedJavaScriptBeforeContentLoaded` non restituisce più un valore di valutazione né registra un avviso nella console. Nel caso improbabile che la tua app dipenda da questo comportamento, consulta i passaggi di migrazione [qui](https://github.com/react-native-webview/react-native-webview/pull/1119#issuecomment-574919464) per mantenere un comportamento equivalente. -> Su Android, `injectedJavaScript` esegue un metodo sul WebView di Android chiamato `evaluateJavascriptWithFallback`. -> Nota sulla compatibilità di Android: per le applicazioni che mirano a `Build.VERSION_CODES.N` o versioni successive, lo state JavaScript da una WebView vuota non viene più mantenuto tra le navigazioni come `loadUrl(java.lang.String)`. Ad esempio, le variabili globali e le funzioni definite prima di chiamare `loadUrl(java.lang.String)` non esisteranno nella pagina caricata. Le applicazioni devono utilizzare l'API nativa di Android `addJavascriptInterface(Object, String)` per mantenere gli oggetti JavaScript tra le navigazioni. - -#### Il metodo `injectJavaScript` -Sebbene comodo, il lato negativo della prop `injectedJavaScript` precedentemente menzionata è che viene eseguita solo una volta. Ecco perché mettiamo a disposizione anche un metodo sull'oggetto di riferimento della WebView chiamato `injectJavaScript` (nota il nome leggermente diverso!). - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const run = ` - document.body.style.backgroundColor = 'blue'; - true; - `; - - setTimeout(() => { - this.webref.injectJavaScript(run); - }, 3000); - - return ( - - (this.webref = r)} - source={{ - uri: 'https://github.com/react-native-webview/react-native-webview', - }} - /> - - ); - } -} -``` - -Dopo 3 secondi, questo codice cambia il colore di sfondo in blu: - -Screenshot dell'app che mostra il codice JavaScript iniettato - -_Roba da smanettoni_ -> Su iOS, `injectJavaScript` chiama il metodo `evaluateJS:andThen:` della WebView -> Su Android, `injectJavaScript` chiama il metodo `evaluateJavascriptWithFallback` della WebView di Android - -#### Il metodo `window.ReactNativeWebView.postMessage` e la prop `onMessage` -Poter inviare JavaScript alla pagina web è fantastico, ma cosa succede quando la pagina web vuole comunicare con il tuo codice React Native? È qui che entrano in gioco `window.ReactNativeWebView.postMessage` e la prop `onMessage`. - -È **necessario** impostare `onMessage`, altrimenti il metodo `window.ReactNativeWebView.postMessage` non verrà iniettato nella pagina web. - -`window.ReactNativeWebView.postMessage` accetta solo un argomento che deve essere una stringa. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const html = ` - - - - - - - `; - - return ( - - { - alert(event.nativeEvent.data); - }} - /> - - ); - } -} -``` - -Questo codice genererà un avviso come dimostrato: -Avviso che mostra la comunicazione dalla pagina web a React Native - - -### Lavorare con header personalizzate, sessioni e cookie -#### Impostazione degli header personalizzati -In React Native WebView, è possibile impostare un header personalizzato nel seguente modo: - -```jsx - -``` - -Ciò imposterà l'header durante il primo caricamento, ma non durante le successive navigazioni di pagina. - -Per risolvere questo problema, è possibile tenere traccia dell'URL corrente, intercettare i nuovi caricamenti delle pagine e navigare verso di essi manualmente ([il merito di questa tecnica va dato a Chirag Shah di Big Binary](https://www.bigbinary.com/blog/passing-request-headers-on-each-webview-request-in-react-native)): - -```jsx -const CustomHeaderWebView = (props) => { - const { uri, onLoadStart, ...restProps } = props; - const [currentURI, setURI] = useState(props.source.uri); - const newSource = { ...props.source, uri: currentURI }; - - return ( - { - // Se stiamo caricando l'URI corrente, consentiamo il caricamento - if (request.url === currentURI) return true; - // Stiamo caricando un nuovo URL: cambiamo prima lo stato. - setURI(request.url); - return false; - }} - /> - ); -}; - -; -``` - -#### Gestione dei cookie -Puoi impostare i cookie dal lato React Native utilizzando il pacchetto [@react-native-community/cookies](https://github.com/react-native-community/cookies). - -Quando lo fai, dovrai abilitare anche la prop [sharedCookiesEnabled](Reference.italian.md#sharedCookiesEnabled). - -```jsx -const App = () => { - return ( - - ); -}; -``` - -Se desideri inviare cookie personalizzati direttamente nella WebView, puoi farlo utilizzando un'intestazione personalizzata, come segue: - -```jsx -const App = () => { - return ( - - ); -}; -``` - -Tieni presente che questi cookie verranno inviati solo nella prima richiesta a meno che tu non utilizzi la tecnica descritta sopra per impostare gli [header personalizzati](#impostazione-degli-header-personalizzati) ad ogni caricamento della pagina. - -### Supporto per la navigazione gestuale e a pulsanti -Possiamo fornire supporto per la navigazione convenzionale delle pagine mobili: gesti di scorrimento avanti/indietro su iOS e il pulsante indietro/gesto hardware su Android. - -Per iOS, è sufficiente utilizzare la proprietà [`allowsBackForwardNavigationGestures`](Reference.italian.md#allowsbackforwardnavigationgestures). - -Per Android, è necessario utilizzare [`BackHandler.addEventListener`](https://reactnative.dev/docs/backhandler) e collegarlo per chiamare `goBack` sul `WebView`. - -Con i componenti funzionali di React, è possibile utilizzare `useRef` e `useEffect` (dovrai importarli da React se non lo hai già fatto) per consentire agli utenti di navigare alla pagina precedente quando il pulsante "indietro" viene premuto, come segue: - -```jsx -import React, { useEffect, useRef, } from 'react'; -import { BackHandler, Platform, } from 'react-native'; -``` - -```jsx -const webViewRef = useRef(null); -const onAndroidBackPress = () => { - if (webViewRef.current) { - webViewRef.current.goBack(); - return true; // previeni il comportamento predefinito (uscita dall'app) - } - return false; -}; - -useEffect(() => { - if (Platform.OS === 'android') { - BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress); - return () => { - BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress); - }; - } -}, []); -``` - -E aggiungi questa proprietà `ref` al tuo componente `WebView`: - -```jsx - -``` - -Vi sono alcune incongruenze nel modo in cui il tasto hardware del silenzioso viene gestito tra gli elementi audio e video incorporati e tra le piattaforme iOS e Android. - -Su iOS, l'audio verrà disattivato quando il silenzioso è nella posizione attiva, a meno che il parametro `ignoreSilentHardwareSwitch` non sia impostato su true. - -Sempre su iOS, invece, il video ignorerà sempre il tasto del silenzioso. - - -### Traduzioni -Questo file è disponibile nelle seguenti lingue: -- [Inglese](Guide.md) -- [Portoghese brasiliano](Guide.portuguese.md) \ No newline at end of file diff --git a/docs/Guide.md b/docs/Guide.md deleted file mode 100644 index 1ddd2cad0..000000000 --- a/docs/Guide.md +++ /dev/null @@ -1,614 +0,0 @@ -# React Native WebView Guide - -This document walks you through the most common use cases for React Native WebView. It doesn't cover [the full API](Reference.md), but after reading it and looking at the sample code snippets you should have a good sense for how the WebView works and common patterns for using the WebView. - -_This guide is currently a work in progress._ - -## Guide Index - -- [Basic Inline HTML](Guide.md#basic-inline-html) -- [Basic URL Source](Guide.md#basic-url-source) -- [Loading local HTML files](Guide.md#loading-local-html-files) -- [Controlling navigation state changes](Guide.md#controlling-navigation-state-changes) -- [Add support for File Upload](Guide.md#add-support-for-file-upload) -- [Multiple files upload](Guide.md#multiple-files-upload) -- [Add support for File Download](Guide.md#add-support-for-file-download) -- [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) -- [Working with custom headers, sessions, and cookies](Guide.md#working-with-custom-headers-sessions-and-cookies) -- [Page navigation gesture and button support](Guide.md#page-navigation-gesture-and-button-support) - -### Basic inline HTML - -The simplest way to use the WebView is to simply pipe in the HTML you want to display. Note that setting an `html` source requires the [originWhiteList](Reference.md#originWhiteList) property to be set to `['*']`. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyInlineWeb extends Component { - render() { - return ( - This is a static HTML source!' }} - /> - ); - } -} -``` - -Passing a new static html source will cause the WebView to rerender. - -### Basic URL Source - -This is the most common use-case for WebView. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ; - } -} -``` - -### Loading local HTML files - -Note: This is currently not working as discussed in [#428](https://github.com/react-native-webview/react-native-webview/issues/428) and [#518](https://github.com/react-native-webview/react-native-webview/issues/518). Possible workarounds include bundling all assets with webpack or similar, or running a [local webserver](https://github.com/birdofpreyru/react-native-static-server). - -
Show non-working method - -Sometimes you would have bundled an HTML file along with the app and would like to load the HTML asset into your WebView. To do this on iOS and Windows, you can just import the html file like any other asset as shown below. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -const myHtmlFile = require('./my-asset-folder/local-site.html'); - -class MyWeb extends Component { - render() { - return ; - } -} -``` - -However on Android, you need to place the HTML file inside your android project's asset directory. For example, if `local-site.html` is your HTML file and you'd like to load it into the webview, you should move the file to your project's android asset directory which is `your-project/android/app/src/main/assets/`. Then you can load the html file as shown in the following code block - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ( - - ); - } -} -``` - -
- -### Controlling navigation state changes - -Sometimes you want to intercept a user tapping on a link in your webview and do something different than navigating there in the webview. Here's some example code on how you might do that using the `onNavigationStateChange` function. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - webview = null; - - render() { - return ( - (this.webview = ref)} - source={{ uri: 'https://reactnative.dev/' }} - onNavigationStateChange={this.handleWebViewNavigationStateChange} - /> - ); - } - - handleWebViewNavigationStateChange = (newNavState) => { - // newNavState looks something like this: - // { - // url?: string; - // title?: string; - // loading?: boolean; - // canGoBack?: boolean; - // canGoForward?: boolean; - // } - const { url } = newNavState; - if (!url) return; - - // handle certain doctypes - if (url.includes('.pdf')) { - this.webview.stopLoading(); - // open a modal with the PDF viewer - } - - // one way to handle a successful form submit is via query strings - if (url.includes('?message=success')) { - this.webview.stopLoading(); - // maybe close this view? - } - - // one way to handle errors is via query string - if (url.includes('?errors=true')) { - this.webview.stopLoading(); - } - - // redirect somewhere else - if (url.includes('google.com')) { - const newURL = 'https://reactnative.dev/'; - const redirectTo = 'window.location = "' + newURL + '"'; - this.webview.injectJavaScript(redirectTo); - } - }; -} -``` - -### Add support for File Upload - -##### iOS - -For iOS, all you need to do is specify the permissions in your `ios/[project]/Info.plist` file: - -Photo capture: - -``` -NSCameraUsageDescription -Take pictures for certain activities -``` - -Gallery selection: - -``` -NSPhotoLibraryUsageDescription -Select pictures for certain activities -``` - -Video recording: - -``` -NSMicrophoneUsageDescription -Need microphone access for recording videos -``` - -##### Android - -Add permission in AndroidManifest.xml: - -```xml - - ...... - - - - - ...... - -``` - -###### Camera option availability in uploading for Android - -If the file input indicates that images or video is desired with [`accept`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept), then the WebView will attempt to provide options to the user to use their camera to take a picture or video. - -Normally, apps that do not have permission to use the camera can prompt the user to use an external app so that the requesting app has no need for permission. However, Android has made a special exception for this around the camera to reduce confusion for users. If an app _can_ request the camera permission because it has been declared, and the user has not granted the permission, it may not fire an intent that would use the camera (`MediaStore.ACTION_IMAGE_CAPTURE` or `MediaStore.ACTION_VIDEO_CAPTURE`). In this scenario, it is up to the developer to request camera permission before a file upload directly using the camera is necessary. - -##### Check for File Upload support, with `static isFileUploadSupported()` - -File Upload using `` is not supported for Android 4.4 KitKat (see [details](https://github.com/delight-im/Android-AdvancedWebView/issues/4#issuecomment-70372146)): - -```jsx -import { WebView } from "react-native-webview"; - -WebView.isFileUploadSupported().then(res => { - if (res === true) { - // file upload is supported - } else { - // not file upload support - } -}); - -``` - -##### MacOS - -Add read access for `User Selected File` in `Signing & Capabilities` tab under `App Sandbox`: - -settings screenshot - -Note: Attempting to open a file input without this permission will crash the webview. - -### Multiple Files Upload - -You can control **single** or **multiple** file selection by specifing the [`multiple`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#multiple) attribute on your `input` element: - -``` -// multiple file selection - - -// single file selection - -``` - -### Add support for File Download - -##### iOS - -On iOS, you are going to have to supply your own code to download files. You can supply an `onFileDownload` callback -to the WebView component as a prop. If RNCWebView determines that a file download needs to take place, the URL where you can download the file -will be given to `onFileDownload`. From that callback you can then download that file however you would like to do so. - -NOTE: iOS 13+ is needed for the best possible download experience. On iOS 13 Apple added an API for accessing HTTP response headers, which -is used to determine if an HTTP response should be a download. On iOS 12 or older, only MIME types that cannot be rendered by the webview will -trigger calls to `onFileDownload`. - -Example: - -```javascript -onFileDownload = ({ nativeEvent }) => { - const { downloadUrl } = nativeEvent; - // --> Your download code goes here <-- -}; -``` - -To be able to save images to the gallery you need to specify this permission in your `ios/[project]/Info.plist` file: - -``` -NSPhotoLibraryAddUsageDescription -Save pictures for certain activities. -``` - -##### Android - -On Android, integration with the DownloadManager is built-in. -Add this permission in AndroidManifest.xml (only required if your app supports Android versions lower than 10): - -```xml - - ...... - - - - - ...... - -``` - -### Communicating between JS and Native - -You will often find yourself wanting to send messages to the web pages loaded by your webviews and also receiving messages back from those web pages. - -To accomplish this, React Native WebView exposes three different options: - -1. React Native -> Web: The `injectedJavaScript` prop -2. React Native -> Web: The `injectJavaScript` method -3. Web -> React Native: The `postMessage` method and `onMessage` prop - -#### The `injectedJavaScript` prop - -This is a script that runs immediately after the web page loads for the first time. It only runs once, even if the page is reloaded or navigated away. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const runFirst = ` - document.body.style.backgroundColor = 'red'; - setTimeout(function() { window.alert('hi') }, 2000); - true; // note: this is required, or you'll sometimes get silent failures - `; - return ( - - {}} - injectedJavaScript={runFirst} - /> - - ); - } -} -``` - -This runs the JavaScript in the `runFirst` string once the page is loaded. In this case, you can see that both the body style was changed to red and the alert showed up after 2 seconds. An `onMessage` event is required as well to inject the JavaScript code into the WebView. - -By setting `injectedJavaScriptForMainFrameOnly: false`, the JavaScript injection will occur on all frames (not just the main frame) if supported for the given platform. For example, if a page contains an iframe, the javascript will be injected into that iframe as well with this set to `false`. (Note this is not supported on Android.) There is also `injectedJavaScriptBeforeContentLoadedForMainFrameOnly` for injecting prior to content loading. Read more about this in the [Reference](./Reference.md#injectedjavascriptformainframeonly). - -screenshot of Github repo - -_Under the hood_ - -> On iOS, ~~`injectedJavaScript` runs a method on WebView called `evaluateJavaScript:completionHandler:`~~ – this is no longer true as of version `8.2.0`. Instead, we use a `WKUserScript` with injection time `WKUserScriptInjectionTimeAtDocumentEnd`. As a consequence, `injectedJavaScript` no longer returns an evaluation value nor logs a warning to the console. In the unlikely event that your app depended upon this behaviour, please see migration steps [here](https://github.com/react-native-webview/react-native-webview/pull/1119#issuecomment-574919464) to retain equivalent behaviour. -> On Android, `injectedJavaScript` runs a method on the Android WebView called `evaluateJavascriptWithFallback` -> On Windows, `injectedJavaScript` runs a method on the WinRT/C++ WebView called `InvokeScriptAsync` - -#### The `injectedJavaScriptBeforeContentLoaded` prop - -This is a script that runs **before** the web page loads for the first time. It only runs once, even if the page is reloaded or navigated away. This is useful if you want to inject anything into the window, localstorage, or document prior to the web code executing. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const runFirst = ` - window.isNativeApp = true; - true; // note: this is required, or you'll sometimes get silent failures - `; - return ( - - - - ); - } -} -``` - -This runs the JavaScript in the `runFirst` string before the page is loaded. In this case, the value of `window.isNativeApp` will be set to true before the web code executes. - -> **Warning** -> On Android, this may work, but it is not 100% reliable (see [#1609](https://github.com/react-native-webview/react-native-webview/issues/1609) and [#1099](https://github.com/react-native-webview/react-native-webview/pull/1099)). - -By setting `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false`, the JavaScript injection will occur on all frames (not just the top frame) if supported for the given platform. However, although support for `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false` has been implemented for iOS and macOS, [it is not clear](https://github.com/react-native-webview/react-native-webview/pull/1119#issuecomment-600275750) that it is actually possible to inject JS into iframes at this point in the page lifecycle, and so relying on the expected behaviour of this prop when set to `false` is not recommended. - -> On iOS, ~~`injectedJavaScriptBeforeContentLoaded` runs a method on WebView called `evaluateJavaScript:completionHandler:`~~ – this is no longer true as of version `8.2.0`. Instead, we use a `WKUserScript` with injection time `WKUserScriptInjectionTimeAtDocumentStart`. As a consequence, `injectedJavaScriptBeforeContentLoaded` no longer returns an evaluation value nor logs a warning to the console. In the unlikely event that your app depended upon this behaviour, please see migration steps [here](https://github.com/react-native-webview/react-native-webview/pull/1119#issuecomment-574919464) to retain equivalent behaviour. -> On Android, `injectedJavaScript` runs a method on the Android WebView called `evaluateJavascriptWithFallback` -> Note on Android Compatibility: For applications targeting `Build.VERSION_CODES.N` or later, JavaScript state from an empty WebView is no longer persisted across navigations like `loadUrl(java.lang.String)`. For example, global variables and functions defined before calling `loadUrl(java.lang.String)` will not exist in the loaded page. Applications should use the Android Native API `addJavascriptInterface(Object, String)` instead to persist JavaScript objects across navigations. - -#### The `injectJavaScript` method - -While convenient, the downside to the previously mentioned `injectedJavaScript` prop is that it only runs once. That's why we also expose a method on the webview ref called `injectJavaScript` (note the slightly different name!). - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const run = ` - document.body.style.backgroundColor = 'blue'; - true; - `; - - setTimeout(() => { - this.webref.injectJavaScript(run); - }, 3000); - - return ( - - (this.webref = r)} - source={{ - uri: 'https://github.com/react-native-webview/react-native-webview', - }} - /> - - ); - } -} -``` - -After 3 seconds, this code turns the background blue: - -Screenshot of app showing injected javascript - -_Under the hood_ - -> On iOS, `injectJavaScript` calls WebView's `evaluateJS:andThen:` -> On Android, `injectJavaScript` calls Android WebView's `evaluateJavascriptWithFallback` method - -#### The `window.ReactNativeWebView.postMessage` method and `onMessage` prop - -Being able to send JavaScript to the web page is great, but what about when the web page wants to communicate back to your React Native code? This is where `window.ReactNativeWebView.postMessage` and the `onMessage` prop come in. - -You _must_ set `onMessage` or the `window.ReactNativeWebView.postMessage` method will not be injected into the web page. - -`window.ReactNativeWebView.postMessage` only accepts one argument which must be a string. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const html = ` - - - - - - - `; - - return ( - - { - alert(event.nativeEvent.data); - }} - /> - - ); - } -} -``` - -This code will result in this alert: - -Alert showing communication from web page to React Native - -### Working with custom headers, sessions, and cookies - -#### Setting Custom Headers - -In React Native WebView, you can set a custom header like this: - -```jsx - -``` - -This will set the header on the first load, but not on subsequent page navigations. - -In order to work around this, you can track the current URL, intercept new page loads, and navigate to them yourself ([original credit for this technique to Chirag Shah from Big Binary](https://www.bigbinary.com/blog/passing-request-headers-on-each-webview-request-in-react-native)): - -```jsx -const CustomHeaderWebView = (props) => { - const { uri, onLoadStart, ...restProps } = props; - const [currentURI, setURI] = useState(props.source.uri); - const newSource = { ...props.source, uri: currentURI }; - - return ( - { - // If we're loading the current URI, allow it to load - if (request.url === currentURI) return true; - // We're loading a new URL -- change state first - setURI(request.url); - return false; - }} - /> - ); -}; - -; -``` - -#### Managing Cookies - -You can set cookies on the React Native side using the [@react-native-community/cookies](https://github.com/react-native-community/cookies) package. - -When you do, you'll likely want to enable the [sharedCookiesEnabled](Reference.md#sharedCookiesEnabled) prop as well. - -```jsx -const App = () => { - return ( - - ); -}; -``` - -If you'd like to send custom cookies in the WebView itself, you can do so in a custom header, like this: - -```jsx -const App = () => { - return ( - - ); -}; -``` - -Note that these cookies will only be sent on the first request unless you use the technique above for [setting custom headers on each page load](#Setting-Custom-Headers). - -### Page navigation gesture and button support -We can provide support for conventional mobile page navigation: forward/back swipe gestures on iOS and the hardware back button/gesture on Android. - -For iOS, you'll just need to use the [`allowsbackforwardnavigationgestures`](Reference.md#allowsbackforwardnavigationgestures) prop. - -For Android, you need to use `BackHandler.addEventListener` and hook that up to call `goBack` on the `WebView`. - -With functional React components, you can use `useRef` and `useEffect` (you'll need to import them from React if you aren't already) to allow users to navigate to the previous page when they press the back button like so: -```jsx -import React, { - useEffect, - useRef, -} from 'react'; -import { - BackHandler, - Platform, -} from 'react-native'; -``` - -```jsx -const webViewRef = useRef(null); -const onAndroidBackPress = () => { - if (webViewRef.current) { - webViewRef.current.goBack(); - return true; // prevent default behavior (exit app) - } - return false; -}; - -useEffect(() => { - if (Platform.OS === 'android') { - BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress); - return () => { - BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress); - }; - } -}, []); -``` - -And add this prop to your `WebView` component: -```jsx - -``` - -### Hardware Silence Switch - -There are some inconsistencies in how the hardware silence switch is handled between embedded `audio` and `video` elements and between iOS and Android platforms. - -Audio on `iOS` will be muted when the hardware silence switch is in the on position, unless the `ignoreSilentHardwareSwitch` parameter is set to true. - -Video on `iOS` will always ignore the hardware silence switch. - -## Translations - -This file is available in: - -- [Brazilian portuguese](Guide.portuguese.md) -- [Italian](Guide.italian.md) diff --git a/docs/Guide.portuguese.md b/docs/Guide.portuguese.md deleted file mode 100644 index 453315329..000000000 --- a/docs/Guide.portuguese.md +++ /dev/null @@ -1,553 +0,0 @@ -# Guia React Native WebView - -Este documento orienta você pelos casos de uso mais comuns do React Native WebView. Ele não cobre [a API completa](Reference.portuguese.md), mas depois de lê-lo e ver os trechos de código de exemplo, você deve ter uma boa noção de como o WebView funciona e os padrões comuns para usar o WebView. - -_Este guia atualmente é um trabalho em andamento._ - -## Index - -- [HTML Básico](Guide.portuguese.md#html-básico) -- [Url](Guide.portuguese.md#url) -- [Carregando de arquivos HTML locais](Guide.portuguese.md#carregando-de-arquivos-html-locais) -- [Controlando as alterações do estado de navegação](Guide.portuguese.md#controlando-as-alterações-do-estado-de-navegação) -- [Adicionar suporte para upload de arquivos](Guide.portuguese.md#adicionar-suporte-para-upload-de-arquivos) -- [Upload de vários arquivos](Guide.portuguese.md#upload-de-vários-arquivos) -- [Adicionar suporte para download de arquivos](Guide.portuguese.md#adicionar-suporte-para-download-de-arquivos) -- [Comunicação entre JS e Native](Guide.portuguese.md#comunicação-entre-js-e-native) -- [Trabalhando com cabeçalhos, sessões e cookies personalizados](Guide.portuguese.md#trabalhando-com-cabeçalhos-sessões-e-cookies-personalizados) - -### HTML Básico - -A maneira mais simples de usar a WebView é simplesmente canalizar o HTML que você deseja exibir. Observe que definir uma fonte `html` requer que a propriedade [originWhiteList](Reference.portuguese.md#originWhiteList) seja definida como `['*']`. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyInlineWeb extends Component { - render() { - return ( - Esta é uma fonte HTML estática!' }} - /> - ); - } -} -``` - -Passar uma nova fonte html estática fará com que o WebView seja renderizado novamente. - -### Url - -Este é o caso de uso mais comum para WebView. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ; - } -} -``` - -### Carregando arquivos HTML locais - -Observação: no momento, isso não está funcionando conforme discutido em [#428](https://github.com/react-native-webview/react-native-webview/issues/428) e [#518](https://github.com/react-native-webview/react-native-webview/issues/518). As possíveis soluções incluem agrupar todos os ativos com webpack ou similar, ou executar um [servidor da web local](https://github.com/futurepress/react-native-static-server). - -
Mostrar método que não funciona - -Às vezes, você teria agrupado um arquivo HTML junto com o aplicativo e gostaria de carregar o ativo HTML em seu WebView. Para fazer isso no iOS e no Windows, basta importar o arquivo html como qualquer outro ativo, conforme mostrado abaixo. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -const myHtmlFile = require('./my-asset-folder/local-site.html'); - -class MyWeb extends Component { - render() { - return ; - } -} -``` - -No entanto, no Android, você precisa colocar o arquivo HTML dentro do diretório de ativos do seu projeto Android. Por exemplo, se `local-site.html` for seu arquivo HTML e você quiser carregá-lo na visualização da web, você deve mover o arquivo para o diretório de ativos do Android do seu projeto, que é `your-project/android/app/src /main/assets/`. Então você pode carregar o arquivo html conforme mostrado no seguinte bloco de código - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - render() { - return ( - - ); - } -} -``` - -
- -### Controlando as alterações do estado de navegação - -Às vezes, você deseja interceptar um usuário tocando em um link em sua visualização da web e fazer algo diferente de navegar na visualização da web. Aqui está um código de exemplo de como você pode fazer isso usando a função `onNavigationStateChange`. - -```js -import React, { Component } from 'react'; -import { WebView } from 'react-native-webview'; - -class MyWeb extends Component { - webview = null; - - render() { - return ( - (this.webview = ref)} - source={{ uri: 'https://reactnative.dev/' }} - onNavigationStateChange={this.handleWebViewNavigationStateChange} - /> - ); - } - - handleWebViewNavigationStateChange = (newNavState) => { - // newNavState se parece com isso: - // { - // url?: string; - // title?: string; - // loading?: boolean; - // canGoBack?: boolean; - // canGoForward?: boolean; - // } - const { url } = newNavState; - if (!url) return; - - // lidar com doctypes - if (url.includes('.pdf')) { - this.webview.stopLoading(); - // abra um modal com o visualizador de PDF - } - - // uma maneira de lidar com um envio de formulário bem-sucedido é por meio de strings de consulta - if (url.includes('?message=success')) { - this.webview.stopLoading(); - // talvez fechar? - } - - // uma maneira de lidar com erros é via string de consulta - if (url.includes('?errors=true')) { - this.webview.stopLoading(); - } - - // redirecionar para outro lugar - if (url.includes('google.com')) { - const newURL = 'https://reactnative.dev/'; - const redirectTo = 'window.location = "' + newURL + '"'; - this.webview.injectJavaScript(redirectTo); - } - }; -} -``` - -### Adicionar suporte para upload de arquivos - -##### iOS - -Para iOS, tudo que você precisa fazer é especificar as permissões em seu arquivo `ios/[project]/Info.plist`: - -Captura de foto: - -``` -NSCameraUsageDescription -Take pictures for certain activities -``` - -Seleção de galeria: - -``` -NSPhotoLibraryUsageDescription -Select pictures for certain activities -``` - -Gravação de vídeo: - -``` -NSMicrophoneUsageDescription -Need microphone access for recording videos -``` - -##### Android - -Adicione permissão no AndroidManifest.xml: - -```xml - - ...... - - - - - ...... - -``` - -###### Disponibilidade da opção de câmera no upload para Android - -Se a entrada do arquivo indicar que imagens ou vídeo são desejados com [`accept`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept), então a WebView tentará fornecer opções ao usuário para usar sua câmera para tirar uma foto ou vídeo. - -Normalmente, os aplicativos que não têm permissão para usar a câmera podem solicitar que o usuário use um aplicativo externo para que o aplicativo solicitante não precise de permissão. No entanto, o Android fez uma exceção especial para isso em torno da câmera para reduzir a confusão dos usuários. Se um aplicativo _can_ solicitar a permissão da câmera porque foi declarado e o usuário não concedeu a permissão, ele não poderá disparar um intent que usaria a câmera (`MediaStore.ACTION_IMAGE_CAPTURE` ou `MediaStore.ACTION_VIDEO_CAPTURE`). Nesse cenário, cabe ao desenvolvedor solicitar a permissão da câmera antes que um upload de arquivo diretamente usando a câmera seja necessário. - -##### Verifique se há suporte para upload de arquivos, com `static isFileUploadSupported()` - -O upload de arquivo usando `` não é compatível com o Android 4.4 KitKat (consulte os [detalhes](https://github.com/delight-im/Android-AdvancedWebView/issues/4#issuecomment-70372146 )): - -```javascript -import { WebView } from "react-native-webview"; - -WebView.isFileUploadSupported().then(res => { - if (res === true) { - // o upload de arquivos é suportado - } else { - // o upload de arquivos não é suportado - } -}); -``` - -### Upload de vários arquivos - -Você pode controlar a seleção de arquivo **único** ou **múltiplo** especificando o [`múltiplo`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#multiple) em seu elemento `input`: - -```javascript -// seleção de vários arquivos - - -// seleção de arquivo único - -``` - -### Adicionar suporte para download de arquivos - -##### iOS - -O iOS, você terá que fornecer seu próprio código para baixar os arquivos. Você pode fornecer um retorno de chamada `onFileDownload` para o componente WebView como um prop. Se o RNCWebView determinar que um download de arquivo precisa ocorrer, a URL onde você pode baixar o arquivo será dado a `onFileDownload`. A partir desse retorno de chamada, você pode baixar esse arquivo da maneira que desejar. - -NOTA: O iOS 13+ é necessário para a melhor experiência de download possível. No iOS 13, a Apple adicionou uma API para acessar cabeçalhos de resposta HTTP, que -é usado para determinar se uma resposta HTTP deve ser um download. No iOS 12 ou anterior, apenas os tipos MIME que não podem ser renderizados pela webview serão -acionar chamadas para `onFileDownload`. - -Exemplo: - -```javascript -onFileDownload = ({ nativeEvent }) => { - const { downloadUrl } = nativeEvent; - // --> Seu código de download vai aqui <-- -}; -``` - -Para poder salvar imagens na galeria você precisa especificar esta permissão em seu arquivo `ios/[project]/Info.plist`: - -``` -NSPhotoLibraryAddUsageDescription -Save pictures for certain activities. -``` - -##### Android - -No Android, a integração com o DownloadManager é integrada. -Adicione esta permissão em AndroidManifest.xml (necessário apenas se seu aplicativo for compatível com versões do Android anteriores a 10): - -```xml - - ...... - - - - - ...... - -``` - -### Comunicação entre JS e Native - -Muitas vezes você vai querer enviar mensagens para as páginas da web carregadas por suas visualizações da web e também receber mensagens de volta dessas páginas da web. - -Para fazer isso, o React Native WebView expõe três opções diferentes: - -1. Reagir Nativo -> Web: A prop `injectedJavaScript` -2. Reagir Nativo -> Web: O método `injectJavaScript` -3. Web -> React Native: O método `postMessage` e a prop `onMessage` - -#### A prop `injectedJavaScript` - -Este é um script que é executado imediatamente após o carregamento da página da Web pela primeira vez. Ele é executado apenas uma vez, mesmo que a página seja recarregada ou navegada. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const runFirst = ` - document.body.style.backgroundColor = 'red'; - setTimeout(function() { window.alert('hi') }, 2000); - true; // nota: isso é necessário, ou às vezes você terá falhas - `; - return ( - - {}} - injectedJavaScript={runFirst} - /> - - ); - } -} -``` - -Isso executa o JavaScript na string `runFirst` assim que a página é carregada. Nesse caso, você pode ver que o estilo do corpo foi alterado para vermelho e o alerta apareceu após 2 segundos. Um evento `onMessage` também é necessário para injetar o código JavaScript no WebView. - -Ao definir `injectedJavaScriptForMainFrameOnly: false`, a injeção de JavaScript ocorrerá em todos os quadros (não apenas no quadro principal) se houver suporte para a plataforma especificada. Por exemplo, se uma página contiver um iframe, o javascript também será injetado nesse iframe com este definido como `false`. (Observe que isso não é suportado no Android.) Há também o `injectedJavaScriptBeforeContentLoadedForMainFrameOnly` para injeção antes do carregamento do conteúdo. Leia mais sobre isso na [Referência](./Reference.portuguese.md#injectedjavascriptformainframeonly). - -screenshot of Github repo - -_Como funciona no OS_ - -> No iOS, ~~`injectedJavaScript` executa um método no WebView chamado `evaluateJavaScript:completionHandler:`~~ – isso não é mais verdade a partir da versão `8.2.0`. Em vez disso, usamos um `WKUserScript` com tempo de injeção `WKUserScriptInjectionTimeAtDocumentEnd`. Como consequência, o `injectedJavaScript` não retorna mais um valor de avaliação nem registra um aviso no console. No caso improvável de seu aplicativo depender desse comportamento, consulte as etapas de migração [aqui](https://github.com/react-native-webview/react-native-webview/pull/1119#issuecomment-574919464) para manter comportamento equivalente. -> No Android, `injectedJavaScript` executa um método no Android WebView chamado `evaluateJavascriptWithFallback` -> No Windows, o `injectedJavaScript` executa um método no WinRT/C++ WebView chamado `InvokeScriptAsync` - -#### A prop `injectedJavaScriptBeforeContentLoaded` - -Este é um script executado **antes** do carregamento da página da Web pela primeira vez. Ele é executado apenas uma vez, mesmo que a página seja recarregada ou navegada. Isso é útil se você deseja injetar qualquer coisa na janela, armazenamento local ou documento antes da execução do código da web. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const runFirst = ` - window.isNativeApp = true; - true; // nota: isso é necessário, ou às vezes você terá falhas - `; - return ( - - - - ); - } -} -``` - -Isso executa o JavaScript na string `runFirst` antes que a página seja carregada. Nesse caso, o valor de `window.isNativeApp` será definido como true antes que o código da web seja executado. - -Ao definir `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false`, a injeção de JavaScript ocorrerá em todos os quadros (não apenas no quadro superior) se houver suporte para a plataforma especificada. No entanto, embora o suporte para `injectedJavaScriptBeforeContentLoadedForMainFrameOnly: false` tenha sido implementado para iOS e macOS, [não está claro](https://github.com/react-native-webview/react-native-webview/pull/1119#issuecomment-600275750) que é realmente possível injetar JS em iframes neste ponto do ciclo de vida da página e, portanto, confiar no comportamento esperado dessa prop quando definido como `false` não é recomendado. - -> No iOS, ~~`injectedJavaScriptBeforeContentLoaded` executa um método no WebView chamado `evaluateJavaScript:completionHandler:`~~ – isso não é mais verdade a partir da versão `8.2.0`. Em vez disso, usamos um `WKUserScript` com tempo de injeção `WKUserScriptInjectionTimeAtDocumentStart`. Como consequência, `injectedJavaScriptBeforeContentLoaded` não retorna mais um valor de avaliação nem registra um aviso no console. No caso improvável de seu aplicativo depender desse comportamento, consulte as etapas de migração [aqui](https://github.com/react-native-webview/react-native-webview/pull/1119#issuecomment-574919464) para manter comportamento equivalente. -> No Android, `injectedJavaScript` executa um método no Android WebView chamado `evaluateJavascriptWithFallback` -> Observação sobre compatibilidade com Android: para aplicativos direcionados a `Build.VERSION_CODES.N` ou posterior, o estado JavaScript de um WebView vazio não é mais mantido em navegações como `loadUrl(java.lang.String)`. Por exemplo, variáveis ​​globais e funções definidas antes de chamar `loadUrl(java.lang.String)` não existirão na página carregada. Os aplicativos devem usar a API nativa do Android `addJavascriptInterface(Object, String)` para persistir objetos JavaScript nas navegações. - -#### O método `injectJavaScript` - -Embora conveniente, a desvantagem da prop `injectedJavaScript` mencionado anteriormente é que ele é executado apenas uma vez. É por isso que também expomos um método no webview ref chamado `injectJavaScript` (observe o nome ligeiramente diferente!). - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const run = ` - document.body.style.backgroundColor = 'blue'; - true; - `; - - setTimeout(() => { - this.webref.injectJavaScript(run); - }, 3000); - - return ( - - (this.webref = r)} - source={{ - uri: 'https://github.com/react-native-webview/react-native-webview', - }} - /> - - ); - } -} -``` - -Após 3 segundos, este código torna o fundo azul: - -Screenshot of app showing injected javascript - -_Como funciona no OS_ - -> No iOS, `injectJavaScript` chama `evaluateJS:andThen:` da WebView -> No Android, `injectJavaScript` chama o método `evaluateJavascriptWithFallback` do Android WebView - -#### O método `window.ReactNativeWebView.postMessage` e a prop `onMessage` - -Ser capaz de enviar JavaScript para a página da Web é ótimo, mas e quando a página da Web deseja se comunicar de volta ao seu código React Native? É aqui que entram o `window.ReactNativeWebView.postMessage` e a prop `onMessage`. - -Você _deve_ definir `onMessage` ou o método `window.ReactNativeWebView.postMessage` não será injetado na página web. - -`window.ReactNativeWebView.postMessage` só aceita um argumento que deve ser uma string. - -```jsx -import React, { Component } from 'react'; -import { View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -export default class App extends Component { - render() { - const html = ` - - - - - - - `; - - return ( - - { - alert(event.nativeEvent.data); - }} - /> - - ); - } -} -``` - -Este código resultará neste alerta: - -Alert showing communication from web page to React Native - -### Trabalhando com cabeçalhos, sessões e cookies personalizados - -#### Configurando cabeçalhos personalizados - -No React Native WebView, você pode definir um cabeçalho personalizado como este: - -```jsx - -``` - -Isso definirá o cabeçalho no primeiro carregamento, mas não nas navegações de página subsequentes. - -Para contornar isso, você pode rastrear o URL atual, interceptar novos carregamentos de página e navegar até eles você mesmo ([crédito original desta técnica para Chirag Shah do Big Binary](https://blog.bigbinary.com/2016/07/26/passing-request-headers-on-each-webview-request-in-react-native.html)): - -```jsx -const CustomHeaderWebView = (props) => { - const { uri, onLoadStart, ...restProps } = props; - const [currentURI, setURI] = useState(props.source.uri); - const newSource = { ...props.source, uri: currentURI }; - - return ( - { - // Se estivermos carregando o URI atual, permita que ele carregue - if (request.url === currentURI) return true; - // Estamos carregando um novo URL -- altere o estado primeiro - setURI(request.url); - return false; - }} - /> - ); -}; - -; -``` - -#### Gerenciando cookies - -Você pode definir cookies no lado React Native usando o pacote [@react-native-community/cookies](https://github.com/react-native-community/cookies). - -Ao fazer isso, você provavelmente desejará habilitar a propriedade [sharedCookiesEnabled](Reference.portuguese.md#sharedCookiesEnabled) também. - -```jsx -const App = () => { - return ( - - ); -}; -``` - -Se você deseja enviar cookies personalizados na própria WebView, pode fazê-lo em um cabeçalho personalizado, como este: - -```jsx -const App = () => { - return ( - - ); -}; -``` - -Observe que esses cookies só serão enviados na primeira solicitação, a menos que você use a técnica acima para [definir cabeçalhos personalizados em cada carregamento de página](#Setting-Custom-Headers). - -### Interruptor de silêncio de hardware - -Existem algumas inconsistências na forma como o interruptor de silêncio de hardware é tratado entre os elementos `audio` e `video` incorporados e entre as plataformas iOS e Android. - -O áudio no `iOS` será silenciado quando a chave de silêncio do hardware estiver na posição ligada, a menos que o parâmetro `ignoreSilentHardwareSwitch` seja definido como verdadeiro. - -O vídeo no `iOS` sempre ignorará a chave de silêncio do hardware. - -## Traduções - -Esse arquivo está disponível em: - -- [Inglês](Guide.md) -- [Italiano](Guide.italian.md) diff --git a/docs/README.french.md b/docs/README.french.md deleted file mode 100644 index 62a5b39a5..000000000 --- a/docs/README.french.md +++ /dev/null @@ -1,78 +0,0 @@ -# React Native WebView - -![star this repo](https://img.shields.io/github/stars/react-native-webview/react-native-webview?style=flat-square) -[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) -[![NPM Version](https://img.shields.io/npm/v/react-native-webview.svg?style=flat-square)](https://www.npmjs.com/package/react-native-webview) -![Npm Downloads](https://img.shields.io/npm/dm/react-native-webview.svg) - -**React Native WebView** est un composent WebView maintenu par la communauté. Il existe en remplacement au composant WebView de React Native (qui a [été retiré du core](https://github.com/react-native-community/discussions-and-proposals/pull/3)). - -### Contributeurs - -**Merci beaucoup aux entreprises** pour nous permettre de travailler sur de l'open source. -Également beaucoup de temps personnel est investi pour maintenir ce projet, n'hésitez pas à nous sponsoriser, **ça aide vraiment.** - -- [Thibault Malbranche](https://github.com/Titozzz) ([Twitter @titozzz](https://twitter.com/titozzz)) de [Brigad](https://www.brigad.co/fr-fr/about-us) -[*Me Sponsor* ❤️ !](https://github.com/sponsors/Titozzz) - - -Windows et macOS sont maintenues par Microsoft, notamment: -- [Alexander Sklar](https://github.com/asklar) ([Twitter @alexsklar](https://twitter.com/alexsklar)) de [React Native for Windows](https://microsoft.github.io/react-native-windows/) -- [Chiara Mooney](https://github.com/chiaramooney) de [React Native for Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) - -Grand merci à [Jamon Holmgren](https://github.com/jamonholmgren) de [Infinite Red](https://infinite.red) pour l'aide apportée lorsqu'il avait plus de temps disponible. - -### Disclaimer - -Maintenir la WebView est très compliqué, à cause de ses nombreux usages (rendering svgs, pdfs, login flows, et autres). On supporte également de nombreuses plateformes et les deux architectures de React Native. - -Depuis que la WebView a été retirée du core, près de 500 PR ont été mergées. -En considérant que nous possédons un temps limité, les issues github serviront principalement comme lieu d'échange pour la communauté, tandis que **nous prioriserons les reviews et les merges de pull requests** - -### Platform compatibles - -Ce projet est compatible avec **iOS**, **Android**, **Windows** et **macOS**. -Ce projet supporte à la fois **l'ancienne** (paper) **et la nouvelle architecture** (fabric). -Ce projet est compatible avec [expo](https://docs.expo.dev/versions/latest/sdk/webview/). - -## Débuter - -Lisez attentivement notre guide (exclusivement en anglais) [Getting Started Guide](docs/Getting-Started.md). Si la moindre étape ne semble pas claire, merci de créer une **issue** détaillée. - -## Versionnage - -Ce projet suit la [gestion sémantique de version](https://semver.org/). Nous n'hésitons pas à publier des modifications "breaking-change", mais elles seront intégrées dans une version majeure. - -## Utilisation - -Importez le composant `WebView` de `react-native-webview` et utilisez le de la manière suivante : - -```tsx -import React, { Component } from 'react'; -import { StyleSheet, Text, View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -// ... -const MyWebComponent = () => { - return ; -} -``` - -Pour plus de détails, lisez la [Référence API](./docs/Reference.md) et le [Guide](./docs/Guide.md). Si vous êtes intéressé à contribuer, lisez le [Guide de contribution](./docs/Contributing.md). - -## Problèmes communs - -- Si l'erreur `Invariant Violation: Native component for "RNCWebView does not exist"` intervient, cela signifie probablement que vous avez oublié d'executer `react-native link` ou qu'une erreur est intervenue durant le processus de liaison. -- Si vous rencontrer une erreur de build durant l'execution de la tâche `:app:mergeDexRelease`, vous devez activer le support du multidex dans `android/app/build.gradle` comme discuté [ici](https://github.com/react-native-webview/react-native-webview/issues/1344#issuecomment-650544648) - -## Contribuer - -Voir [Contributing.md](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Contributing.md) - -## Translations - -This readme is available in: - -- [English](../README.md) -- [Italian](README.italian.md) -- [Brazilian portuguese](README.portuguese.md) diff --git a/docs/README.italian.md b/docs/README.italian.md deleted file mode 100644 index c7d33ed20..000000000 --- a/docs/README.italian.md +++ /dev/null @@ -1,63 +0,0 @@ -# React Native WebView - -![Dai una stella a questo repo](https://img.shields.io/github/stars/react-native-webview/react-native-webview?style=flat-square&label=stelle) -[![PRs gradite](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) -[![Versione NPM](https://img.shields.io/npm/v/react-native-webview.svg?style=flat-square)](https://www.npmjs.com/package/react-native-webview) -![NPM Downloads mensili](https://img.shields.io/npm/dm/react-native-webview.svg) - -**React Native WebView** è un componente WebView mantenuto dalla community per React Native. È un sostituto del WebView integrato, il quale è stato rimosso dal core. - -### Manutentori -**Un ringraziamento speciale a queste aziende** per averci concesso del tempo per lavorare su software open source. Si prega di notare che anche i mantainer dedicano molto del loro tempo libero a lavorare su questo progetto, quindi sentiti libero di sponsorizzarli: **fa davvero la differenza**. - -- [Thibault Malbranche](https://github.com/Titozzz) ([Twitter @titozzz](https://twitter.com/titozzz)) di [Brigad](https://www.brigad.co/en-gb/about-us) -[*Sponsorizzami* ❤️ !](https://github.com/sponsors/Titozzz) - -Windows e macOS sono gestiti da Microsoft, in particolare: -- [Alexander Sklar](https://github.com/asklar) ([Twitter @alexsklar](https://twitter.com/alexsklar)) di [React Native per Windows](https://microsoft.github.io/react-native-windows/) -- [Chiara Mooney](https://github.com/chiaramooney) di [React Native per Windows presso Microsoft](https://microsoft.github.io/react-native-windows/) - -Un ringraziamento speciale va dato a [Jamon Holmgren](https://github.com/jamonholmgren) della [Infinite Red](https://infinite.red) per il prezioso aiuto fornito al repository quando aveva più tempo a disposizione. - -### Esonero da responsabilità -Mantenere la WebView è molto complesso, poiché viene frequentemente impiegata in numerosi scenari d'uso diversi, come ad esempio la renderizzazione di SVG, PDF, flussi di accesso e altri ancora. Supportiamo inoltre numerose piattaforme e entrambe le architetture di React Native. - -Dal momento che WebView è stato estratto dal core di React Native, sono state integrate quasi 500 pull request. Considerando che abbiamo un tempo limitato, gli issue serviranno principalmente come luogo di discussione per la comunità, mentre **daremo priorità alla revisione e all'integrazione delle pull request**. - -### Compatibilità con le piattaforme -Questo progetto è compatibile con le seguenti piattaforme: **iOS**, **Android**, **Windows** e **macOS**. Supporta sia **la vecchia architettura** (paper) **che la nuova architettura** (fabric). Inoltre, è compatibile con [Expo](https://docs.expo.dev/versions/latest/sdk/webview/). - -### Version -Questo progetto segue la convenzione del [versionamento semantico](https://semver.org/lang/it/). Non esitiamo a rilasciare modifiche che potrebbero causare incompatibilità (breaking changes), ma lo faremo all'interno di una versione principale. - -### Utilizzo -Importa il componente `WebView` da `react-native-webview` per poi usarlo nel seguente modo: - -```tsx -import React, { Component } from 'react'; -import { StyleSheet, Text, View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -// ... -const MyWebComponent = () => { - return ; -} -``` - -Per ulteriori informazioni, leggi il [riferimento alle API](Reference.italian.md) e la [guida](Guide.italian.md). Se sei interessato a dare il tuo contributo, consulta la [guida per i collaboratori](Contributing.italian.md). - -### Problemi comuni -- Se riscontri `Invariant Violation: Native component for "RNCWebView does not exist"`, probabilmente significa che hai dimenticato di eseguire `react-native link` o c'è stato qualche errore durante il processo di collegamento. -- In caso di un errore di compilazione durante l'operazione `:app:mergeDexRelease`, devi abilitare il supporto multidex in `android/app/build.gradle`, come discusso in [questa issue](https://github.com/react-native-webview/react-native-webview/issues/1344#issuecomment-650544648). - -### Contribuire -Le contribuzioni sono benvenute, per maggiori informazioni consulta la pagina [Contributing.md](Contributing.italian.md). - -### Licenza -MIT - -### Traduzioni -Questo readme è disponibile nelle seguenti lingue: -- [Francese](README.french.md) -- [Inglese](../README.md) -- [Portoghese brasiliano](README.portuguese.md) \ No newline at end of file diff --git a/docs/README.portuguese.md b/docs/README.portuguese.md deleted file mode 100644 index 934535ec7..000000000 --- a/docs/README.portuguese.md +++ /dev/null @@ -1,109 +0,0 @@ -# React Native WebView - Um moderno, WebView multiplataforma para React Native - -[![star this repo](http://githubbadges.com/star.svg?user=react-native-webview&repo=react-native-webview&style=flat)](https://github.com/react-native-webview/react-native-webview) -[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) -[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors) -[![Known Vulnerabilities](https://snyk.io/test/github/react-native-webview/react-native-webview/badge.svg?style=flat-square)](https://snyk.io/test/github/react-native-webview/react-native-webview) - - -**React Native WebView** é um moderno WebView multiplataforma para React Native. Ele foi projetado para substituir o WebView embutido(que será [removido do core](https://github.com/react-native-community/discussions-and-proposals/pull/3)). - -## Principais Mantenedores - Empresas Patrocinadoras - -_Esse projeto é mantido gratuitamente por essas pessoas usando ambos, seu tempo livre e tempo de trabalho na empresa._ - -- [Thibault Malbranche](https://github.com/Titozzz) ([Twitter @titozzz](https://twitter.com/titozzz)) from [Brigad](https://brigad.co/about) -- [Jamon Holmgren](https://github.com/jamonholmgren) ([Twitter @jamonholmgren](https://twitter.com/jamonholmgren)) from [Infinite Red](https://infinite.red/react-native) -- [Alexander Sklar](https://github.com/asklar) ([Twitter @alexsklar](https://twitter.com/alexsklar)) from [React Native Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) -- [Chiara Mooney](https://github.com/chiaramooney) from [React Native Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) - -## Plataformas suportadas - -- [x] iOS -- [x] Android -- [x] macOS -- [x] Windows - -_Nota: O suporte da Expo para o React Native WebView começou com [Expo SDK v33.0.0](https://blog.expo.io/expo-sdk-v33-0-0-is-now-available-52d1c99dfe4c)._ - -## Começando - -Leia nosso [Getting Started Guide](docs/Getting-Started.md). Se algum passo não ficou claro, por favor, crie um issue detalhado. - -## Versionamento - -Esse projeto segue [versionamento semântico](https://semver.org/). Não hesitamos em lançar as alterações mais recentes, mas elas estarão em uma versão principal. - -**Histórico:** - -Versão atual: ![version](https://img.shields.io/npm/v/react-native-webview.svg) - -- [11.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v11.0.0) - Android setSupportMultipleWindows. -- [10.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v10.0.0) - O plugin Android Gradle só é necessário ao abrir o projeto _stand-alone_. -- [9.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v9.0.0) - Atualizações de _props_ para injectedJavaScript não são mais imutáveis. -- [8.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v8.0.0) - onNavigationStateChange agora é disparado quando alterado o hash da URL. -- [7.0.1](https://github.com/react-native-webview/react-native-webview/releases/tag/v7.0.1) - UIWebView removido. -- [6.0.**2**](https://github.com/react-native-webview/react-native-webview/releases/tag/v6.0.2) - Update para AndroidX. Tenha certeza de habilitar no `android/gradle.properties` do seu projeto. Veja o [Getting Started Guide](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Getting-Started.md). -- [5.0.**1**](https://github.com/react-native-webview/react-native-webview/releases/tag/v5.0.0) - Refatorou a antiga implementação postMessage para comunicação da visualização da webview para nativa. -- [4.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v4.0.0) - Cache adicionada(habilitada por padrão). -- [3.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v3.0.0) - WKWebview: Adicionado um pool de processos compartilhados para que os cookies e o localStorage sejam compartilhados nas webviews no iOS (habilitadas por padrão) -- [2.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v2.0.0) - Primeiro lançamento, esta é uma réplica do componente principal do webview. - -**Próximos Passos:** - -- Remoção do this.webView.postMessage() ( - nunca foi documentado e é menos flexível que o injectJavascript) -> [Como migrar](https://github.com/react-native-webview/react-native-webview/issues/809) -- Reescrita em Kotlin -- Talvez reescrita em Swift - -## Uso - -Importe o componente `WebView` `react-native-webview` e use assim: - -```jsx -import React, { Component } from 'react'; -import { StyleSheet, Text, View } from 'react-native'; -import { WebView } from 'react-native-webview'; - -// ... -class MyWebComponent extends Component { - render() { - return ; - } -} -``` - -Para mais informações, leia a [API Reference](./docs/Reference.md) e o [Guia](./docs/Guide.md). Se você está interessado em contribuir, confira o [Guia de contribuição](./docs/Contributing.md). - -## Problemas comuns - -- Se você está recebendo `Invariant Violation: Native component for "RNCWebView does not exist"` provavelmente significa que você esqueceu de rodar `react-native link` ou houve algum erro no processo de linking. -- Se você encontrar um erro de compilação durante a tarefa: `app:mergeDexRelease`, será necessário habilitar o suporte multidex em `android/app/build.gradle` conforme discutido [neste problema](https://github.com/react-native-webview/react-native-webview/issues/1344#issuecomment-650544648) - -## Contribuindo - -Veja [Contributing.md](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Contributing.md) - -## Contribuidores - -Um grande obrigado vai para essas pessoas maravilhosas ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key-)): - - - -
Thibault Malbranche
Thibault Malbranche

💻 🤔 👀 📖 🚧 ⚠️ 🚇 💬
Jamon Holmgren
Jamon Holmgren

💻 🤔 👀 📖 🚧 ⚠️ 💡 💬
Andrei Pfeiffer
Andrei Pfeiffer

💻 👀 🤔
Michael Diarmid
Michael Diarmid

💻 👀 🤔 🔧
Scott Mathson
Scott Mathson

💻 📖
Margaret
Margaret

💻 📖
Jordan Sexton
Jordan Sexton

💻 📖
Malcolm Scruggs
Malcolm Scruggs

💻 🔧 ⚠️
Momazo7u7
Momazo7u7

📖
Marco
Marco

📖
Julien Eluard
Julien Eluard

📖
Jian Wei
Jian Wei

💻 📖
Sergei Butko
Sergei Butko

📖
TMomemt
TMomemt

💻
Eric Lewis
Eric Lewis

💻 📖
Daniel Vicory
Daniel Vicory

💻 📖
- - - -Esse projeto segue a especificação [all-contributors](https://github.com/all-contributors/all-contributors). Contribuições de qualquer tipo são bem-vindas! - -## Licença - -MIT - -## Traduções - -Esse readme está disponível em: - -- [Francês](README.french.md) -- [Inglês](../README.md) -- [Italiano](README.italian.md) diff --git a/docs/Reference.italian.md b/docs/Reference.italian.md deleted file mode 100644 index 18fb8329e..000000000 --- a/docs/Reference.italian.md +++ /dev/null @@ -1,1591 +0,0 @@ -# Riferimento all'API di React Native WebView - -Questo documento elenca le attuali proprietà e metodi pubblici di React Native WebView. - -## Indice delle Props - -- [`source`](Reference.italian.md#source) -- [`automaticallyAdjustContentInsets`](Reference.italian.md#automaticallyadjustcontentinsets) -- [`automaticallyAdjustsScrollIndicatorInsets`](Reference.italian.md#automaticallyAdjustsScrollIndicatorInsets) -- [`injectedJavaScript`](Reference.italian.md#injectedjavascript) -- [`injectedJavaScriptBeforeContentLoaded`](Reference.italian.md#injectedjavascriptbeforecontentloaded) -- [`injectedJavaScriptForMainFrameOnly`](Reference.italian.md#injectedjavascriptformainframeonly) -- [`injectedJavaScriptBeforeContentLoadedForMainFrameOnly`](Reference.italian.md#injectedjavascriptbeforecontentloadedformainframeonly) -- [`mediaPlaybackRequiresUserAction`](Reference.italian.md#mediaplaybackrequiresuseraction) -- [`nativeConfig`](Reference.italian.md#nativeconfig) -- [`onError`](Reference.italian.md#onerror) -- [`onRenderProcessGone`](Reference.italian.md#onRenderProcessGone) -- [`onLoad`](Reference.italian.md#onload) -- [`onLoadEnd`](Reference.italian.md#onloadend) -- [`onLoadStart`](Reference.italian.md#onloadstart) -- [`onLoadProgress`](Reference.italian.md#onloadprogress) -- [`onHttpError`](Reference.italian.md#onhttperror) -- [`onMessage`](Reference.italian.md#onmessage) -- [`onNavigationStateChange`](Reference.italian.md#onnavigationstatechange) -- [`onContentProcessDidTerminate`](Reference.italian.md#oncontentprocessdidterminate) -- [`onScroll`](Reference.italian.md#onscroll) -- [`originWhitelist`](Reference.italian.md#originwhitelist) -- [`renderError`](Reference.italian.md#rendererror) -- [`renderLoading`](Reference.italian.md#renderloading) -- [`scalesPageToFit`](Reference.italian.md#scalespagetofit) -- [`onShouldStartLoadWithRequest`](Reference.italian.md#onshouldstartloadwithrequest) -- [`startInLoadingState`](Reference.italian.md#startinloadingstate) -- [`style`](Reference.italian.md#style) -- [`containerStyle`](Reference.italian.md#containerStyle) -- [`decelerationRate`](Reference.italian.md#decelerationrate) -- [`domStorageEnabled`](Reference.italian.md#domstorageenabled) -- [`javaScriptEnabled`](Reference.italian.md#javascriptenabled) -- [`javaScriptCanOpenWindowsAutomatically`](Reference.italian.md#javascriptcanopenwindowsautomatically) -- [`androidLayerType`](Reference.italian.md#androidLayerType) -- [`mixedContentMode`](Reference.italian.md#mixedcontentmode) -- [`thirdPartyCookiesEnabled`](Reference.italian.md#thirdpartycookiesenabled) -- [`userAgent`](Reference.italian.md#useragent) -- [`applicationNameForUserAgent`](Reference.italian.md#applicationNameForUserAgent) -- [`allowsFullscreenVideo`](Reference.italian.md#allowsfullscreenvideo) -- [`allowsInlineMediaPlayback`](Reference.italian.md#allowsinlinemediaplayback) -- [`allowsAirPlayForMediaPlayback`](Reference.italian.md#allowsAirPlayForMediaPlayback) -- [`bounces`](Reference.italian.md#bounces) -- [`overScrollMode`](Reference.italian.md#overscrollmode) -- [`contentInset`](Reference.italian.md#contentinset) -- [`contentInsetAdjustmentBehavior`](Reference.italian.md#contentInsetAdjustmentBehavior) -- [`contentMode`](Reference.italian.md#contentMode) -- [`dataDetectorTypes`](Reference.italian.md#datadetectortypes) -- [`scrollEnabled`](Reference.italian.md#scrollenabled) -- [`nestedScrollEnabled`](Reference.italian.md#nestedscrollenabled) -- [`setBuiltInZoomControls`](Reference.italian.md#setBuiltInZoomControls) -- [`setDisplayZoomControls`](Reference.italian.md#setDisplayZoomControls) -- [`directionalLockEnabled`](Reference.italian.md#directionalLockEnabled) -- [`geolocationEnabled`](Reference.italian.md#geolocationenabled) -- [`allowFileAccessFromFileURLs`](Reference.italian.md#allowFileAccessFromFileURLs) -- [`allowUniversalAccessFromFileURLs`](Reference.italian.md#allowUniversalAccessFromFileURLs) -- [`allowingReadAccessToURL`](Reference.italian.md#allowingReadAccessToURL) -- [`keyboardDisplayRequiresUserAction`](Reference.italian.md#keyboardDisplayRequiresUserAction) -- [`hideKeyboardAccessoryView`](Reference.italian.md#hidekeyboardaccessoryview) -- [`allowsBackForwardNavigationGestures`](Reference.italian.md#allowsbackforwardnavigationgestures) -- [`incognito`](Reference.italian.md#incognito) -- [`allowFileAccess`](Reference.italian.md#allowFileAccess) -- [`saveFormDataDisabled`](Reference.italian.md#saveFormDataDisabled) -- [`cacheEnabled`](Reference.italian.md#cacheEnabled) -- [`cacheMode`](Reference.italian.md#cacheMode) -- [`pagingEnabled`](Reference.italian.md#pagingEnabled) -- [`allowsLinkPreview`](Reference.italian.md#allowsLinkPreview) -- [`sharedCookiesEnabled`](Reference.italian.md#sharedCookiesEnabled) -- [`textZoom`](Reference.italian.md#textZoom) -- [`pullToRefreshEnabled`](Reference.italian.md#pullToRefreshEnabled) -- [`ignoreSilentHardwareSwitch`](Reference.italian.md#ignoreSilentHardwareSwitch) -- [`onFileDownload`](Reference.italian.md#onFileDownload) -- [`limitsNavigationsToAppBoundDomains`](Reference.italian.md#limitsNavigationsToAppBoundDomains) -- [`textInteractionEnabled`](Reference.italian.md#textInteractionEnabled) -- [`mediaCapturePermissionGrantType`](Reference.italian.md#mediaCapturePermissionGrantType) -- [`autoManageStatusBarEnabled`](Reference.italian.md#autoManageStatusBarEnabled) -- [`setSupportMultipleWindows`](Reference.italian.md#setSupportMultipleWindows) -- [`basicAuthCredential`](Reference.italian.md#basicAuthCredential) -- [`enableApplePay`](Reference.italian.md#enableApplePay) -- [`forceDarkOn`](Reference.italian.md#forceDarkOn) -- [`useWebView2`](Reference.italian.md#useWebView2) -- [`minimumFontSize`](Reference.italian.md#minimumFontSize) -- [`downloadingMessage`](Reference.italian.md#downloadingMessage) -- [`lackPermissionToDownloadMessage`](Reference.italian.md#lackPermissionToDownloadMessage) -- [`allowsProtectedMedia`](Reference.italian.md#allowsProtectedMedia) -- [`webviewDebuggingEnabled`](Reference.italian.md#webviewDebuggingEnabled) - -## Methods Index - -- [`goForward`](Reference.italian.md#goforward) -- [`goBack`](Reference.italian.md#goback) -- [`reload`](Reference.italian.md#reload) -- [`stopLoading`](Reference.italian.md#stoploading) -- [`injectJavaScript`](Reference.italian.md#injectjavascriptstr) -- [`clearFormData`](Reference.italian.md#clearFormData) -- [`clearCache`](Reference.italian.md#clearCachebool) -- [`clearHistory`](Reference.italian.md#clearHistory) -- [`requestFocus`](Reference.italian.md#requestFocus) -- [`postMessage`](Reference.italian.md#postmessagestr) - ---- - -# Riferimento - -## Props - -### `source`[⬆](#props-index) -Carica HTML statico o un URI (con eventuali header) nella WebView. Si noti che l'HTML statico richiederà l'impostazione di [`originWhitelist`](Reference.italian.md#originWhiteList) a `["*"]`. - -L'oggetto passato a `source` può avere una delle seguenti forme: - -**Caricamento di un URI** -- `uri` (string) - L'URI da caricare nel `WebView`. Può essere un file locale o remoto e può essere modificato con lo stato o le props di React per navigare verso una nuova pagina. -- `method` (string) - Il metodo HTTP da utilizzare. Se non specificato, il valore predefinito è GET. Su Android e Windows, i metodi supportati sono solo GET e POST. -- `headers` (object) - Intestazioni HTTP aggiuntive da inviare con la richiesta. Su Android, queste possono essere utilizzate solo con richieste GET. Consulta la [Guida](Guida.italian.md#impostazione-degli-header-personalizzati) per ulteriori informazioni sull'impostazione di header personalizzati. -- `body` (string) - Il body HTTP da inviare con la richiesta. Deve essere una stringa valida in formato UTF-8 e verrà inviata esattamente come specificato, senza ulteriori codifiche (ad esempio, URL-escaping o base64) applicate. Su Android e Windows, questo può essere utilizzato solo con richieste POST. - -**HTML Statico** -_Note that using static HTML requires the WebView property [originWhiteList](Reference.italian.md#originWhiteList) to `['*']`. For some content, such as video embeds (e.g. Twitter or Facebook posts with video), the baseUrl needs to be set for the video playback to work_ - -- `html` (string) - Una pagina HTML statica da visualizzare nel WebView. -- `baseUrl` (string) - L'URL di base da utilizzare per i link relativi nell'HTML. Questo viene utilizzato anche per l'header dell'origine con le richieste CORS effettuate dal WebView. Consulta la documentazione di [Android WebView](https://developer.android.com/reference/android/webkit/WebView#loadDataWithBaseURL) per ulteriori informazioni. - -| Tipo | Obbligatorio | -| ------ | ------------ | -| object | No | - ---- - -### `automaticallyAdjustContentInsets`[⬆](#props-index) -Controlla se regolare l'inset del contenuto per le web view posizionate dietro una barra di navigazione, una barra delle schede o una barra degli strumenti. Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | iOS | - ---- - -### `automaticallyAdjustsScrollIndicatorInsets`[⬆](#props-index) -Controlla se regolare l'inset dell'indicatore di scroll per le web view posizionate dietro una barra di navigazione, una barra delle schede o una barra degli strumenti. Il valore predefinito è `false`. (iOS 13+) - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | iOS(13+) | - ---- - -### `injectedJavaScript`[⬆](#props-index) -Imposta questo per fornire del codice JavaScript che verrà iniettato nella pagina web dopo il completamento del caricamento del documento, ma prima del completamento del caricamento di altre risorse secondarie. - -Assicurati che la stringa abbia un tipo valido (`true` funziona) e non generi eccezioni. - -Su iOS, consulta [`WKUserScriptInjectionTimeAtDocumentEnd`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentend?language=objc). Assicurati di impostare un handler [`onMessage`](Reference.italian.md#onmessage), anche se è una funzione vuota, altrimenti il codice non verrà eseguito. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ---------------------------- | -| string | No | iOS, Android, macOS, Windows | - -Per saperne di più leggi la guida [Comunicazione tra JS e Native](Guide.italian.md#comunicazione-tra-js-e-native). - -N.B.: Windows non ha [supporto nativo per gli alert](https://github.com/MicrosoftDocs/winrt-api/blob/docs/windows.ui.xaml.controls/webview.md#use-of-alert), pertanto eventuali script che mostrano un alert non funzioneranno. - -Esempio: - -Invia un messaggio contenente `window.location` sottoforma di un oggetto JSON da gestire tramite [`onMessage`](Reference.italian.md#onmessage): - -```jsx -const INJECTED_JAVASCRIPT = `(function() { - window.ReactNativeWebView.postMessage(JSON.stringify(window.location)); -})();`; - -; -``` - ---- - -### `injectedJavaScriptBeforeContentLoaded`[⬆](#props-index) -Imposta questo per passare del codice JavaScript che verrà iniettato nella pagina web dopo la creazione dell'elemento del documento, ma prima del completamento del caricamento di altre risorse secondarie. - -Assicurati che la stringa abbia un tipo valido (`true` funziona) e non generi eccezioni. - -Su iOS, consulta [`WKUserScriptInjectionTimeAtDocumentStart`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentstart?language=objc). - -> **Avviso** -> Su Android, funziona, ma non è affidabile al 100% (vedi [#1609](https://github.com/react-native-webview/react-native-webview/issues/1609) e [#1099](https://github.com/react-native-webview/react-native-webview/pull/1099)). - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ---------------------------------- | -| string | No | iOS, macOS, Android (experimental) | - -Per saperne di più leggi la guida [Comunicazione tra JS e Native](Guide.italian.md#comunicazione-tra-js-e-native). - -Esempio: - -Invia un messaggio contenente `window.location` sottoforma di un oggetto JSON da gestire tramite [`onMessage`](Reference.italian.md#onmessage). `window.ReactNativeWebView.postMessage` questa volta _sarà_ disponibile. - -```jsx -const INJECTED_JAVASCRIPT = `(function() { - window.ReactNativeWebView.postMessage(JSON.stringify(window.location)); -})();`; - -; -``` - ---- - -### `injectedJavaScriptForMainFrameOnly`[⬆](#props-index) -If `true` (default; mandatory for Android), loads the `injectedJavaScript` only into the main frame. - -If `false`, (only supported on iOS and macOS), loads it into all frames (e.g. iframes). - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | -------------------------------------------------------- | -| bool | No | iOS e macOS (Android ha supporto solo quando è `true`) | - ---- - -### `injectedJavaScriptBeforeContentLoadedForMainFrameOnly`[⬆](#props-index) -If `true` (default; mandatory for Android), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame. - -If `false`, (only supported on iOS and macOS), loads it into all frames (e.g. iframes). - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | -------------------------------------------------------- | -| bool | No | iOS e macOS (Android ha supporto solo quando è `true`) | - ---- - -### `mediaPlaybackRequiresUserAction`[⬆](#props-index) -Boolean che determina se è necessario che l'audio e il video HTML5 richiedano all'utente di interagire prima di avviare la riproduzione. Il valore predefinito è `true`. (Versione minima dell'API Android 17). - -NOTA: il valore predefinito `true` potrebbe causare il blocco del caricamento di alcuni video su iOS. Impostarlo su `false` potrebbe risolvere questo problema. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `nativeConfig`[⬆](#props-index) -Sovrascrive il componente nativo utilizzato per il render della WebView. Consente di utilizzare una WebView nativa personalizzata che usa lo stesso JavaScript della WebView originale. - -La prop `nativeConfig` si aspetta un oggetto con le seguenti chiavi: - -- `component` (any) -- `props` (object) -- `viewManager` (object) - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------------- | -| object | No | iOS, Android, macOS | - ---- - -### `onError`[⬆](#props-index) -Funzione che viene invocata quando il caricamento della `WebView` non riesce. - -| Tipo | Obbligatorio | -| -------- | ------------ | -| function | No | - -Esempio: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn('Errore WebView: ', nativeEvent); - }} -/> -``` - -La funzione passata a `onError` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -canGoBack -canGoForward -code -description -didFailProvisionalNavigation -domain -loading -target -title -url -``` - -> **_Nota_** -> Domain è solo usato su iOS - -Il `syntheticEvent` può essere interrotto nell'esecuzione dell'azione predefinita chiamando `syntheticEvent.preventDefault()`. - ---- - -### `onLoad`[⬆](#props-index) -Funzione che viene invocata quando il caricamento della `WebView` è completato. - -| Tipo | Obbligatorio | -| -------- | ------------ | -| function | No | - -Esempio: - -```jsx - { - const { nativeEvent } = syntheticEvent; - this.url = nativeEvent.url; - }} -/> -``` - -La funzione passata a `onLoad` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadEnd`[⬆](#props-index) -Funzione che viene invocata quando il caricamento della `WebView` va a buon fine o fallisce. - -| Tipo | Obbligatorio | -| -------- | ------------ | -| function | No | - -Esempio: - -```jsx - { - // update component to be aware of loading status - const { nativeEvent } = syntheticEvent; - this.isLoading = nativeEvent.loading; - }} -/> -``` - -La funzione passata a `onLoadEnd` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadStart`[⬆](#props-index) -Funzione che viene invocata quando il caricamento della `WebView` inizia. - -| Tipo | Obbligatorio | -| -------- | ------------ | -| function | No | - -Esempio: - -```jsx - { - // update component to be aware of loading status - const { nativeEvent } = syntheticEvent; - this.isLoading = nativeEvent.loading; - }} -/> -``` - -La funzione passata a `onLoadStart` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadProgress`[⬆](#props-index) -Funzione che viene invocata quando la `WebView` sta caricando. - -| Tipo | Obbligatorio | Piattaforma | -| -------- | ------------ | ------------------- | -| function | No | iOS, Android, macOS | - -Esempio: - -```jsx - { - this.loadingProgress = nativeEvent.progress; - }} -/> -``` - -La funzione passata a `onLoadProgress` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -canGoBack -canGoForward -loading -progress -target -title -url -``` - ---- - -### `onHttpError`[⬆](#props-index) -Funzione che viene invocata quando la `WebView` riceve un errore HTTP. - -> **_Nota_** -> Versione minima dell'API Android 23. - -| Tipo | Obbligatorio | -| -------- | ------------ | -| function | No | - -Esempio: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn( - 'WebView received error status code: ', - nativeEvent.statusCode, - ); - }} -/> -``` - -La funzione passata a `onHttpError` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -canGoBack -canGoForward -description -loading -statusCode -target -title -url -``` - -> **_Note_** -> Description è usata solo su Android - ---- - -### `onRenderProcessGone`[⬆](#props-index) -Funzione che viene invocata quando il processo della `WebView` si arresta in modo anomalo o viene interrotto dal sistema operativo su Android. - -> **_Nota_** -> Versione minima dell'API Android. Solo Android - -| Tipo | Obbligatorio | -| -------- | ------------ | -| function | No | - -Esempio: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn( - 'La WebView ha crashato: ', - nativeEvent.didCrash, - ); - }} -/> -``` - -La funzione passata a `onRenderProcessGone` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -didCrash -``` ---- - -### `onMessage`[⬆](#props-index) -Funzione che viene invocata quando la WebView chiama `window.ReactNativeWebView.postMessage`. Impostando questa proprietà, verrà iniettato questo oggetto globale nella WebView. - -`window.ReactNativeWebView.postMessage` accetta un argomento, `data`, che sarà disponibile sull'oggetto evento come `event.nativeEvent.data`. `data` deve essere una stringa. - -| Tipo | Obbligatorio | -| -------- | ------------ | -| function | No | - -Per saperne di più leggi la guida [Comunicazione tra JS e Native](Guide.italian.md#comunicazione-tra-js-e-native). - ---- - -### `onNavigationStateChange`[⬆](#props-index) -Funzione che viene invocata quando il caricamento del `WebView` inizia o termina. - -| Tipo | Obbligatorio | -| -------- | ------------ | -| function | No | - -Esempio: - -```jsx - { - // Tenere traccia della navigazione "indietro" all'interno del componente - this.canGoBack = navState.canGoBack; - }} -/> -``` - -L'oggetto `navState` ha le seguenti proprietà: - -``` -canGoBack -canGoForward -loading -navigationType (solo iOS) -target -title -url -``` - ---- - -### `onContentProcessDidTerminate`[⬆](#props-index) -Funzione che viene invocata quando l'elaborazione del contenuto della `WebView` viene terminato. - -| Tipo | Obbligatorio | Piattaforma | -| -------- | ------------ | --------------------------- | -| function | No | iOS e macOS WKWebView | - -Le web view di iOS utilizzano un processo separato per il rendering e la gestione dei contenuti web. WebKit chiama questo metodo quando il processo per la web view specificata termina per qualsiasi motivo. -Il motivo non è necessariamente un crash. Ad esempio, poiché le web view di iOS non sono incluse nella RAM totale dell'app, possono essere terminate indipendentemente dall'app per liberare memoria per nuove app che l'utente sta aprendo. Non è insolito che le Web view vengano terminate dopo un po' di tempo in background. - -Esempio: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn('Elaborazione del contenuto terminato, ricaricamento in corso.', nativeEvent); - this.refs.webview.reload(); - }} -/> -``` - -La funzione passata a `onContentProcessDidTerminate` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onScroll`[⬆](#props-index) -Funzione che viene invocata quando viene generato l'evento di scorrimento (`scroll`) nella `WebView`. - -| Tipo | Obbligatorio | Piattaforma | -| -------- | ------------ | ---------------------------- | -| function | No | iOS, macOS, Android, Windows | - -Esempio: - -```jsx - { - const { contentOffset } = syntheticEvent.nativeEvent - console.table(contentOffset) - }} -/> -``` - -La funzione passata a `onScroll` viene chiamata con un evento sintetico (`SyntheticEvent`) che racchiude un evento nativo con le seguenti proprietà: - -``` -contentInset -contentOffset -contentSize -layoutMeasurement -velocity -zoomScale -``` - ---- - -### `originWhitelist`[⬆](#props-index) -Elenco di stringhe di origine consentite per la navigazione. Le stringhe consentono caratteri jolly (*) e vengono confrontate solo con l'origine (non l'URL completo). Se l'utente schiaccia per navigare verso una nuova pagina ma la nuova pagina non è in questa lista di controllo, l'URL verrà gestito dal sistema operativo. Le origini predefinite in lista bianca (whitelist o allowlist) sono "http://*" e "https://*". - -| Tipo | Obbligatorio | Piattaforma | -| ---------------- | ------------ | ------------------- | -| array of strings | No | iOS, Android, macOS | - -Esempio: - -```jsx -// Consenti solo URI che iniziano con https:// or git:// - -``` - ---- - -### `renderError`[⬆](#props-index) -Funzione che restituisce una View da mostrare in caso di errore. - -| Tipo | Obbligatorio | Piattaforma | -| -------- | ------------ | ------------------- | -| function | No | iOS, Android, macOS | - -Esempio: - -```jsx - } -/> -``` - -La funzione passata a `renderError` verrà chiamata con il nome dell'errore. - ---- - -### `renderLoading`[⬆](#props-index) -Funzione che restituisce un indicatore di caricamento. La prop `startInLoadingState` deve essere impostata su `true` per utilizzare questa prop. - -| Tipo | Obbligatorio | Piattaforma | -| -------- | ------------ | ------------------- | -| function | No | iOS, Android, macOS | - -Esempio: - -```jsx - } -/> -``` - ---- - -### `scalesPageToFit`[⬆](#props-index) -Boolean che controlla se il contenuto web viene ridimensionato per adattarsi alla vista e consente all'utente di modificare la scala. Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | Android | - ---- - -### `onShouldStartLoadWithRequest`[⬆](#props-index) -Funzione che consente la gestione personalizzata di qualsiasi richiesta della web view. Restituisci `true` dalla funzione per continuare a caricare la richiesta e `false` per interrompere il caricamento. - -Su Android, non viene chiamata durante il primo caricamento. - -| Tipo | Obbligatorio | Piattaforma | -| -------- | ------------ | ------------------- | -| function | No | iOS, Android, macOS | - -Esempio: - -```jsx - { - // Consenti solo la navigazione all'interno di questo sito web. - return request.url.startsWith('https://reactnative.dev'); - }} -/> -``` - -L'oggetto `request` include queste proprietà: - -``` -title -url -loading -target -canGoBack -canGoForward -lockIdentifier -mainDocumentURL (solo iOS) -navigationType (solo iOS) -isTopFrame (solo iOS) -``` - ---- - -### `startInLoadingState`[⬆](#props-index) -Boolean che forza la `WebView` a mostrare una View di caricamento durante il primo caricamento. Questa prop dev'essere impostata su `true` affinché la prop `renderLoading` funzioni. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `style`[⬆](#props-index) -[Style](https://reactnative.dev/docs/view-style-props) ti permette di personalizzare lo stile della `WebView`. Nota che ci sono stili predefiniti (ad esempio: è necessario aggiungere `flex: 0` allo stile se si desidera utilizzare la proprietà `height`). - -| Tipo | Obbligatorio | -| ----- | ------------ | -| style | No | - -Esempio: - -```jsx - -``` - ---- - -### `containerStyle`[⬆](#props-index) -[Style](https://reactnative.dev/docs/view-style-props) che consente di personalizzare lo stile del contenitore della `WebView`. Nota che ci sono stili predefiniti (ad esempio: è necessario aggiungere `flex: 0` allo stile se si desidera utilizzare la proprietà `height`). - -| Tipo | Obbligatorio | -| ----- | ------------ | -| style | No | - -Esempio: - -```jsx - -``` - ---- - -### `decelerationRate`[⬆](#props-index) -Un numero in virgola mobile che determina quanto rapidamente lo scroll nella view decelera dopo che l'utente ha sollevato il dito. È possibile utilizzare anche i valori di stringa `"normal"` e `"fast"` che corrispondono alle impostazioni sottostanti di iOS per `UIScrollViewDecelerationRateNormal` e `UIScrollViewDecelerationRateFast` rispettivamente: -- `normal`: 0,998 -- `fast`: 0,99 (impostazione predefinita per la web view di iOS) - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| number | No | iOS | - ---- - -### `domStorageEnabled`[⬆](#props-index) -Valore booleano per controllare se il DOM Storage è abilitato. Usato solo in Android. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | Android | - ---- - -### `javaScriptEnabled`[⬆](#props-index) -Valore booleano per abilitare JavaScript nella `WebView`. Il valore predefinito è `true`. - -| Tipo | Obbligatorio | -| ---- | ------------ | -| bool | No | - ---- - -### `javaScriptCanOpenWindowsAutomatically`[⬆](#props-index) -Una boolean che indica se JavaScript può aprire finestre senza chel'utente interagisca. Il valore predefinito è `false`. - -| Tipo | Obbligatorio | -| ---- | ------------ | -| bool | No | - ---- - -### `androidLayerType`[⬆](#props-index) -Specifica il tipo di layer. - -I possibili valori per `androidLayerType` sono: - -- `none` (predefinito): la view non ha un layer. -- `software`: la view ha un layer software. Un layer software è supportato da un bitmap e fa sì che la view venga renderizzata utilizzando la pipeline di rendering software di Android, anche se l'accelerazione hardware è abilitata. -- `hardware`: la view ha un layer hardware. Un layer hardware è supportato da una texture specifica dell'hardware e fa sì che la view venga renderizzata utilizzando la pipeline di rendering hardware di Android, ma solo se l'accelerazione hardware è abilitata per la gerarchia delle view. - - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| string | No | Android | - ---- - -### `mixedContentMode`[⬆](#props-index) -Specifica la modalità di contenuto misto. Ad esempio, la WebView consentirà a un'origine sicura di caricare contenuti da qualsiasi altra origine. - -I possibili valori per `mixedContentMode` sono: - -- `never` (predefinito): la WebView non consentirà a un'origine sicura di caricare contenuti da un'origine non sicura. -- `always`: la WebView consentirà a un'origine sicura di caricare contenuti da qualsiasi altra origine, anche se questa origine non è sicura. -- `compatibility`: la WebView cercherà di essere compatibile con l'approccio di un web browser moderno per quanto riguarda i contenuti misti. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| string | No | Android | - ---- - -### `thirdPartyCookiesEnabled`[⬆](#props-index) -Boolean che abilita i cookie di terze parti nella WebView. Utilizzato solo su Android Lollipop e versioni successive, poiché i cookie di terze parti sono abilitati per impostazione predefinita su Android Kitkat e versioni precedenti e su iOS. Il valore predefinito è `true`. Per ulteriori informazioni sui cookie, leggi la [guida per come gestire i cookie](Guide.italian.md#gestione-dei-cookie). - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | Android | - ---- - -### `userAgent`[⬆](#props-index) -Imposta l'user-agent per la WebView. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ----------------------- | -| string | No | iOS, Android, macOS | - ---- - -### `applicationNameForUserAgent`[⬆](#props-index) -Aggiungi all'user-agent esistente. Impostare `userAgent` sovrascriverà questa opzione. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ----------------------- | -| string | No | iOS, Android, macOS | - -```jsx - -// Il risultato dell'user-agent sarà simile a: -// Mozilla/5.0 (Linux; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.021; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36 DemoApp/1.1.0 -// Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DemoApp/1.1.0 -``` - -### `allowsFullscreenVideo`[⬆](#props-index) -Boolean che determina se è consentito riprodurre i video a schermo intero. Il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | Android | - ---- - -### `allowsInlineMediaPlayback`[⬆](#props-index) -Boolean che determina se i video HTML5 vengono riprodotti all'interno del contenuto o utilizzano il controller a schermo intero nativo. Il valore predefinito è `false`. - -> **NOTA** -> -> Per consentire la riproduzione inline dei video, non basta solo che questa proprietà sia impostata su `true`, ma l'elemento video nel documento HTML deve anche includere l'attributo `webkit-playsinline`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | iOS | - ---- -### `allowsAirPlayForMediaPlayback`[⬆](#props-index) -Un valore booleano che indica se è consentito l'uso di AirPlay. Il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ----------------- | -| boolean | No | iOS e macOS | - ---- - -### `bounces`[⬆](#props-index) -Valore booleano che determina se la web view effettua l'effetto di "rimbalzo" (bounce) quando raggiunge il bordo del contenuto. Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | iOS | - ---- - -### `overScrollMode`[⬆](#props-index) -Specifica la modalità di overscroll. - -I possibili valori per `overScrollMode` sono: - -- `always` (predefinito): consente sempre all'utente di eseguire l'overscroll su questa view, a condizione che sia una view scrollabile. -- `content`: consente all'utente di eseguire l'overscroll su questa view solo se il contenuto è sufficientemente grande da poter usare lo scrolling in modo significativo, a condizione che sia una view che ha lo scrolling. -- `never`: Non consente mai all'utente di eseguire l'overscroll su questa view. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| string | No | Android | - ---- - -### `contentInset`[⬆](#props-index) - -La quantità di spazio tra il contenuto della WebView e i bordi della ScrollView. Impostato di default su {top: 0, left: 0, bottom: 0, right: 0}. - -| Tipo | Obbligatorio | Piattaforma | -| ------------------------------------------------------------------ | ------------ | ------------ | -| object: {top: number, left: number, bottom: number, right: number} | No | iOS | - ---- - -### `contentInsetAdjustmentBehavior`[⬆](#props-index) -Questa proprietà specifica come gli inset della safe area vengono utilizzati per modificare l'area del contenuto della scroll view. Il valore predefinito di questa proprietà è "never" (mai). Disponibile su iOS 11 e versioni successive. Il valore Predefinito è `never`. - -Valori possibili: -- `automatic` (automatico) -- `scrollableAxes` (assi scorrevoli) -- `never` (mai) -- `always` (sempre) - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| string | No | iOS | - ---- - -### `contentMode`[⬆](#props-index) -Controlla il tipo di contenuto da caricare. Disponibile su iOS 13 e versioni successive. Predefinito a `recommended` (consigliato), che carica contenuti per dispositivi mobili su iPhone e iPad Mini, ma contenuti per desktop su iPad più grandi. - -Per ulteriori informazioni consulta [Introducing Desktop-class Browsing on iPad](https://developer.apple.com/videos/play/wwdc2019/203/). - -Valori possibili: -- `recommended` (consigliato) -- `mobile` -- `desktop` - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| string | No | iOS | - ---- - -### `dataDetectorTypes`[⬆](#props-index) -I tipi di dati riconosciuti per la rilevazione dei link nel contenuto della web view. Di seguito sono riportati i possibili valori per `dataDetectorTypes`: - -- `phoneNumber` -- `link` -- `address` -- `calendarEvent` -- `none` -- `all` -- `trackingNumber` -- `flightNumber` -- `lookupSuggestion` - -| Tipo | Obbligatorio | Piattaforma | -| ---------------- | ------------ | ------------ | -| string o array | No | iOS | - ---- - -### `scrollEnabled`[⬆](#props-index) -Boolean che determina se la funzionalità di scroll è abilitata nella `WebView`. Il valore predefinito è `true`. Impostando questo valore su `false`, la webview non sposterà il body del documento quando la tastiera appare sopra un campo di input. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ----------------- | -| bool | No | iOS e macOS | - ---- - -### `nestedScrollEnabled`[⬆](#props-index) -Boolean che determina se è possibile effettuare lo scroll nella `WebView` quando viene utilizzato all'interno di un `ScrollView` su Android. Il valore predefinito è `false`. - -Impostando questo valore su `true`, verrà impedito alla `ScrollView` di effettuare lo scrolling quando si scorre all'interno della `WebView`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ----------------- | -| bool | No | Android | - ---- - -### `setBuiltInZoomControls`[⬆](#props-index) -Imposta se la WebView usa meccanismi di zoom integrati. Il valore predefinito è `true`. Impostando questo valore su `false`, verrà impedito l'uso del gesto di pinch (pizzico) per il controllo dello zoom. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ----------------- | -| bool | No | Android | - ---- - -### `setDisplayZoomControls`[⬆](#props-index) -Imposta se la WebView deve mostrare i controlli di zoom sullo schermo quando si utilizzano i meccanismi di zoom integrati (vedi `setBuiltInZoomControls`). Il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ----------------- | -| bool | No | Android | - ---- - -### `directionalLockEnabled`[⬆](#props-index) -Un valore booleano che determina se lo scrolling è disabilitato per una direzione specifica. Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | iOS | - ---- - -### `showsHorizontalScrollIndicator`[⬆](#props-index) -Boolean che determina se l'indicatore di scrolling orizzontale viene mostrato nella `WebView`. Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ----------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `showsVerticalScrollIndicator`[⬆](#props-index) -Boolean che determina se l'indicatore di scrolling verticale viene mostrato nella `WebView`. Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ----------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `geolocationEnabled`[⬆](#props-index) -Imposta se la geolocalizzazione è abilitata nella `WebView`. Il valore predefinito è `false`. Supportato solo su Android. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------ | -| bool | No | Android | - ---- - -### `allowFileAccessFromFileURLs`[⬆](#props-index) -Il valore booleano determina se è consentito a JavaScript, in esecuzione all'interno di un URL con schema file, di accedere ai contenuti di altri URL con schema file. Il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ----------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `allowUniversalAccessFromFileURLs`[⬆](#props-index) -Il valore booleano determina se è consentito a JavaScript, in esecuzione all'interno di un URL con schema file, di accedere ai contenuti di qualsiasi origine, compresi i contenuti di altri URL con schema file. Il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ---- | ------------ | ------------------------ | -| bool | No | iOS, Android, macOS | - ---- - -### `allowingReadAccessToURL`[⬆](#props-index) -Il valore di tipo stringa indica a quali URL il file della WebView può fare riferimento negli script, nelle richieste AJAX e negli import di CSS. Questo viene utilizzato solo per le WebView che vengono caricate con un `source.uri` impostato su un URL `'file://'`. Se non viene fornito, il valore predefinito è consentire solo l'accesso in lettura all'URL fornito in `source.uri` stesso. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ----------------- | -| string | No | iOS e macOS | - ---- - -### `keyboardDisplayRequiresUserAction`[⬆](#props-index) -Se impostato su `false`, il contenuto web non mostra la tastiera mediante codice (programmatically). Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | iOS | - ---- - -### `hideKeyboardAccessoryView`[⬆](#props-index) -Se impostato su `true`, nasconde la view accessorio della tastiera(< > e Fatto). - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | iOS | - ---- - -### `allowsBackForwardNavigationGestures`[⬆](#props-index) -Se impostato su `true`, sarà possibile utilizzare i gesti di scrolling orizzontale. Il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ----------------- | -| boolean | No | iOS e macOS | - ---- - -### `incognito`[⬆](#props-index) -Non memorizza alcun dato durante il ciclo di vita della WebView. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ----------------------- | -| boolean | No | iOS, Android, macOS | - ---- - -### `allowFileAccess`[⬆](#props-index) -Se impostato su `true`, consentirà l'accesso ai file di sistema tramite URI `file://`. Il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | Android | - ---- - -### `saveFormDataDisabled`[⬆](#props-index) -Imposta se la WebView deve disabilitare il salvataggio dei dati dei form. Il valore predefinito è `false`. Questa funzione non ha alcun effetto dall'API level 26 di Android in poi, in quanto è presente una funzionalità di compilazione automatica che memorizza i dati dei form. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | Android | - ---- - -### `cacheEnabled`[⬆](#props-index) -Imposta se la WebView deve utilizzare la cache del browser. - -| Tipo | Obbligatorio | Default | Piattaforma | -| ------- | ------------ | ------- | ----------------------- | -| boolean | No | true | iOS, Android, macOS | - ---- - -### `cacheMode`[⬆](#props-index) -Sovrascrive il modo in cui viene usata la cache. Il modo in cui viene utilizzata la cache dipende dal tipo di navigazione. Per un normale caricamento della pagina, la cache viene controllata e il contenuto viene rivalidato se necessario. Quando si torna indietro, il contenuto non viene rivalidato, ma viene semplicemente recuperato dalla cache. Questa proprietà consente al client di sovrascrivere questo comportamento. - -I valori possibili sono: - -- `LOAD_DEFAULT`: modalità di utilizzo predefinita della cache. Se il tipo di navigazione non impone alcun comportamento specifico, usa le risorse in cache quando sono disponibili e non scadute, altrimenti carica le risorse dalla rete. -- `LOAD_CACHE_ELSE_NETWORK`: utilizza le risorse in cache quando sono disponibili, anche se sono scadute. Altrimenti carica le risorse dalla rete. -- `LOAD_NO_CACHE`: non utilizza la cache, carica dalla rete. -- `LOAD_CACHE_ONLY`: non utilizza la rete, carica dalla cache. - -| Tipo | Obbligatorio | Default | Piattaforma | -| ------ | ------------ | ------------ | ------------ | -| string | No | LOAD_DEFAULT | Android | - ---- - -### `pagingEnabled`[⬆](#props-index) -Quando il valore di questa proprietà è impostato su `true`, la view di scrolling si fermerà sugli intervalli corrispondenti ai limiti della vista stessa quando l'utente effettua uno scroll. Il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | iOS | - ---- - -### `allowsLinkPreview`[⬆](#props-index) -Boolean che determina se la pressione su un link visualizza un'anteprima della destinazione del link. In iOS, questa proprietà è disponibile sui dispositivi che supportano il 3D Touch. In iOS 10 e versioni successive, il valore predefinito è `true`. Prima di iOS 10, il valore predefinito è `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ----------------- | -| boolean | No | iOS e macOS | - ---- - -### `sharedCookiesEnabled`[⬆](#props-index) -Imposta `true` se i cookie condivisi da `[NSHTTPCookieStorage sharedHTTPCookieStorage]` devono essere usati per ogni richiesta di caricamento nella WebView. Il valore predefinito è `false`. Per ulteriori informazioni sui cookie, leggi la [guida di gestione dei cookie](Guide.italian.md#gestione-dei-cookie) - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ----------------- | -| boolean | No | iOS e macOS | - ---- - -### `textZoom`[⬆](#props-index) -Se l'utente ha impostato una dimensione del carattere personalizzata nel sistema Android, si verifica una scala indesiderata dell'interfaccia del sito nella WebView. - -Impostando la prop `textZoom` standard (100), questa conseguenza indesiderata scompare. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| number | No | Android | - -Esempio: - -```jsx - -``` - ---- - -### `pullToRefreshEnabled`[⬆](#props-index) -Boolean che determina se è abilitato il gesto di trascinamento per aggiornare nella WebView. Il valore predefinito è `false`, il che significa che il gesto di trascinamento per aggiornare non è disponibile. Se impostato su `true`, abiliterà automaticamente la proprietà `bounces` a `true`, consentendo al contenuto di rimbalzare quando viene trascinato oltre i limiti. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | iOS | - -### `ignoreSilentHardwareSwitch`[⬆](#props-index) -(solo iOS) - -Quando impostato su `true`, viene ignorato il pulsante del silenzioso dell'hardware fisico. Predefinito: `false`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | iOS | - -### `onFileDownload`[⬆](#props-index) -(solo iOS) - -È una funzione che viene invocata quando il client ha bisogno di scaricare un file. - -Solo su iOS 13 e successivi: Se la WebView naviga verso un URL che restituisce una risposta HTTP con un'intestazione Content-Disposition 'attachment...', allora questa funzione verrà chiamata. - -Su iOS 8 e successivi: Se il tipo MIME indica che il contenuto non può essere visualizzato dalla WebView, ciò causerà anche la chiamata di questa funzione. Prima di iOS 13, questa è l'unica condizione che provocherà la chiamata di questa funzione. - -L'applicazione dovrà fornire il proprio codice per effettuare effettivamente il download del file. - -Se non viene fornito codice, il comportamento predefinito è consentire alla WebView di provare a visualizzare il file. - -Esempio: - -```jsx - { - // Puoi utilizzare la prop downloadUrl come una stringa per scaricare i file nel modo desiderato. - }} -/> -``` - -| Tipo | Obbligatorio | Piattaforma | -| -------- | ------------ | ------------ | -| function | No | iOS | - ---- - -### `limitsNavigationsToAppBoundDomains`[⬆](#props-index) -Se impostato su `true`, indica a WebKit che un WKWebView può navigare solo su domini legati all'applicazione. Applicabile solo su iOS 14 o versioni successive. - -Una volta impostato, qualsiasi tentativo di navigare su una pagina che non ha un dominio legato all'applicazione fallirà con l'errore "App-bound domain failure" (mancato dominio legato all'applicazione). -Le applicazioni possono specificare fino a 10 domini "app-bound" utilizzando una nuova chiave `WKAppBoundDomains` nel file `Info.plist`. Per ulteriori informazioni, consulta [App-Bound Domains](https://webkit.org/blog/10882/app-bound-domains/). - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | iOS | - -Esempio: - -```jsx - -``` - ---- - -### `textInteractionEnabled`[⬆](#props-index) -Se impostato su `false`, indica a WebKit che un WKWebView non interagirà con il testo e non mostrerà quindi un'area di selezione del testo. Applicabile solo su iOS 14.5 o versioni successive. - -Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | iOS | - -Esempio: - -```jsx - -``` - ---- - -### `mediaCapturePermissionGrantType`[⬆](#props-index) -Questa prop specifica come gestire le richieste di autorizzazione per la cattura degli strumenti di comunicazione. Il valore predefinito è `prompt`, il che comporta che all'utente venga richiesta l'autorizzazione ripetutamente. Disponibile su iOS 15 e versioni successive. - -I possibili valori sono: - -- `grantIfSameHostElsePrompt`: se l'host dell'origine di sicurezza della richiesta di autorizzazione corrisponde all'host dell'URL corrente della WebView, l'autorizzazione viene concessa se è stata concessa in precedenza. In caso contrario, viene richiesta l'autorizzazione all'utente. -- `grantIfSameHostElseDeny`: se l'host dell'origine di sicurezza della richiesta di autorizzazione corrisponde all'host dell'URL corrente della WebView, l'autorizzazione viene concessa se è stata concessa in precedenza. In caso contrario, viene negata. -- `deny` -- `grant`: l'autorizzazione viene concessa se è stata concessa in precedenza. -- `prompt` - -Nota che anche una concessione può comportare una richiesta all'utente, ad esempio se l'autorizzazione non è mai stata richiesta all'utente in precedenza. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| string | No | iOS | - -Esempio: - -```jsx - -``` - ---- - -### `autoManageStatusBarEnabled`[⬆](#props-index) -Se impostato su `true`, la barra di stato verrà automaticamente nascosta/mostrata dalla WebView, in particolare quando si guarda un video a schermo intero. Se impostato su `false`, WebView non gestirà affatto la barra di stato. Il valore predefinito è `true`. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | iOS | - -Esempio: - -```jsx - -``` - -### `setSupportMultipleWindows`[⬆](#props-index) -Imposta se la WebView supporta più finestre. Consulta la [documentazione di Android]('https://developer.android.com/reference/android/webkit/WebSettings#setSupportMultipleWindows(boolean)') per ulteriori informazioni. -Impostando questo valore su `false`, si potrebbe esporre l'applicazione a questa [vulnerabilità](https://alesandroortiz.com/articles/uxss-android-webview-cve-2020-6506/), consentendo a un iframe maligno di sfuggire al DOM del livello superiore. - -| Tipo | Obbligatorio | Default | Piattaforma | -| ------- | ------------ | ------- | ------------ | -| boolean | No | true | Android | - -Esempio: - -```jsx - -``` - -### `enableApplePay`[⬆](#props-index) -Una boolean che, quando impostata su `true`, renderizzerà la WebView con il supporto di Apple Pay. Una volta impostato, i siti web saranno in grado di invocare Apple Pay da React Native Webview. -Tuttavia, ciò comporta alcune limitazioni, ad esempio le funzionalità come [`injectJavaScript`](Reference.italian.md#injectjavascriptstr), la cronologia di HTML5, [`sharedCookiesEnabled`](Reference.italian.md#sharedCookiesEnabled), [`injectedJavaScript`](Reference.italian.md#injectedjavascript) e [`injectedJavaScriptBeforeContentLoaded`](Reference.italian.md#injectedjavascriptbeforecontentloaded) non funzioneranno. Consulta la [nota di rilascio di Apple Pay](https://developer.apple.com/documentation/safari-release-notes/safari-13-release-notes#Payment-Request-API) per ulteriori informazioni. - -Se devi inviare messaggi all'app, la pagina web dovrà chiamare esplicitamente l'handler dei messaggi di WebKit e riceverli tramite l'handler `onMessage` nel lato di React Native. - -```javascript -window.webkit.messageHandlers.ReactNativeWebView.postMessage("ciao apple pay") -``` - -| Tipo | Obbligatorio | Default | Piattaforma | -| ------- | ------------ | ------- | ------------ | -| boolean | No | false | iOS | - -Esempio: - -```jsx - -``` - -### `forceDarkOn`[⬆](#props-index) -Configurazione del tema scuro (Dark Mode). - -*NOTA*: L'impostazione della Dark Mode non è persistente. È necessario chiamare il metodo statico ogni volta che il processo dell'app viene avviato. - -*NOTA*: Il passaggio da modalità giorno a modalità notte è una modifica di configurazione, quindi per l'impostazione predefinita l'attività verrà riavviata e registrerà i nuovi valori per attivare il tema. Presta attenzione quando sovrascrivi questo comportamento predefinito e assicurati che questo metodo venga comunque chiamato quando vengono apportate modifiche. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | Android | - -Esempio: - -```javascript - -``` - -### `menuItems`[⬆](#props-index) -Un array di oggetti di elementi di menu personalizzati che verranno aggiunti all'UIMenu che appare quando si seleziona del testo (appariranno dopo 'Copia' e 'Condividi...'). Utilizzato insieme a `onCustomMenuSelection`. - -| Tipo | Obbligatorio | Piattaforma | -| ------------------------------------------------------------------ | ------------ | ------------ | -| array of objects: {label: string, key: string} | No | iOS | - -Esempio: - -```jsx - -``` - -### `onCustomMenuSelection`[⬆](#props-index) -La funzione chiamata quando viene selezionato un elemento di menu personalizzato. Riceve un evento Native che include tre chiavi personalizzate: `label`, `key` e `selectedText`. - -| Tipo | Obbligatorio | Piattaforma | -| ------------------------------------------------------------------ | ------------ | ------------ | -| function | No | iOS | - -```javascript - { - const { label } = webViewEvent.nativeEvent; // Il nome dell'elemento di menu, i.e. 'Tweet' - const { key } = webViewEvent.nativeEvent; // La chiave dell'elemento di menu, i.e. 'tweet' - const { selectedText } = webViewEvent.nativeEvent; // Testo evidenziato - }} -/> -``` - -### `basicAuthCredential`[⬆](#props-index) -Un oggetto che specifica le credenziali di un utente da usare per l'autenticazione di base. -- `username` (string): un nome utente usato per l'autenticazione di base. -- `password` (string): una password usata per l'autenticazione di base. - -| Tipo | Obbligatorio | -| ------ | ------------ | -| object | No | - -### `useWebView2`[⬆](#props-index) -Usa il controllo WebView2 di WinUI al posto del controllo WebView come visualizzatore web nativo. Il controllo WebView2 è un controllo WinUI che renderizza il contenuto web utilizzando il motore di esecuzione Microsoft Edge (Chromium). L'opzione può essere attivata o disattivata durante l'esecuzione e supporta Fast Refresh. Per saperne di più leggi la sezione riguardante WebView2 nella [guida getting-started](Getting-Started.italian.md#3-supporto-per-webview2). - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | Windows | - -Esempio: - -```javascript - -``` - -### `minimumFontSize`[⬆](#props-index) -Android impone una dimensione minima del carattere basata su questo valore. Un numero intero non negativo compreso tra `1` e `72`. Qualsiasi numero al di fuori di questo intervallo verrà limitato ai valori consentiti. Il valore predefinito è `8`. Se si utilizzano dimensioni del carattere più piccole e si riscontrano problemi nel visualizzare l'intera finestra su un unico schermo, si consiglia di impostare un valore più piccolo. - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| number | No | Android | - -Esempio: - -```jsx - -``` - -### `downloadingMessage`[⬆](#props-index) -Questo è il messaggio visualizzato nel Toast (finestra di dialogo o notifica) durante il download di un file tramite la WebView. Il messaggio predefinito è "Downloading". - -| Tipo | Obbligatorio | Piattaforma | -| ------ | -------- | ------------ | -| string | No | Android | - -### `lackPermissionToDownloadMessage`[⬆](#props-index) -Questo è il messaggio visualizzato nel Toast (finestra di dialogo o notifica) quando la WebView non è in grado di scaricare un file. Il messaggio predefinito è "Cannot download files as permission was denied. Please provide permission to write to storage, in order to download files." (_Impossibile scaricare i file in quanto è stato negato l'accesso. Fornisci il permesso di scrittura sulla memoria per poter scaricare i file._). - -| Tipo | Obbligatorio | Piattaforma | -| ------ | ------------ | ------------ | -| string | No | Android | - -### `allowsProtectedMedia`[⬆](#props-index) -Se impostato su `true`, la WebView può riprodurre contenuti multimediali protetti da DRM (Digital Rights Management). Il valore predefinito è `false`. -⚠️ L'impostazione di questa opzione su `false` non revoca automaticamente il permesso già concesso alla pagina web corrente. Per farlo, è necessario ricaricare la pagina. ⚠️ - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | ------------ | -| boolean | No | Android | - -### `fraudulentWebsiteWarningEnabled`[⬆](#props-index) -Boolean che indica se la WebView mostra avvisi per contenuti sospetti di frode, come malware o tentativi di phishing. Il valore predefinito è `true`. (iOS 13+) - -| Tipo | Obbligatorio | Default | Piattaforma | -| ------- | ------------ | ------- | ------------ | -| boolean | No | true | iOS | - -### `webviewDebuggingEnabled`[⬆](#props-index) -Valore che determina se la WebView può essere debuggata in remoto utilizzando Safari/Chrome. Il valore predefinito è `false`. Supportato su iOS a partire dalla versione 16.4, nelle versioni precedenti il debug è sempre abilitato di default. - -| Tipo | Obbligatorio | Piattaforma | -| ------- | ------------ | -------------- | -| boolean | No | iOS e Android | - -## Methods -### `goForward()`[⬆](#methods-index) - -```javascript -goForward(); -``` - -Vai avanti di una pagina nella cronologia web. - -### `goBack()`[⬆](#methods-index) - -```javascript -goBack(); -``` - -Torna indietro di una pagina nella cronologia web. - -### `reload()`[⬆](#methods-index) - -```javascript -reload(); -``` - -Ricarica la pagina corrente. - -### `stopLoading()`[⬆](#methods-index) - -```javascript -stopLoading(); -``` - -Ferma il caricamento della pagina corrente. - -### `injectJavaScript(str)`[⬆](#methods-index) - -```javascript -injectJavaScript('... javascript string ...'); -``` - -Esegue il codice JavaScript fornito come stringa di testo. - -Per saperne di più leggi la guida [Comunicazione tra JS e Native](Guide.italian.md#comunicazione-tra-js-e-native). - -### `requestFocus()`[⬆](#methods-index) - -```javascript -requestFocus(); -``` - -Richiedi alla WebView di ottenere il focus. (Se lavori su app per TV potresti trovare questa funzione interessante!) - -### `postMessage(str)`[⬆](#methods-index) - -```javascript -postMessage('message'); -``` - -Invia un messaggio alla WebView, tramite l'handler [`onMessage`](Reference.italian.md#onmessage). - -### `clearFormData()`[⬆](#methods-index) - -(solo android) - -```javascript -clearFormData(); -``` - -Se presente, toglie la popup di autocompletamento dal campo di form attualmente selezionato. [developer.android.com reference]() - -### `clearCache(bool)`[⬆](#methods-index) - -(solo android) - -```javascript -clearCache(true) -``` - -Cancella la cache delle risorse. Nota che la cache è specifica dell'applicazione, quindi questa operazione cancellerà la cache per tutte le WebView in uso. [developer.android.com reference]() - -### `clearHistory()`[⬆](#methods-index) - -(solo android) - -```javascript -clearHistory(); -``` - -Indica a questa WebView di cancellare la sua cronologia interna di pagine precedenti/successive.[developer.android.com reference]() - -## Altri Documenti -Fai anche riferimento alla nostra [Guida per Iniziare](Getting-Started.italian.md) e alla [Guida Approfondita](Guide.italian.md). - - -### Traduzioni -Questo file è disponibile nelle seguenti lingue: -- [Inglese](Reference.md) -- [Portoghese brasiliano](Reference.portuguese.md) \ No newline at end of file diff --git a/docs/Reference.md b/docs/Reference.md deleted file mode 100644 index adeefeb76..000000000 --- a/docs/Reference.md +++ /dev/null @@ -1,1754 +0,0 @@ -# React Native WebView API Reference - -This document lays out the current public properties and methods for the React Native WebView. - -## Props Index - -- [`source`](Reference.md#source) -- [`automaticallyAdjustContentInsets`](Reference.md#automaticallyadjustcontentinsets) -- [`automaticallyAdjustsScrollIndicatorInsets`](Reference.md#automaticallyAdjustsScrollIndicatorInsets) -- [`injectedJavaScript`](Reference.md#injectedjavascript) -- [`injectedJavaScriptBeforeContentLoaded`](Reference.md#injectedjavascriptbeforecontentloaded) -- [`injectedJavaScriptForMainFrameOnly`](Reference.md#injectedjavascriptformainframeonly) -- [`injectedJavaScriptBeforeContentLoadedForMainFrameOnly`](Reference.md#injectedjavascriptbeforecontentloadedformainframeonly) -- [`mediaPlaybackRequiresUserAction`](Reference.md#mediaplaybackrequiresuseraction) -- [`nativeConfig`](Reference.md#nativeconfig) -- [`onError`](Reference.md#onerror) -- [`onRenderProcessGone`](Reference.md#onRenderProcessGone) -- [`onLoad`](Reference.md#onload) -- [`onLoadEnd`](Reference.md#onloadend) -- [`onLoadStart`](Reference.md#onloadstart) -- [`onLoadProgress`](Reference.md#onloadprogress) -- [`onHttpError`](Reference.md#onhttperror) -- [`onMessage`](Reference.md#onmessage) -- [`onNavigationStateChange`](Reference.md#onnavigationstatechange) -- [`onOpenWindow`](Reference.md#onopenwindow) -- [`onContentProcessDidTerminate`](Reference.md#oncontentprocessdidterminate) -- [`onScroll`](Reference.md#onscroll) -- [`originWhitelist`](Reference.md#originwhitelist) -- [`renderError`](Reference.md#rendererror) -- [`renderLoading`](Reference.md#renderloading) -- [`scalesPageToFit`](Reference.md#scalespagetofit) -- [`onShouldStartLoadWithRequest`](Reference.md#onshouldstartloadwithrequest) -- [`startInLoadingState`](Reference.md#startinloadingstate) -- [`style`](Reference.md#style) -- [`containerStyle`](Reference.md#containerStyle) -- [`decelerationRate`](Reference.md#decelerationrate) -- [`domStorageEnabled`](Reference.md#domstorageenabled) -- [`javaScriptEnabled`](Reference.md#javascriptenabled) -- [`javaScriptCanOpenWindowsAutomatically`](Reference.md#javascriptcanopenwindowsautomatically) -- [`androidLayerType`](Reference.md#androidLayerType) -- [`mixedContentMode`](Reference.md#mixedcontentmode) -- [`thirdPartyCookiesEnabled`](Reference.md#thirdpartycookiesenabled) -- [`userAgent`](Reference.md#useragent) -- [`applicationNameForUserAgent`](Reference.md#applicationNameForUserAgent) -- [`allowsFullscreenVideo`](Reference.md#allowsfullscreenvideo) -- [`allowsInlineMediaPlayback`](Reference.md#allowsinlinemediaplayback) -- [`allowsAirPlayForMediaPlayback`](Reference.md#allowsAirPlayForMediaPlayback) -- [`bounces`](Reference.md#bounces) -- [`overScrollMode`](Reference.md#overscrollmode) -- [`contentInset`](Reference.md#contentinset) -- [`contentInsetAdjustmentBehavior`](Reference.md#contentInsetAdjustmentBehavior) -- [`contentMode`](Reference.md#contentMode) -- [`dataDetectorTypes`](Reference.md#datadetectortypes) -- [`scrollEnabled`](Reference.md#scrollenabled) -- [`nestedScrollEnabled`](Reference.md#nestedscrollenabled) -- [`setBuiltInZoomControls`](Reference.md#setBuiltInZoomControls) -- [`setDisplayZoomControls`](Reference.md#setDisplayZoomControls) -- [`directionalLockEnabled`](Reference.md#directionalLockEnabled) -- [`geolocationEnabled`](Reference.md#geolocationenabled) -- [`allowFileAccessFromFileURLs`](Reference.md#allowFileAccessFromFileURLs) -- [`allowUniversalAccessFromFileURLs`](Reference.md#allowUniversalAccessFromFileURLs) -- [`allowingReadAccessToURL`](Reference.md#allowingReadAccessToURL) -- [`keyboardDisplayRequiresUserAction`](Reference.md#keyboardDisplayRequiresUserAction) -- [`hideKeyboardAccessoryView`](Reference.md#hidekeyboardaccessoryview) -- [`allowsBackForwardNavigationGestures`](Reference.md#allowsbackforwardnavigationgestures) -- [`incognito`](Reference.md#incognito) -- [`allowFileAccess`](Reference.md#allowFileAccess) -- [`saveFormDataDisabled`](Reference.md#saveFormDataDisabled) -- [`cacheEnabled`](Reference.md#cacheEnabled) -- [`cacheMode`](Reference.md#cacheMode) -- [`pagingEnabled`](Reference.md#pagingEnabled) -- [`allowsLinkPreview`](Reference.md#allowsLinkPreview) -- [`sharedCookiesEnabled`](Reference.md#sharedCookiesEnabled) -- [`textZoom`](Reference.md#textZoom) -- [`pullToRefreshEnabled`](Reference.md#pullToRefreshEnabled) -- [`ignoreSilentHardwareSwitch`](Reference.md#ignoreSilentHardwareSwitch) -- [`onFileDownload`](Reference.md#onFileDownload) -- [`limitsNavigationsToAppBoundDomains`](Reference.md#limitsNavigationsToAppBoundDomains) -- [`textInteractionEnabled`](Reference.md#textInteractionEnabled) -- [`suppressMenuItems`](Reference.md#suppressMenuItems) -- [`mediaCapturePermissionGrantType`](Reference.md#mediaCapturePermissionGrantType) -- [`autoManageStatusBarEnabled`](Reference.md#autoManageStatusBarEnabled) -- [`setSupportMultipleWindows`](Reference.md#setSupportMultipleWindows) -- [`basicAuthCredential`](Reference.md#basicAuthCredential) -- [`enableApplePay`](Reference.md#enableApplePay) -- [`forceDarkOn`](Reference.md#forceDarkOn) -- [`useWebView2`](Reference.md#useWebView2) -- [`minimumFontSize`](Reference.md#minimumFontSize) -- [`downloadingMessage`](Reference.md#downloadingMessage) -- [`lackPermissionToDownloadMessage`](Reference.md#lackPermissionToDownloadMessage) -- [`allowsProtectedMedia`](Reference.md#allowsProtectedMedia) -- [`webviewDebuggingEnabled`](Reference.md#webviewDebuggingEnabled) - -## Methods Index - -- [`goForward`](Reference.md#goforward) -- [`goBack`](Reference.md#goback) -- [`reload`](Reference.md#reload) -- [`stopLoading`](Reference.md#stoploading) -- [`injectJavaScript`](Reference.md#injectjavascriptstr) -- [`clearFormData`](Reference.md#clearFormData) -- [`clearCache`](Reference.md#clearCachebool) -- [`clearHistory`](Reference.md#clearHistory) -- [`requestFocus`](Reference.md#requestFocus) -- [`postMessage`](Reference.md#postmessagestr) - ---- - -# Reference - -## Props - -### `source`[⬆](#props-index) - -Loads static HTML or a URI (with optional headers) in the WebView. Note that static HTML will require setting [`originWhitelist`](Reference.md#originwhitelist) to `["*"]`. - -The object passed to `source` can have either of the following shapes: - -**Load uri** - -- `uri` (string) - The URI to load in the `WebView`. Can be a local or remote file, and can be changed with React state or props to navigate to a new page. -- `method` (string) - The HTTP Method to use. Defaults to GET if not specified. On Android and Windows, the only supported methods are GET and POST. -- `headers` (object) - Additional HTTP headers to send with the request. On Android, this can only be used with GET requests. See the [Guide](Guide.md#setting-custom-headers) for more information on setting custom headers. -- `body` (string) - The HTTP body to send with the request. This must be a valid UTF-8 string, and will be sent exactly as specified, with no additional encoding (e.g. URL-escaping or base64) applied. On Android and Windows, this can only be used with POST requests. - -**Static HTML** - -_Note that using static HTML requires the WebView property [originWhiteList](Reference.md#originWhiteList) to `['*']`. For some content, such as video embeds (e.g. Twitter or Facebook posts with video), the baseUrl needs to be set for the video playback to work_ - -- `html` (string) - A static HTML page to display in the WebView. -- `baseUrl` (string) - The base URL to be used for any relative links in the HTML. This is also used for the origin header with CORS requests made from the WebView. See [Android WebView Docs](https://developer.android.com/reference/android/webkit/WebView#loadDataWithBaseURL) - -| Type | Required | -| ------ | -------- | -| object | No | - ---- - -### `automaticallyAdjustContentInsets`[⬆](#props-index) - -Controls whether to adjust the content inset for web views that are placed behind a navigation bar, tab bar, or toolbar. The default value is `true`. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | iOS | - ---- - -### `automaticallyAdjustsScrollIndicatorInsets`[⬆](#props-index) - -Controls whether to adjust the scroll indicator inset for web views that are placed behind a navigation bar, tab bar, or toolbar. The default value `false`. (iOS 13+) - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | iOS(13+) | - ---- - -### `injectedJavaScript`[⬆](#props-index) - -Set this to provide JavaScript that will be injected into the web page after the document finishes loading, but before other subresources finish loading. - -Make sure the string evaluates to a valid type (`true` works) and doesn't otherwise throw an exception. - -On iOS, see [`WKUserScriptInjectionTimeAtDocumentEnd`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentend?language=objc). Be sure -to set an [`onMessage`](Reference.md#onmessage) handler, even if it's a no-op, or the code will not be run. - -| Type | Required | Platform | -| ------ | -------- | ---------------------------- | -| string | No | iOS, Android, macOS, Windows | - -To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide. - -_Kindly note: Windows does not have [native support for alerts](https://github.com/MicrosoftDocs/winrt-api/blob/docs/windows.ui.xaml.controls/webview.md#use-of-alert), as such any scripts to show an alert will not work._ - -Example: - -Post message a JSON object of `window.location` to be handled by [`onMessage`](Reference.md#onmessage) - -```jsx -const INJECTED_JAVASCRIPT = `(function() { - window.ReactNativeWebView.postMessage(JSON.stringify(window.location)); -})();`; - -; -``` - ---- - -### `injectedJavaScriptBeforeContentLoaded`[⬆](#props-index) - -Set this to provide JavaScript that will be injected into the web page after the document element is created, but before other subresources finish loading. - -Make sure the string evaluates to a valid type (`true` works) and doesn't otherwise throw an exception. - -On iOS, see [`WKUserScriptInjectionTimeAtDocumentStart`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentstart?language=objc) - -> **Warning** -> On Android, this may work, but it is not 100% reliable (see [#1609](https://github.com/react-native-webview/react-native-webview/issues/1609) and [#1099](https://github.com/react-native-webview/react-native-webview/pull/1099)). - -| Type | Required | Platform | -| ------ | -------- | ---------------------------------- | -| string | No | iOS, macOS, Android (experimental) | - -To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide. - -Example: - -Post message a JSON object of `window.location` to be handled by [`onMessage`](Reference.md#onmessage). `window.ReactNativeWebView.postMessage` _will_ be available at this time. - -```jsx -const INJECTED_JAVASCRIPT = `(function() { - window.ReactNativeWebView.postMessage(JSON.stringify(window.location)); -})();`; - -; -``` - ---- - -### `injectedJavaScriptForMainFrameOnly`[⬆](#props-index) - -If `true` (default; mandatory for Android), loads the `injectedJavaScript` only into the main frame. - -If `false`, (only supported on iOS and macOS), loads it into all frames (e.g. iframes). - -| Type | Required | Platform | -| ---- | -------- | ------------------------------------------------- | -| bool | No | iOS and macOS (only `true` supported for Android) | - ---- - -### `injectedJavaScriptBeforeContentLoadedForMainFrameOnly`[⬆](#props-index) - -If `true` (default; mandatory for Android), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame. - -If `false`, (only supported on iOS and macOS), loads it into all frames (e.g. iframes). - -| Type | Required | Platform | -| ---- | -------- | ------------------------------------------------- | -| bool | No | iOS and macOS (only `true` supported for Android) | - ---- - -### `mediaPlaybackRequiresUserAction`[⬆](#props-index) - -Boolean that determines whether HTML5 audio and video requires the user to tap them before they start playing. The default value is `true`. (Android API minimum version 17). - -NOTE: the default `true` value might cause some videos to hang loading on iOS. Setting it to `false` could fix this issue. - -| Type | Required | Platform | -| ---- | -------- | ------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `nativeConfig`[⬆](#props-index) - -Override the native component used to render the WebView. Enables a custom native WebView which uses the same JavaScript as the original WebView. - -The `nativeConfig` prop expects an object with the following keys: - -- `component` (any) -- `props` (object) -- `viewManager` (object) - -| Type | Required | Platform | -| ------ | -------- | ------------------- | -| object | No | iOS, Android, macOS | - ---- - -### `onError`[⬆](#props-index) - -Function that is invoked when the `WebView` load fails. - -| Type | Required | -| -------- | -------- | -| function | No | - -Example: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn('WebView error: ', nativeEvent); - }} -/> -``` - -Function passed to `onError` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -canGoBack -canGoForward -code -description -didFailProvisionalNavigation -domain -loading -target -title -url -``` - -> **_Note_** -> Domain is only used on iOS - -The `syntheticEvent` can be stopped doing its default action by calling `syntheticEvent.preventDefault()`. - ---- - -### `onLoad`[⬆](#props-index) - -Function that is invoked when the `WebView` has finished loading. - -| Type | Required | -| -------- | -------- | -| function | No | - -Example: - -```jsx - { - const { nativeEvent } = syntheticEvent; - this.url = nativeEvent.url; - }} -/> -``` - -Function passed to `onLoad` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadEnd`[⬆](#props-index) - -Function that is invoked when the `WebView` load succeeds or fails. - -| Type | Required | -| -------- | -------- | -| function | No | - -Example: - -```jsx - { - // update component to be aware of loading status - const { nativeEvent } = syntheticEvent; - this.isLoading = nativeEvent.loading; - }} -/> -``` - -Function passed to `onLoadEnd` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadStart`[⬆](#props-index) - -Function that is invoked when the `WebView` starts loading. - -| Type | Required | -| -------- | -------- | -| function | No | - -Example: - -```jsx - { - // update component to be aware of loading status - const { nativeEvent } = syntheticEvent; - this.isLoading = nativeEvent.loading; - }} -/> -``` - -Function passed to `onLoadStart` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadProgress`[⬆](#props-index) - -Function that is invoked when the `WebView` is loading. - -| Type | Required | Platform | -| -------- | -------- | ------------------- | -| function | No | iOS, Android, macOS | - -Example: - -```jsx - { - this.loadingProgress = nativeEvent.progress; - }} -/> -``` - -Function passed to `onLoadProgress` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -canGoBack -canGoForward -loading -progress -target -title -url -``` - ---- - -### `onHttpError`[⬆](#props-index) - -Function that is invoked when the `WebView` receives an http error. - -> **_Note_** -> Android API minimum level 23. - -| Type | Required | -| -------- | -------- | -| function | No | - -Example: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn( - 'WebView received error status code: ', - nativeEvent.statusCode, - ); - }} -/> -``` - -Function passed to `onHttpError` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -canGoBack -canGoForward -description -loading -statusCode -target -title -url -``` - -> **_Note_** -> Description is only used on Android - ---- - -### `onRenderProcessGone`[⬆](#props-index) - -Function that is invoked when the `WebView` process crashes or is killed by the OS on Android. - -> **_Note_** -> Android API minimum level 26. Android Only - -| Type | Required | -| -------- | -------- | -| function | No | - -Example: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn( - 'WebView Crashed: ', - nativeEvent.didCrash, - ); - }} -/> -``` - -Function passed to `onRenderProcessGone` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -didCrash -``` ---- - -### `onMessage`[⬆](#props-index) - -Function that is invoked when the webview calls `window.ReactNativeWebView.postMessage`. Setting this property will inject this global into your webview. - -`window.ReactNativeWebView.postMessage` accepts one argument, `data`, which will be available on the event object, `event.nativeEvent.data`. `data` must be a string. - -| Type | Required | -| -------- | -------- | -| function | No | - -To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide. - ---- - -### `onNavigationStateChange`[⬆](#props-index) - -Function that is invoked when the `WebView` loading starts or ends. - -| Type | Required | -| -------- | -------- | -| function | No | - -Example: - -```jsx - { - // Keep track of going back navigation within component - this.canGoBack = navState.canGoBack; - }} -/> -``` - -The `navState` object includes these properties: - -``` -canGoBack -canGoForward -loading -navigationType (iOS only) -target -title -url -``` - ---- - -### `onOpenWindow`[⬆](#props-index) - -Function that is invoked when the `WebView` should open a new window. - -This happens when the JS calls `window.open('http://someurl', '_blank')` or when the user clicks on a `` link. - -| Type | Required | -| -------- | -------- | -| function | No | - -Example: - -```jsx - { - const { nativeEvent } = syntheticEvent; - const { targetUrl } = nativeEvent - console.log('Intercepted OpenWindow for', targetUrl) - }} -/> -``` - -Function passed to onOpenWindow is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -targetUrl -``` - ---- - -### `onContentProcessDidTerminate`[⬆](#props-index) - -Function that is invoked when the `WebView` content process is terminated. - -| Type | Required | Platform | -| -------- | -------- | ----------------------- | -| function | No | iOS and macOS WKWebView | - -iOS Web views use a separate process to render and manage web content. WebKit calls this method when the process for the specified web view terminates for any reason. -The reason is not necessarily a crash. For instance, since iOS WebViews are not included in the total RAM of the app, they can be terminated independently of the app to liberate memory for new apps the user is opening. It's not unexpected to have WebViews get terminated after a while in the background. - -Example: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn('Content process terminated, reloading', nativeEvent); - this.refs.webview.reload(); - }} -/> -``` - -Function passed to `onContentProcessDidTerminate` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onScroll`[⬆](#props-index) - -Function that is invoked when the scroll event is fired in the `WebView`. - -| Type | Required | Platform | -| -------- | -------- | ---------------------------- | -| function | No | iOS, macOS, Android, Windows | - -Example: - -```jsx - { - const { contentOffset } = syntheticEvent.nativeEvent - console.table(contentOffset) - }} -/> -``` - -Function passed to `onScroll` is called with a SyntheticEvent wrapping a nativeEvent with these properties: - -``` -contentInset -contentOffset -contentSize -layoutMeasurement -velocity -zoomScale -``` - ---- - -### `originWhitelist`[⬆](#props-index) - -List of origin strings to allow being navigated to. The strings allow wildcards and get matched against _just_ the origin (not the full URL). If the user taps to navigate to a new page but the new page is not in this whitelist, the URL will be handled by the OS. The default whitelisted origins are "http://*" and "https://*". - -| Type | Required | Platform | -| ---------------- | -------- | ------------------- | -| array of strings | No | iOS, Android, macOS | - -Example: - -```jsx -//only allow URIs that begin with https:// or git:// - -``` - ---- - -### `renderError`[⬆](#props-index) - -Function that returns a view to show if there's an error. - -| Type | Required | Platform | -| -------- | -------- | ------------------- | -| function | No | iOS, Android, macOS | - -Example: - -```jsx - } -/> -``` - -The function passed to `renderError` will be called with the name of the error - ---- - -### `renderLoading`[⬆](#props-index) - -Function that returns a loading indicator. The `startInLoadingState` prop must be set to `true` in order to use this prop. - -| Type | Required | Platform | -| -------- | -------- | ------------------- | -| function | No | iOS, Android, macOS | - -Example: - -```jsx - } -/> -``` - ---- - -### `scalesPageToFit`[⬆](#props-index) - -Boolean that controls whether the web content is scaled to fit the view and enables the user to change the scale. The default value is `true`. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | Android | - ---- - -### `onShouldStartLoadWithRequest`[⬆](#props-index) - -Function that allows custom handling of any web view requests. Return `true` from the function to continue loading the request and `false` to stop loading. - -On Android, is not called on the first load. - -| Type | Required | Platform | -| -------- | -------- | ------------------- | -| function | No | iOS, Android, macOS | - -Example: - -```jsx - { - // Only allow navigating within this website - return request.url.startsWith('https://reactnative.dev'); - }} -/> -``` - -The `request` object includes these properties: - -``` -title -url -loading -target -canGoBack -canGoForward -lockIdentifier -mainDocumentURL (iOS only) -navigationType (iOS only) -isTopFrame (iOS only) -hasTargetFrame (iOS only) -``` - -The `hasTargetFrame` prop is a boolean that is `false` when the navigation targets a new window or tab, otherwise it should be `true` ([more info](https://developer.apple.com/documentation/webkit/wknavigationaction/1401918-targetframe)). Note that this prop should always be `true` when `onOpenWindow` event is registered on the WebView because the `false` case is intercepted by this event. - ---- - -### `startInLoadingState`[⬆](#props-index) - -Boolean value that forces the `WebView` to show the loading view on the first load. This prop must be set to `true` in order for the `renderLoading` prop to work. - -| Type | Required | Platform | -| ---- | -------- | ------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `style`[⬆](#props-index) - -A style object that allow you to customize the `WebView` style. Please note that there are default styles (example: you need to add `flex: 0` to the style if you want to use `height` property). - -| Type | Required | -| ----- | -------- | -| style | No | - -Example: - -```jsx - -``` - ---- - -### `containerStyle`[⬆](#props-index) - -A style object that allow you to customize the `WebView` container style. Please note that there are default styles (example: you need to add `flex: 0` to the style if you want to use `height` property). - -| Type | Required | -| ----- | -------- | -| style | No | - -Example: - -```jsx - -``` - ---- - -### `decelerationRate`[⬆](#props-index) - -A floating-point number that determines how quickly the scroll view decelerates after the user lifts their finger. You may also use the string shortcuts `"normal"` and `"fast"` which match the underlying iOS settings for `UIScrollViewDecelerationRateNormal` and `UIScrollViewDecelerationRateFast` respectively: - -- normal: 0.998 -- fast: 0.99 (the default for iOS web view) - -| Type | Required | Platform | -| ------ | -------- | -------- | -| number | No | iOS | - ---- - -### `domStorageEnabled`[⬆](#props-index) - -Boolean value to control whether DOM Storage is enabled. Used only in Android. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | Android | - ---- - -### `javaScriptEnabled`[⬆](#props-index) - -Boolean value to enable JavaScript in the `WebView`. The default value is `true`. - -| Type | Required | -| ---- | -------- | -| bool | No | - ---- - -### `javaScriptCanOpenWindowsAutomatically`[⬆](#props-index) - -A Boolean value indicating whether JavaScript can open windows without user interaction. The default value is `false`. - -| Type | Required | -| ---- | -------- | -| bool | No | - ---- - -### `androidLayerType`[⬆](#props-index) - -Specifies the layer type. - -Possible values for `androidLayerType` are: - -- `none` (default) - The view does not have a layer. -- `software` - The view has a software layer. A software layer is backed by a bitmap and causes the view to be rendered using Android's software rendering pipeline, even if hardware acceleration is enabled. -- `hardware` - The view has a hardware layer. A hardware layer is backed by a hardware specific texture and causes the view to be rendered using Android's hardware rendering pipeline, but only if hardware acceleration is turned on for the view hierarchy. - - -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | Android | - ---- - -### `mixedContentMode`[⬆](#props-index) - -Specifies the mixed content mode. i.e WebView will allow a secure origin to load content from any other origin. - -Possible values for `mixedContentMode` are: - -- `never` (default) - WebView will not allow a secure origin to load content from an insecure origin. -- `always` - WebView will allow a secure origin to load content from any other origin, even if that origin is insecure. -- `compatibility` - WebView will attempt to be compatible with the approach of a modern web browser with regard to mixed content. - -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | Android | - ---- - -### `thirdPartyCookiesEnabled`[⬆](#props-index) - -Boolean value to enable third party cookies in the `WebView`. Used on Android Lollipop and above only as third party cookies are enabled by default on Android Kitkat and below and on iOS. The default value is `true`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies) - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | Android | - ---- - -### `userAgent`[⬆](#props-index) - -Sets the user-agent for the `WebView`. - -| Type | Required | Platform | -| ------ | -------- | ------------------- | -| string | No | iOS, Android, macOS | - ---- - -### `applicationNameForUserAgent`[⬆](#props-index) - -Append to the existing user-agent. Setting `userAgent` will override this. - -| Type | Required | Platform | -| ------ | -------- | ------------------- | -| string | No | iOS, Android, macOS | - -```jsx - -// Resulting User-Agent will look like: -// Mozilla/5.0 (Linux; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.021; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36 DemoApp/1.1.0 -// Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DemoApp/1.1.0 -``` - -### `allowsFullscreenVideo`[⬆](#props-index) - -Boolean that determines whether videos are allowed to be played in fullscreen. The default value is `false`. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | Android | - ---- - -### `allowsInlineMediaPlayback`[⬆](#props-index) - -Boolean that determines whether HTML5 videos play inline or use the native full-screen controller. The default value is `false`. - -> **NOTE** -> -> In order for video to play inline, not only does this property need to be set to `true`, but the video element in the HTML document must also include the `webkit-playsinline` attribute. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | iOS | - ---- -### `allowsAirPlayForMediaPlayback`[⬆](#props-index) - -A Boolean value indicating whether AirPlay is allowed. The default value is `false`. - -| Type | Required | Platform | -| ------- | -------- | ------------- | -| boolean | No | iOS and macOS | - ---- - -### `bounces`[⬆](#props-index) - -Boolean value that determines whether the web view bounces when it reaches the edge of the content. The default value is `true`. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | iOS | - ---- - -### `overScrollMode`[⬆](#props-index) - -Specifies the over scroll mode. - -Possible values for `overScrollMode` are: - -- `always` (default) - Always allow a user to over-scroll this view, provided it is a view that can scroll. -- `content` - Allow a user to over-scroll this view only if the content is large enough to meaningfully scroll, provided it is a view that can scroll. -- `never` - Never allow a user to over-scroll this view. - -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | Android | - ---- - -### `contentInset`[⬆](#props-index) - -The amount by which the web view content is inset from the edges of the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}. - -| Type | Required | Platform | -| ------------------------------------------------------------------ | -------- | -------- | -| object: {top: number, left: number, bottom: number, right: number} | No | iOS | - ---- - -### `contentInsetAdjustmentBehavior`[⬆](#props-index) - -This property specifies how the safe area insets are used to modify the content area of the scroll view. The default value of this property is "never". Available on iOS 11 and later. Defaults to `never`. - -Possible values: - -- `automatic` -- `scrollableAxes` -- `never` -- `always` - -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | iOS | - ---- - -### `contentMode`[⬆](#props-index) - -Controls the type of content to load. Available on iOS 13 and later. Defaults to `recommended`, which loads mobile content on iPhone & iPad Mini but desktop content on larger iPads. - -See [Introducing Desktop-class Browsing on iPad](https://developer.apple.com/videos/play/wwdc2019/203/) for more. - -Possible values: - -- `recommended` -- `mobile` -- `desktop` - -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | iOS | - ---- - -### `dataDetectorTypes`[⬆](#props-index) - -Determines the types of data converted to clickable URLs in the web view's content. By default only phone numbers are detected. - -You can provide one type or an array of many types. - -Possible values for `dataDetectorTypes` are: - -- `phoneNumber` -- `link` -- `address` -- `calendarEvent` -- `none` -- `all` -- `trackingNumber` -- `flightNumber` -- `lookupSuggestion` - -| Type | Required | Platform | -| ---------------- | -------- | -------- | -| string, or array | No | iOS | - ---- - -### `scrollEnabled`[⬆](#props-index) - -Boolean value that determines whether scrolling is enabled in the `WebView`. The default value is `true`. Setting this to `false` will prevent the webview from moving the document body when the keyboard appears over an input. - -| Type | Required | Platform | -| ---- | -------- | ------------- | -| bool | No | iOS and macOS | - ---- - -### `nestedScrollEnabled`[⬆](#props-index) - -Boolean value that determines whether scrolling is possible in the `WebView` when used inside a `ScrollView` on Android. The default value is `false`. - -Setting this to `true` will prevent the `ScrollView` to scroll when scrolling from inside the `WebView`. - -| Type | Required | Platform | -| ---- | -------- | ------------- | -| bool | No | Android | - ---- - -### `setBuiltInZoomControls`[⬆](#props-index) - -Sets whether the WebView should use its built-in zoom mechanisms. The default value is `true`. Setting this to `false` will prevent the use of a pinch gesture to control zooming. - -| Type | Required | Platform | -| ---- | -------- | ------------- | -| bool | No | Android | - ---- - -### `setDisplayZoomControls`[⬆](#props-index) - -Sets whether the WebView should display on-screen zoom controls when using the built-in zoom mechanisms (see `setBuiltInZoomControls`). The default value is `false`. - -| Type | Required | Platform | -| ---- | -------- | ------------- | -| bool | No | Android | - ---- - -### `directionalLockEnabled`[⬆](#props-index) - -A Boolean value that determines whether scrolling is disabled in a particular direction. -The default value is `true`. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | iOS | - ---- - -### `showsHorizontalScrollIndicator`[⬆](#props-index) - -Boolean value that determines whether a horizontal scroll indicator is shown in the `WebView`. The default value is `true`. - -| Type | Required | Platform | -| ---- | -------- | ------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `showsVerticalScrollIndicator`[⬆](#props-index) - -Boolean value that determines whether a vertical scroll indicator is shown in the `WebView`. The default value is `true`. - -| Type | Required | Platform | -| ---- | -------- | ------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `geolocationEnabled`[⬆](#props-index) - -Set whether Geolocation is enabled in the `WebView`. The default value is `false`. Used only in Android. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | Android | - ---- - -### `allowFileAccessFromFileURLs`[⬆](#props-index) - -Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. The default value is `false`. - -| Type | Required | Platform | -| ---- | -------- | ------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `allowUniversalAccessFromFileURLs`[⬆](#props-index) - -Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from any origin. Including accessing content from other file scheme URLs. The default value is `false`. - -| Type | Required | Platform | -| ---- | -------- | -------------------- | -| bool | No | iOS, Android, macOS | - ---- - -### `allowingReadAccessToURL`[⬆](#props-index) - -A String value that indicates which URLs the WebView's file can then reference in scripts, AJAX requests, and CSS imports. This is only used in for WebViews that are loaded with a `source.uri` set to a `'file://'` URL. If not provided, the default is to only allow read access to the URL provided in `source.uri` itself. - -| Type | Required | Platform | -| ------ | -------- | ------------- | -| string | No | iOS and macOS | - ---- - -### `keyboardDisplayRequiresUserAction`[⬆](#props-index) - -If `false`, web content can programmatically display the keyboard. The default value is `true`. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS | - ---- - -### `hideKeyboardAccessoryView`[⬆](#props-index) - -If `true`, this will hide the keyboard accessory view (< > and Done). - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS | - ---- - -### `allowsBackForwardNavigationGestures`[⬆](#props-index) - -If `true`, this will be able horizontal swipe gestures. The default value is `false`. - -| Type | Required | Platform | -| ------- | -------- | ------------- | -| boolean | No | iOS and macOS | - ---- - -### `incognito`[⬆](#props-index) - -Does not store any data within the lifetime of the WebView. - -| Type | Required | Platform | -| ------- | -------- | ------------------- | -| boolean | No | iOS, Android, macOS | - ---- - -### `allowFileAccess`[⬆](#props-index) - -If `true`, this will allow access to the file system via `file://` URI's. The default value is `false`. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | Android | - ---- - -### `saveFormDataDisabled`[⬆](#props-index) - -Sets whether the WebView should disable saving form data. The default value is `false`. This function does not have any effect from Android API level 26 onwards as there is an Autofill feature which stores form data. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | Android | - ---- - -### `cacheEnabled`[⬆](#props-index) - -Sets whether WebView should use browser caching. - -| Type | Required | Default | Platform | -| ------- | -------- | ------- | ------------------- | -| boolean | No | true | iOS, Android, macOS | - ---- - -### `cacheMode`[⬆](#props-index) - -Overrides the way the cache is used. The way the cache is used is based on the navigation type. For a normal page load, the cache is checked and content is re-validated as needed. When navigating back, content is not revalidated, instead the content is just retrieved from the cache. This property allows the client to override this behavior. - -Possible values are: - -- `LOAD_DEFAULT` - Default cache usage mode. If the navigation type doesn't impose any specific behavior, use cached resources when they are available and not expired, otherwise load resources from the network. -- `LOAD_CACHE_ELSE_NETWORK` - Use cached resources when they are available, even if they have expired. Otherwise load resources from the network. -- `LOAD_NO_CACHE` - Don't use the cache, load from the network. -- `LOAD_CACHE_ONLY` - Don't use the network, load from the cache. - -| Type | Required | Default | Platform | -| ------ | -------- | ------------ | -------- | -| string | No | LOAD_DEFAULT | Android | - ---- - -### `pagingEnabled`[⬆](#props-index) - -If the value of this property is `true`, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls. The default value is `false`. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS | - ---- - -### `allowsLinkPreview`[⬆](#props-index) - -A Boolean value that determines whether pressing on a link displays a preview of the destination for the link. In iOS this property is available on devices that support 3D Touch. In iOS 10 and later, the default value is `true`; before that, the default value is `false`. - -| Type | Required | Platform | -| ------- | -------- | ------------- | -| boolean | No | iOS and macOS | - ---- - -### `sharedCookiesEnabled`[⬆](#props-index) - -Set `true` if shared cookies from `[NSHTTPCookieStorage sharedHTTPCookieStorage]` should be used for every load request in the WebView. The default value is `false`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies) - -| Type | Required | Platform | -| ------- | -------- | ------------- | -| boolean | No | iOS and macOS | - ---- - -### `textZoom`[⬆](#props-index) - -If the user has set a custom font size in the Android system, an undesirable scale of the site interface in WebView occurs. - -When setting the standard textZoom (100) parameter size, this undesirable effect disappears. - -| Type | Required | Platform | -| ------ | -------- | -------- | -| number | No | Android | - -Example: - -```jsx - -``` - ---- - -### `pullToRefreshEnabled`[⬆](#props-index) - -Boolean value that determines whether a pull to refresh gesture is available in the `WebView`. The default value is `false`. If `true`, sets `bounces` automatically to `true`. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS | - -### `ignoreSilentHardwareSwitch`[⬆](#props-index) - -(ios only) - -When set to `true` the hardware silent switch is ignored. Default: `false` - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS | - -### `onFileDownload`[⬆](#props-index) -This property is iOS-only. - -Function that is invoked when the client needs to download a file. - -iOS 13+ only: If the webview navigates to a URL that results in an HTTP -response with a Content-Disposition header 'attachment...', then -this will be called. - -iOS 8+: If the MIME type indicates that the content is not renderable by the -webview, that will also cause this to be called. On iOS versions before 13, -this is the only condition that will cause this function to be called. - -The application will need to provide its own code to actually download -the file. - -If not provided, the default is to let the webview try to render the file. - -Example: - -```jsx - { - // You use downloadUrl which is a string to download files however you want. - }} -/> -``` - -| Type | Required | Platform | -| -------- | -------- | -------- | -| function | No | iOS | - ---- - -### `limitsNavigationsToAppBoundDomains`[⬆](#props-index) - -If `true` indicates to WebKit that a WKWebView will only navigate to app-bound domains. Only applicable for iOS 14 or greater. - -Once set, any attempt to navigate away from an app-bound domain will fail with the error “App-bound domain failure.” -Applications can specify up to 10 “app-bound” domains using a new Info.plist key `WKAppBoundDomains`. For more information see [App-Bound Domains](https://webkit.org/blog/10882/app-bound-domains/). - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS | - -Example: - -```jsx - -``` - ---- - -### `textInteractionEnabled`[⬆](#props-index) - -If false indicates to WebKit that a WKWebView will not interact with text, thus not showing a text selection loop. Only applicable for iOS 14.5 or greater. - -Defaults to `true`. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS | - -Example: - -```jsx - -``` - ---- - -### `suppressMenuItems`[⬆](#props-index) - -Allows to suppress menu item from the default context menu. - -Possible values are: - -- `cut` -- `copy` -- `paste` -- `delete` -- `select` -- `selectAll` -- `replace` -- `lookup` -- `translate` -- `bold` -- `italic` -- `underline` -- `share` - -| Type | Required | Default | Platform | -| ---------------- | -------- | ------------ | -------- | -| array of strings | No | [] | iOS | - -### `mediaCapturePermissionGrantType`[⬆](#props-index) - -This property specifies how to handle media capture permission requests. Defaults to `prompt`, resulting in the user being prompted repeatedly. Available on iOS 15 and later. - -Possible values: - -- `grantIfSameHostElsePrompt`: If the security origin's host of the permission request equals the host of the WebView's current URL, the permission is granted if it has been granted before. Otherwise, the user gets prompted. -- `grantIfSameHostElseDeny`: If the security origin's host of the permission request equals the host of the WebView's current URL, the permission is granted if it has been granted before. Otherwise, it gets denied. -- `deny` -- `grant`: The permission is granted if it has been granted before. -- `prompt` - -Note that a grant may still result in a prompt, for example if the user has never been prompted for the permission before. - -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | iOS | - -Example: - -```jsx - -``` - ---- - -### `autoManageStatusBarEnabled`[⬆](#props-index) - -If set to `true`, the status bar will be automatically hidden/shown by WebView, specifically when full screen video is being watched. If `false`, WebView will not manage the status bar at all. The default value is `true`. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS | - -Example: - -```jsx - -``` - -### `setSupportMultipleWindows`[⬆](#props-index) - -Sets whether the WebView supports multiple windows. See [Android documentation]('https://developer.android.com/reference/android/webkit/WebSettings#setSupportMultipleWindows(boolean)') for more information. -Setting this to `false` can expose the application to this [vulnerability](https://alesandroortiz.com/articles/uxss-android-webview-cve-2020-6506/) allowing a malicious iframe to escape into the top layer DOM. - -| Type | Required | Default | Platform | -| ------- | -------- | ------- | -------- | -| boolean | No | true | Android | - -Example: - -```javascript - -``` - -### `enableApplePay`[⬆](#props-index) - -A Boolean value which, when set to `true`, WebView will be rendered with Apple Pay support. Once set, websites will be able to invoke Apple Pay from React Native Webview. -This comes with a cost features like [`injectJavaScript`](Reference.md#injectjavascriptstr), html5 History, [`sharedCookiesEnabled`](Reference.md#sharedCookiesEnabled), [`injectedJavaScript`](Reference.md#injectedjavascript), [`injectedJavaScriptBeforeContentLoaded`](Reference.md#injectedjavascriptbeforecontentloaded) will not work See [Apple Pay Release Note](https://developer.apple.com/documentation/safari-release-notes/safari-13-release-notes#Payment-Request-API). - -If you are required to send message to App , webpage has to explicitly call webkit message handler and receive it on `onMessage` handler on react native side -```javascript -window.webkit.messageHandlers.ReactNativeWebView.postMessage("hello apple pay") -``` - -| Type | Required | Default | Platform | -| ------- | -------- | ------- | -------- | -| boolean | No | false | iOS | - -Example: - -```javascript - -``` - -### `forceDarkOn`[⬆](#props-index) - -Configuring Dark Theme - -*NOTE* : The force dark setting is not persistent. You must call the static method every time your app process is started. - -*NOTE* : The change from day<->night mode is a configuration change so by default the activity will be restarted and pickup the new values to apply the theme. Take care when overriding this default behavior to ensure this method is still called when changes are made. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | Android | - -Example: - -```javascript - -``` - -### `menuItems`[⬆](#props-index) - -An array of custom menu item objects that will be shown when selecting text. An empty array will suppress the menu. Used in tandem with `onCustomMenuSelection` - -| Type | Required | Platform | -| ------------------------------------------------------------------ | -------- | -------- | -| array of objects: {label: string, key: string} | No | iOS, Android | - -Example: - -```jsx - -``` - -### `onCustomMenuSelection`[⬆](#props-index) - -Function called when a custom menu item is selected. It receives a Native event, which includes three custom keys: `label`, `key` and `selectedText`. - -| Type | Required | Platform | -| ------------------------------------------------------------------ | -------- | -------- | -| function | No | iOS, Android | - -```jsx - { - const { label } = webViewEvent.nativeEvent; // The name of the menu item, i.e. 'Tweet' - const { key } = webViewEvent.nativeEvent; // The key of the menu item, i.e. 'tweet' - const { selectedText } = webViewEvent.nativeEvent; // Text highlighted - }} -/> -``` - -### `basicAuthCredential`[⬆](#props-index) - -An object that specifies the credentials of a user to be used for basic authentication. - -- `username` (string) - A username used for basic authentication. -- `password` (string) - A password used for basic authentication. - -| Type | Required | -| ------ | -------- | -| object | No | - -### `useWebView2`[⬆](#props-index) - -Use WinUI WebView2 control instead of WebView control as the native webview. The WebView2 control is a WinUI control that renders web content using the Microsoft Edge (Chromium) rendering engine. Option can be toggled at runtime and supports Fast Refresh. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | Windows | - -Example: - -```jsx - -``` - -### `minimumFontSize`[⬆](#props-index) - -Android enforces a minimum font size based on this value. A non-negative integer between 1 and 72. Any number outside the specified range will be pinned. Default value is 8. If you are using smaller font sizes and are having trouble fitting the whole window onto one screen, try setting this to a smaller value. - -| Type | Required | Platform | -| ------ | -------- | -------- | -| number | No | Android | - -Example: - -```jsx - -``` - -### `downloadingMessage`[⬆](#props-index) - -This is the message that is shown in the Toast when downloading a file via WebView. Default message is "Downloading". - -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | Android | - -### `lackPermissionToDownloadMessage`[⬆](#props-index) - -This is the message that is shown in the Toast when the webview is unable to download a file. Default message is "Cannot download files as permission was denied. Please provide permission to write to storage, in order to download files.". - -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | Android | - -### `allowsProtectedMedia`[⬆](#props-index) - -Whether or not the Webview can play media protected by DRM. Default is `false`. -⚠️ Setting this to `false` won't revoke the permission already granted to the current webpage. In order to do so, you'd have to reload the page as well. ⚠️ - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | Android | - -### `fraudulentWebsiteWarningEnabled`[⬆](#props-index) - -A Boolean value that indicates whether the web view shows warnings for suspected fraudulent content, such as malware or phishing attempts. The default value is `true`. (iOS 13+) - -| Type | Required | Default | Platform | -| ------- | -------- | ------- | -------- | -| boolean | No | true | iOS | - -### `webviewDebuggingEnabled`[⬆](#props-index) - -Whether or not the webview can be debugged remotely using Safari / Chrome. -Default is `false`. Supported on iOS as of 16.4, previous versions always allow debugging by default. - -| Type | Required | Platform | -| ------- | -------- | -------- | -| boolean | No | iOS & Android | - -## Methods - -### `goForward()`[⬆](#methods-index) - -```javascript -goForward(); -``` - -Go forward one page in the web view's history. - -### `goBack()`[⬆](#methods-index) - -```javascript -goBack(); -``` - -Go back one page in the web view's history. - -### `reload()`[⬆](#methods-index) - -```javascript -reload(); -``` - -Reloads the current page. - -### `stopLoading()`[⬆](#methods-index) - -```javascript -stopLoading(); -``` - -Stop loading the current page. - -### `injectJavaScript(str)`[⬆](#methods-index) - -```javascript -injectJavaScript('... javascript string ...'); -``` - -Executes the JavaScript string. - -To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide. - -### `requestFocus()`[⬆](#methods-index) - -```javascript -requestFocus(); -``` - -Request the webView to ask for focus. (People working on TV apps might want having a look at this!) - -### `postMessage(str)`[⬆](#methods-index) - -```javascript -postMessage('message'); -``` - -Post a message to WebView, handled by [`onMessage`](Reference.md#onmessage). - -### `clearFormData()`[⬆](#methods-index) - -(android only) - -```javascript -clearFormData(); -``` - -Removes the autocomplete popup from the currently focused form field, if present. [developer.android.com reference]() - -### `clearCache(bool)`[⬆](#methods-index) - -(android only) - -```javascript -clearCache(true) -``` - -Clears the resource cache. Note that the cache is per-application, so this will clear the cache for all WebViews used. [developer.android.com reference]() - -### `clearHistory()`[⬆](#methods-index) - -(android only) - -```javascript -clearHistory(); -``` - -Tells this WebView to clear its internal back/forward list. [developer.android.com reference]() - -## Other Docs - -Also check out our [Getting Started Guide](Getting-Started.md) and [In-Depth Guide](Guide.md). - -## Translations - -This file is available in: - -- [Brazilian portuguese](Reference.portuguese.md) -- [Italian](Reference.italian.md) diff --git a/docs/Reference.portuguese.md b/docs/Reference.portuguese.md deleted file mode 100644 index ebeb2cb66..000000000 --- a/docs/Reference.portuguese.md +++ /dev/null @@ -1,1624 +0,0 @@ -# React Native WebView API Referência - -Este documento apresenta as propriedades e métodos públicos para o React Native WebView. - -## Props Index - -- [`source`](Reference.portuguese.md#source) -- [`automaticallyAdjustContentInsets`](Reference.portuguese.md#automaticallyadjustcontentinsets) -- [`automaticallyAdjustsScrollIndicatorInsets`](Reference.portuguese.md#automaticallyAdjustsScrollIndicatorInsets) -- [`injectedJavaScript`](Reference.portuguese.md#injectedjavascript) -- [`injectedJavaScriptBeforeContentLoaded`](Reference.portuguese.md#injectedjavascriptbeforecontentloaded) -- [`injectedJavaScriptForMainFrameOnly`](Reference.portuguese.md#injectedjavascriptformainframeonly) -- [`injectedJavaScriptBeforeContentLoadedForMainFrameOnly`](Reference.portuguese.md#injectedjavascriptbeforecontentloadedformainframeonly) -- [`mediaPlaybackRequiresUserAction`](Reference.portuguese.md#mediaplaybackrequiresuseraction) -- [`nativeConfig`](Reference.portuguese.md#nativeconfig) -- [`onError`](Reference.portuguese.md#onerror) -- [`onRenderProcessGone`](Reference.portuguese.md#onRenderProcessGone) -- [`onLoad`](Reference.portuguese.md#onload) -- [`onLoadEnd`](Reference.portuguese.md#onloadend) -- [`onLoadStart`](Reference.portuguese.md#onloadstart) -- [`onLoadProgress`](Reference.portuguese.md#onloadprogress) -- [`onHttpError`](Reference.portuguese.md#onhttperror) -- [`onMessage`](Reference.portuguese.md#onmessage) -- [`onNavigationStateChange`](Reference.portuguese.md#onnavigationstatechange) -- [`onContentProcessDidTerminate`](Reference.portuguese.md#oncontentprocessdidterminate) -- [`onScroll`](Reference.portuguese.md#onscroll) -- [`originWhitelist`](Reference.portuguese.md#originwhitelist) -- [`renderError`](Reference.portuguese.md#rendererror) -- [`renderLoading`](Reference.portuguese.md#renderloading) -- [`scalesPageToFit`](Reference.portuguese.md#scalespagetofit) -- [`onShouldStartLoadWithRequest`](Reference.portuguese.md#onshouldstartloadwithrequest) -- [`startInLoadingState`](Reference.portuguese.md#startinloadingstate) -- [`style`](Reference.portuguese.md#style) -- [`containerStyle`](Reference.portuguese.md#containerStyle) -- [`decelerationRate`](Reference.portuguese.md#decelerationrate) -- [`domStorageEnabled`](Reference.portuguese.md#domstorageenabled) -- [`javaScriptEnabled`](Reference.portuguese.md#javascriptenabled) -- [`javaScriptCanOpenWindowsAutomatically`](Reference.portuguese.md#javascriptcanopenwindowsautomatically) -- [`androidLayerType`](Reference.portuguese.md#androidLayerType) -- [`mixedContentMode`](Reference.portuguese.md#mixedcontentmode) -- [`thirdPartyCookiesEnabled`](Reference.portuguese.md#thirdpartycookiesenabled) -- [`userAgent`](Reference.portuguese.md#useragent) -- [`applicationNameForUserAgent`](Reference.portuguese.md#applicationNameForUserAgent) -- [`allowsFullscreenVideo`](Reference.portuguese.md#allowsfullscreenvideo) -- [`allowsInlineMediaPlayback`](Reference.portuguese.md#allowsinlinemediaplayback) -- [`allowsAirPlayForMediaPlayback`](Reference.portuguese.md#allowsAirPlayForMediaPlayback) -- [`bounces`](Reference.portuguese.md#bounces) -- [`overScrollMode`](Reference.portuguese.md#overscrollmode) -- [`contentInset`](Reference.portuguese.md#contentinset) -- [`contentInsetAdjustmentBehavior`](Reference.portuguese.md#contentInsetAdjustmentBehavior) -- [`contentMode`](Reference.portuguese.md#contentMode) -- [`dataDetectorTypes`](Reference.portuguese.md#datadetectortypes) -- [`scrollEnabled`](Reference.portuguese.md#scrollenabled) -- [`nestedScrollEnabled`](Reference.portuguese.md#nestedscrollenabled) -- [`setBuiltInZoomControls`](Reference.portuguese.md#setBuiltInZoomControls) -- [`setDisplayZoomControls`](Reference.portuguese.md#setDisplayZoomControls) -- [`directionalLockEnabled`](Reference.portuguese.md#directionalLockEnabled) -- [`geolocationEnabled`](Reference.portuguese.md#geolocationenabled) -- [`allowFileAccessFromFileURLs`](Reference.portuguese.md#allowFileAccessFromFileURLs) -- [`allowUniversalAccessFromFileURLs`](Reference.portuguese.md#allowUniversalAccessFromFileURLs) -- [`allowingReadAccessToURL`](Reference.portuguese.md#allowingReadAccessToURL) -- [`keyboardDisplayRequiresUserAction`](Reference.portuguese.md#keyboardDisplayRequiresUserAction) -- [`hideKeyboardAccessoryView`](Reference.portuguese.md#hidekeyboardaccessoryview) -- [`allowsBackForwardNavigationGestures`](Reference.portuguese.md#allowsbackforwardnavigationgestures) -- [`incognito`](Reference.portuguese.md#incognito) -- [`allowFileAccess`](Reference.portuguese.md#allowFileAccess) -- [`saveFormDataDisabled`](Reference.portuguese.md#saveFormDataDisabled) -- [`cacheEnabled`](Reference.portuguese.md#cacheEnabled) -- [`cacheMode`](Reference.portuguese.md#cacheMode) -- [`pagingEnabled`](Reference.portuguese.md#pagingEnabled) -- [`allowsLinkPreview`](Reference.portuguese.md#allowsLinkPreview) -- [`sharedCookiesEnabled`](Reference.portuguese.md#sharedCookiesEnabled) -- [`textZoom`](Reference.portuguese.md#textZoom) -- [`pullToRefreshEnabled`](Reference.portuguese.md#pullToRefreshEnabled) -- [`ignoreSilentHardwareSwitch`](Reference.portuguese.md#ignoreSilentHardwareSwitch) -- [`onFileDownload`](Reference.portuguese.md#onFileDownload) -- [`limitsNavigationsToAppBoundDomains`](Reference.portuguese.md#limitsNavigationsToAppBoundDomains) -- [`textInteractionEnabled`](Reference.portuguese.md#textInteractionEnabled) -- [`mediaCapturePermissionGrantType`](Reference.portuguese.md#mediaCapturePermissionGrantType) -- [`autoManageStatusBarEnabled`](Reference.portuguese.md#autoManageStatusBarEnabled) -- [`setSupportMultipleWindows`](Reference.portuguese.md#setSupportMultipleWindows) -- [`basicAuthCredential`](Reference.portuguese.md#basicAuthCredential) -- [`enableApplePay`](Reference.portuguese.md#enableApplePay) -- [`forceDarkOn`](Reference.portuguese.md#forceDarkOn) -- [`minimumFontSize`](Reference.portuguese.md#minimumFontSize) - -## Methods Index - -- [`goForward`](Reference.portuguese.md#goforward) -- [`goBack`](Reference.portuguese.md#goback) -- [`reload`](Reference.portuguese.md#reload) -- [`stopLoading`](Reference.portuguese.md#stoploading) -- [`injectJavaScript`](Reference.portuguese.md#injectjavascriptstr) -- [`clearFormData`](Reference.portuguese.md#clearFormData) -- [`clearCache`](Reference.portuguese.md#clearCachebool) -- [`clearHistory`](Reference.portuguese.md#clearHistory) -- [`requestFocus`](Reference.portuguese.md#requestFocus) -- [`postMessage`](Reference.portuguese.md#postmessagestr) - ---- - -# Referências - -## Props - -### `source`[⬆](#props-index) - -Carrega HTML estático ou um URI (com cabeçalhos opcionais) na WebView. Observe que o HTML estático exigirá a configuração de [`originWhitelist`](Reference.portuguese.md#originwhitelist) como `["*"]`. - -O objeto passado para `source` pode ter uma das seguintes formas: - -**Carregar uri** - -- `uri` (string) - O URI a ser carregada na `WebView`. Pode ser um arquivo local ou remoto e pode ser alterado com o estado React ou props para navegar para uma nova página. -- `method` (string) - O método HTTP é o usado. O padrão é GET se não for especificado. No Android e no Windows, os únicos métodos suportados são GET e POST. -- `headers` (object) - Cabeçalhos HTTP adicionais para enviar com a solicitação. No Android, isso só pode ser usado com solicitações GET. Consulte o [Guia](Guide.portuguese.md#setting-custom-headers) para obter mais informações sobre a configuração de cabeçalhos personalizados. -- `body` (string) - O corpo HTTP a ser enviado com a solicitação. Esta deve ser uma string UTF-8 válida e será enviada exatamente conforme especificado, sem codificação adicional (por exemplo, escape de URL ou base64) aplicada. No Android e no Windows, isso só pode ser usado com solicitações POST. - -**HTML Estático** - -_Observe que usar HTML estático requer a propriedade WebView [originWhiteList](Reference.portuguese.md#originWhiteList) `['*']`. Para alguns conteúdos, como incorporações de vídeo (por exemplo, postagens no Twitter ou Facebook com vídeo), o baseUrl precisa ser definido para que a reprodução do vídeo funcione_ - -- `html` (string) - Uma página HTML estática para exibir na WebView. -- `baseUrl` (string) - A URL base a ser usada para quaisquer links relativos no HTML. Isso também é usado para o cabeçalho de origem com solicitações CORS feitas a partir da WebView. Ver [Documentação do Android WebView](https://developer.android.com/reference/android/webkit/WebView#loadDataWithBaseURL) - -| Tipo | Requerido | -| ------ | -------- | -| object | Falso | - ---- - -### `automaticallyAdjustContentInsets`[⬆](#props-index) - -Controla se a inserção de conteúdo deve ser ajustada para exibições da Web que são colocadas atrás de uma barra de navegação, barra de guias ou barra de ferramentas. O valor padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ---- | -------- | ---------- | -| bool | Falso | iOS | - ---- - -### `automaticallyAdjustsScrollIndicatorInsets`[⬆](#props-index) - -Controla se a inserção do indicador de rolagem deve ser ajustada para exibições da Web que são colocadas atrás de uma barra de navegação, barra de guias ou barra de ferramentas. O valor padrão `falso`. (iOS 13+) - -| Tipo | Requerido | Plataforma | -| ---- | -------- | ---------- | -| bool | Falso | iOS(13+) | - ---- - -### `injectedJavaScript`[⬆](#props-index) - -Defina isso para fornecer ao JavaScript que será injetado na página da Web depois que o documento terminar de carregar, mas antes que outros sub-recursos terminem de carregar. - -Certifique-se de que a string seja avaliada como um tipo válido (`true`) e não lance uma exceção. - -No iOS, consulte [`WKUserScriptInjectionTimeAtDocumentEnd`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentend?language=objc). Tenha certeza -para definir um manipulador [`onMessage`](Reference.portuguese.md#onmessage), mesmo que seja um operação vazia, ou o código não será executado. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------------------------- | -| string | Falso | iOS, Android, macOS, Windows | - -Para saber mais, leia o guia [Comunicação entre JS e Native](Guide.portuguese.md#communicating-between-js-and-native). - -_Observação: o Windows não tem [suporte nativo para alertas](https://github.com/MicrosoftDocs/winrt-api/blob/docs/windows.ui.xaml.controls/webview.md#use-of-alert) , como tal, quaisquer scripts para mostrar um alerta não funcionarão._ - -Exemplo: - -Post envia um objeto JSON de `window.location` para ser tratado por [`onMessage`](Reference.portuguese.md#onmessage) - -```jsx -const INJECTED_JAVASCRIPT = `(function() { - window.ReactNativeWebView.postMessage(JSON.stringify(window.location)); -})();`; - -; -``` - ---- - -### `injectedJavaScriptBeforeContentLoaded`[⬆](#props-index) - -Defina isso para fornecer JavaScript que será injetado na página da Web depois que o elemento do documento for criado, mas antes que outros sub-recursos terminem de carregar. - -Certifique-se de que a string seja avaliada como um tipo válido (`true` funciona) e não lance uma exceção. - -No iOS, consulte [`WKUserScriptInjectionTimeAtDocumentStart`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentstart?language=objc) - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| string | Não | iOS, macOS | - -Para saber mais, leia o guia [Comunicação entre JS e Native](Guide.portuguese.md#communicating-between-js-and-native). - -Exemplo: - -Post message um objeto JSON de `window.location` para ser tratado por [`onMessage`](Reference.portuguese.md#onmessage). `window.ReactNativeWebView.postMessage` _estará_ disponível neste momento. - -```jsx -const INJECTED_JAVASCRIPT = `(function() { - window.ReactNativeWebView.postMessage(JSON.stringify(window.location)); -})();`; - -; -``` - ---- - -### `injectedJavaScriptForMainFrameOnly`[⬆](#props-index) - -Se `true` (padrão; obrigatório para Android), carrega o `injectedJavaScript` apenas no quadro principal. - -Se `false`, (suportado apenas em iOS e macOS), carrega-o em todos os quadros (por exemplo, iframes). - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------------------------------------------- | -| bool | Não | iOS e macOS (`true` somente suportado no Android) | - ---- - -### `injectedJavaScriptBeforeContentLoadedForMainFrameOnly`[⬆](#props-index) - -Se `true` (padrão; obrigatório para Android), carrega o `injectedJavaScriptBeforeContentLoaded` apenas no quadro principal. - -Se `false`, (suportado apenas em iOS e macOS), carrega-o em todos os quadros (por exemplo, iframes). - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------------------------------------------- | -| bool | Não | iOS e macOS (`true` somente suportado para Android) | - ---- - -### `mediaPlaybackRequiresUserAction`[⬆](#props-index) - -Valor boleano que determina se o áudio e o vídeo HTML5 exigem que o usuário toque neles antes de iniciar a reprodução. O valor padrão é `true`. (API Android versão mínima 17). - -NOTA: o valor padrão `true` pode fazer com que alguns vídeos travem o carregamento no iOS. Defini-lo como `false` pode corrigir esse problema. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------------- | -| bool | Não | iOS, Android, macOS | - ---- - -### `nativeConfig`[⬆](#props-index) - -Substitua o componente nativo usado para renderizar a WebView. Habilita uma WebView nativo personalizado que usa o mesmo JavaScript que a WebView original. - -O prop `nativeConfig` espera um objeto com as seguintes chaves: - -- `component` (any) -- `props` (object) -- `viewManager` (object) - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ------------------- | -| object | Não | iOS, Android, macOS | - ---- - -### `onError`[⬆](#props-index) - -Função que é invocada quando o carregamento da `WebView` falha. - -| Tipo | Requerido | -| -------- | --------- | -| function | Não | - -Exemplo: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn('WebView error: ', nativeEvent); - }} -/> -``` - -A função passada para `onError` é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -canGoBack -canGoForward -code -description -didFailProvisionalNavigation -domain -loading -target -title -url -``` - -> **_Observação_** -> O domínio é usado apenas no iOS - -O `syntheticEvent` pode ser interrompido fazendo sua ação padrão chamando `syntheticEvent.preventDefault()`. - ---- - -### `onLoad`[⬆](#props-index) - -Função que é invocada quando a `WebView` termina de carregar. - -| Tipo | Requerido | -| -------- | --------- | -| function | Não | - -Exemplo: - -```jsx - { - const { nativeEvent } = syntheticEvent; - this.url = nativeEvent.url; - }} -/> -``` - -A função passada para `onLoad` é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadEnd`[⬆](#props-index) - -Função que é invocada quando o carregamento da `WebView` é bem-sucedido ou falha. - -| Tipo | Requerido | -| -------- | --------- | -| function | Não | - -Exemplo: - -```jsx - { - // componente de atualização para estar ciente do status de carregamento - const { nativeEvent } = syntheticEvent; - this.isLoading = nativeEvent.loading; - }} -/> -``` - -A função passada para `onLoadEnd` é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadStart`[⬆](#props-index) - -Função que é invocada quando a `WebView` começa a carregar. - -| Tipo | Requerido | -| -------- | --------- | -| function | Não | - -Exemplo: - -```jsx - { - // atualiza o componente para estar ciente do status de carregamento - const { nativeEvent } = syntheticEvent; - this.isLoading = nativeEvent.loading; - }} -/> -``` - -A função passada para `onLoadStart` é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onLoadProgress`[⬆](#props-index) - -Função que é invocada quando a `WebView` está carregando. - -| Tipo | Requerido | Plataforma | -| -------- | --------- | ------------------- | -| function | Não | iOS, Android, macOS | - -Exemplo: - -```jsx - { - this.loadingProgress = nativeEvent.progress; - }} -/> -``` - -A função passada para `onLoadProgress` é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -canGoBack -canGoForward -loading -progress -target -title -url -``` - ---- - -### `onHttpError`[⬆](#props-index) - -Função que é invocada quando a `WebView` recebe um erro http. - -> **_Observação_** -> API Android nível mínimo 23. - -| Tipo | Requerido | -| -------- | --------- | -| function | Não | - -Exemplo: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn( - 'Código de status de erro recebido da WebView: ', - nativeEvent.statusCode, - ); - }} -/> -``` - -A função passada para `onHttpError` é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -canGoBack -canGoForward -description -loading -statusCode -target -title -url -``` - -> **_Observação_** -> A descrição é usada apenas no Android - ---- - -### `onRenderProcessGone`[⬆](#props-index) - -Função que é invocada quando o processo da `WebView` falha ou é morto pelo sistema operacional no Android. - -> **_Observação_** -> API do Android nível mínimo 26. Somente Android - -| Tipo | Requerido | -| -------- | --------- | -| function | Não | - -Exemplo: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn( - 'WebView falhou: ', - nativeEvent.didCrash, - ); - }} -/> -``` - -A função passada para `onRenderProcessGone` é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -didCrash -``` ---- - -### `onMessage`[⬆](#props-index) - -Função que é invocada quando a webview chama `window.ReactNativeWebView.postMessage`. Definir essa propriedade injetará esse global em sua visualização da web. - -`window.ReactNativeWebView.postMessage` aceita um argumento, `data`, que estará disponível no objeto de evento, `event.nativeEvent.data`. `data` deve ser uma string. - -| Tipo | Requerido | -| -------- | --------- | -| function | Não | - -Para saber mais, leia o guia [Comunicação entre JS e Native](Guide.portuguese.md#communicating-between-js-and-native). - ---- - -### `onNavigationStateChange`[⬆](#props-index) - -Função que é invocada quando o carregamento da `WebView` começa ou termina. - -| Tipo | Requerido | -| -------- | --------- | -| function | Não | - -Exemplo: - -```jsx - { - // Acompanhe a navegação de volta no componente - this.canGoBack = navState.canGoBack; - }} -/> -``` - -O objeto `navState` inclui estas propriedades: - -``` -canGoBack -canGoForward -loading -navigationType (iOS only) -target -title -url -``` - ---- - -### `onContentProcessDidTerminate`[⬆](#props-index) - -Função que é invocada quando o processo de conteúdo da `WebView` é encerrado. - -| Tipo | Requerido | Plataforma | -| -------- | --------- | ----------------------- | -| function | Não | iOS e macOS WKWebView | - -Exemplo: - -```jsx - { - const { nativeEvent } = syntheticEvent; - console.warn('Processo de conteúdo encerrado, recarregando', nativeEvent); - this.refs.webview.reload(); - }} -/> -``` - -A função passada para onContentProcessDidTerminate é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -canGoBack -canGoForward -loading -target -title -url -``` - ---- - -### `onScroll`[⬆](#props-index) - -Função que é invocada quando o evento scroll é acionado na `WebView`. - -| Tipo | Requerido | Plataforma | -| -------- | --------- | ---------------------------- | -| function | Não | iOS, macOS, Android, Windows | - -Exemplo: - -```jsx - { - const { contentOffset } = syntheticEvent.nativeEvent - console.table(contentOffset) - }} -/> -``` - -A função passada para `onScroll` é chamada com um SyntheticEvent envolvendo um nativeEvent com estas propriedades: - -``` -contentInset -contentOffset -contentSize -layoutMeasurement -velocity -zoomScale -``` - ---- - -### `originWhitelist`[⬆](#props-index) - -Lista de strings de origem para permitir a navegação. As strings permitem curingas e são correspondidas com __somente a origem (não o URL completo). Se o usuário tocar para navegar para uma nova página, mas a nova página não estiver nesta lista de permissões, a URL será tratada pelo sistema operacional. As origens padrão da lista de permissões são "http://*" e "https://*". - -| Tipo | Requerido | Plataforma | -| ---------------- | --------- | ------------------- | -| array of strings | Não | iOS, Android, macOS | - -Exemplo: - -```jsx -// permitir apenas URIs que comecem com https:// ou git:// - - -``` - ---- - -### `renderError`[⬆](#props-index) - -Função que retorna uma view para mostrar se há um erro. - -| Tipo | Requerido | Plataforma | -| -------- | --------- | ------------------- | -| function | Não | iOS, Android, macOS | - -Exemplo: - -```jsx - } -/> -``` - -A função passada para `renderError` será chamada com o nome do erro. - ---- - -### `renderLoading`[⬆](#props-index) - -Função que retorna um indicador de carregamento. A prop startInLoadingState deve ser definida como true para usar essa prop. - -| Tipo | Requerido | Plataforma | -| -------- | --------- | ------------------- | -| function | Não | iOS, Android, macOS | - -Exemplo: - -```jsx - } -/> -``` - ---- - -### `scalesPageToFit`[⬆](#props-index) - -Booleano que controla se o conteúdo da Web é dimensionado para caber na exibição e permite que o usuário altere a escala. O valor padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | Android | - ---- - -### `onShouldStartLoadWithRequest`[⬆](#props-index) - -Função que permite o tratamento personalizado de qualquer solicitação de visualização da web. Retorne `true` da função para continuar carregando a solicitação e `false` para interromper o carregamento. - -No Android, não é chamado no primeiro carregamento. - -| Tipo | Requerido | Plataforma | -| -------- | --------- | ------------------- | -| function | Não | iOS, Android, macOS | - -Exemplo: - -```jsx - { - // Permitir apenas navegar neste site - return request.url.startsWith('https://reactnative.dev'); - }} -/> -``` - -O objeto `request` inclui estas propriedades: - -``` -title -url -loading -target -canGoBack -canGoForward -lockIdentifier -mainDocumentURL (iOS only) -navigationType (iOS only) -isTopFrame (iOS only) -``` - ---- - -### `startInLoadingState`[⬆](#props-index) - -Valor booleano que força a `WebView` mostrar a visualização de carregamento no primeiro carregamento. Esta prop deve ser definida como `true` para que a prop `renderLoading` funcione. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------------- | -| bool | Não | iOS, Android, macOS | - ---- - -### `style`[⬆](#props-index) - -Um objeto de estilo que permite personalizar o estilo da `WebView`. Observe que existem estilos padrão (exemplo: você precisa adicionar `flex: 0` ao estilo se quiser usar a propriedade `height`). - -| Tipo | Requerido | -| ----- | --------- | -| style | Não | - -Exemplo: - -```jsx - -``` - ---- - -### `containerStyle`[⬆](#props-index) - -Um objeto de estilo que permite personalizar o estilo do contêiner da `WebView`. Observe que existem estilos padrão (exemplo: você precisa adicionar `flex: 0` ao estilo se quiser usar a propriedade `height`). - -| Tipo | Requerido | -| ----- | --------- | -| style | Não | - -Exemplo: - -```jsx - -``` - ---- - -### `decelerationRate`[⬆](#props-index) - -Um número de ponto flutuante que determina a rapidez com que a visualização de rolagem desacelera depois que o usuário levanta o dedo. Você também pode usar os atalhos de string `"normal"` e `"fast"` que correspondem às configurações subjacentes do iOS para `UIScrollViewDecelerationRateNormal` e `UIScrollViewDecelerationRateFast` respectivamente: - -- normal: 0,998 -- rápido: 0,99 (o padrão para visualização na web do iOS) - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| number | Não | iOS | - ---- - -### `domStorageEnabled`[⬆](#props-index) - -Valor booleano para controlar se o DOM Storage está habilitado. Usado apenas no Android. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | Android | - ---- - -### `javaScriptEnabled`[⬆](#props-index) - -Valor booleano para habilitar JavaScript na `WebView`. O valor padrão é `true`. - -| Tipo | Requerido | -| ---- | --------- | -| bool | Não | - ---- - -### `javaScriptCanOpenWindowsAutomatically`[⬆](#props-index) - -Um valor booleano que indica se o JavaScript pode abrir janelas sem interação do usuário. O valor padrão é `falso`. - -| Tipo | Requerido | -| ---- | --------- | -| bool | Não | - ---- - -### `androidLayerType`[⬆](#props-index) - -Especifica o tipo de camada. - -Os valores possíveis para `androidLayerType` são: - -- `none` (padrão) - A visualização não possui uma camada. -- `software` - A visão tem uma camada de software. Uma camada de software é apoiada por um bitmap e faz com que a exibição seja renderizada usando o pipeline de renderização de software do Android, mesmo se a aceleração de hardware estiver habilitada. -- `hardware` - A visualização tem uma camada de hardware. Uma camada de hardware é apoiada por uma textura específica de hardware e faz com que a exibição seja renderizada usando o pipeline de renderização de hardware do Android, mas somente se a aceleração de hardware estiver ativada para a hierarquia de exibição. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| string | Não | Android | - ---- - -### `mixedContentMode`[⬆](#props-index) - -Especifica o modo de conteúdo misto. ou seja, a WebView permitirá que uma origem segura carregue conteúdo de qualquer outra origem. - -Os valores possíveis para `mixedContentMode` são: - -- `never` (padrão) - WebView não permitirá que uma origem segura carregue conteúdo de uma origem insegura. -- `always` - A WebView permitirá que uma origem segura carregue conteúdo de qualquer outra origem, mesmo que essa origem seja insegura. -- `compatibility` - WebView tentará ser compatível com a abordagem de um navegador web moderno em relação ao conteúdo misto. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| string | Não | Android | - ---- - -### `thirdPartyCookiesEnabled`[⬆](#props-index) - -Valor booleano para habilitar cookies de terceiros na `WebView`. Usado no Android Lollipop e acima apenas porque os cookies de terceiros são ativados por padrão no Android Kitkat e abaixo e no iOS. O valor padrão é `true`. Para saber mais sobre cookies, leia o [Guia](Guide.portuguese.md#Managing-Cookies) - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | Android | - ---- - -### `userAgent`[⬆](#props-index) - -Define o agente do usuário para a `WebView`. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ------------------- | -| string | Não | iOS, Android, macOS | - ---- - -### `applicationNameForUserAgent`[⬆](#props-index) - -Anexar ao agente de usuário existente. Definir `userAgent` substituirá isso. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ------------------- | -| string | Não | iOS, Android, macOS | - -```jsx - -// O User-Agent resultante será semelhante a: -// Mozilla/5.0 (Linux; Android 8.1.0; Android SDK built for x86 Build/OSM1.180201.021; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36 DemoApp/1.1.0 -// Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DemoApp/1.1.0 -``` - -### `allowsFullscreenVideo`[⬆](#props-index) - -Booleano que determina se os vídeos podem ser reproduzidos em tela cheia. O valor padrão é `falso`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | Android | - ---- - -### `allowsInlineMediaPlayback`[⬆](#props-index) - -Booleano que determina se os vídeos HTML5 são reproduzidos inline ou usam o controlador de tela cheia nativo. O valor padrão é `falso`. - -> **NOTA** -> -> Para que o vídeo seja reproduzido inline, não apenas esta propriedade precisa ser definida como `true`, mas o elemento de vídeo no documento HTML também deve incluir o atributo `webkit-playsinline`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | iOS | - ---- -### `allowsAirPlayForMediaPlayback`[⬆](#props-index) - -Um valor booleano que indica se o AirPlay é permitido. O valor padrão é `falso`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | --------------- | -| bool | Não | iOS e macOS | - ---- -### `bounces`[⬆](#props-index) - -Valor booleano que determina se a visualização da Web é rejeitada quando atinge a borda do conteúdo. O valor padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | iOS | - ---- - -### `overScrollMode`[⬆](#props-index) - -Especifica o modo de sobrerolagem. - -Os valores possíveis para `overScrollMode` são: - -- `always` (padrão) - Sempre permite que um usuário sobrescreva esta visualização, desde que seja uma visualização que possa rolar. -- `content` - Permitir que um usuário sobrescreva esta visualização somente se o conteúdo for grande o suficiente para rolar significativamente, desde que seja uma visualização que possa rolar. -- `never` - Nunca permita que um usuário sobrescreva esta visualização. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| string | Não | Android | - ---- - -### `contentInset`[⬆](#props-index) - -A quantidade pela qual o conteúdo da visualização da web é inserido a partir das bordas da visualização de rolagem. Padrão {top: 0, left: 0, bottom: 0, right: 0}. - -| Tipo | Requerido | Plataforma | -| ----------------------------------------------------------------- | --------- | ---------- | -| object: {top: number, left: number, bottom: number, right: number} | Não | iOS | - ---- - -### `contentInsetAdjustmentBehavior`[⬆](#props-index) - -Esta propriedade especifica como as inserções da área segura são usadas para modificar a área de conteúdo da visualização de rolagem. O valor padrão dessa propriedade é "never". Disponível no iOS 11 e posterior. O padrão é `never`. - -Valores possíveis: - -- `automatic` -- `scrollableAxes` -- `never` -- `always` - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| string | Não | iOS | - ---- - -### `contentMode`[⬆](#props-index) - -Controla o tipo de conteúdo a ser carregado. Disponível no iOS 13 ou posterior. O padrão é "recomendado", que carrega conteúdo móvel no iPhone e iPad Mini, mas conteúdo de desktop em iPads maiores. - -Consulte [Apresentando a navegação de classe desktop no iPad](https://developer.apple.com/videos/play/wwdc2019/203/) para saber mais. - -Valores possíveis: - -- `recommended` -- `mobile` -- `desktop` - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| string | Não | iOS | - ---- - -### `dataDetectorTypes`[⬆](#props-index) - -Determina os tipos de dados convertidos em URLs clicáveis no conteúdo da visualização da web. Por padrão, apenas números de telefone são detectados. - -Você pode fornecer um tipo ou uma matriz de vários tipos. - -Os valores possíveis para `dataDetectorTypes` são: - -- `phoneNumber` -- `link` -- `address` -- `calendarEvent` -- `none` -- `all` -- `trackingNumber` -- `flightNumber` -- `lookupSuggestion` - -| Tipo | Requerido | Plataforma | -| ---------------- | --------- | ---------- | -| string, or array | Não | iOS | - ---- - -### `scrollEnabled`[⬆](#props-index) - -Valor booleano que determina se a rolagem está habilitada na `WebView`. O valor padrão é `true`. Definir isso como `false` impedirá que a visualização da Web mova o corpo do documento quando o teclado aparecer sobre uma entrada. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | --------------- | -| bool | Não | iOS e macOS | - ---- - -### `nestedScrollEnabled`[⬆](#props-index) - -Valor booleano que determina se a rolagem é possível na `WebView` quando usado dentro de um `ScrollView` no Android. O valor padrão é `falso`. - -Definir isso como `true` impedirá que o `ScrollView` role ao rolar de dentro do `WebView`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------- | -| bool | Não | Android | - ---- - -### `setBuiltInZoomControls`[⬆](#props-index) - -Define se o WebView deve usar seus mecanismos de zoom integrados. O valor padrão é `true`. Definir isso como "falso" impedirá o uso de um gesto de pinça para controlar o zoom. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------- | -| bool | Não | Android | - ---- - -### `setDisplayZoomControls`[⬆](#props-index) - -Define se o WebView deve exibir controles de zoom na tela ao usar os mecanismos de zoom integrados (consulte `setBuiltInZoomControls`). O valor padrão é `falso`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------- | -| bool | Não | Android | - ---- - -### `directionalLockEnabled`[⬆](#props-index) - -Um valor booleano que determina se a rolagem está desabilitada em uma direção específica. -O valor padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | iOS | - ---- - -### `showsHorizontalScrollIndicator`[⬆](#props-index) - -Valor booleano que determina se um indicador de rolagem horizontal é mostrado na `WebView`. O valor padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------------- | -| bool | Não | iOS, Android, macOS | - ---- - -### `showsVerticalScrollIndicator`[⬆](#props-index) - -Valor booleano que determina se um indicador de rolagem vertical é mostrado na `WebView`. O valor padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------------- | -| bool | Não | iOS, Android, macOS | - ---- - -### `geolocationEnabled`[⬆](#props-index) - -Defina se a geolocalização está habilitada na `WebView`. O valor padrão é `falso`. Usado apenas no Android. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | Android | - ---- - -### `allowFileAccessFromFileURLs`[⬆](#props-index) - -Booleano que define se o JavaScript executado no contexto de uma URL de esquema de arquivo deve ter permissão para acessar o conteúdo de outras URLs de esquema de arquivo. O valor padrão é `falso`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ------------------- | -| bool | Não | iOS, Android, macOS | - ---- - -### `allowUniversalAccessFromFileURLs`[⬆](#props-index) - -Booleano que define se o JavaScript executado no contexto de uma URL de esquema de arquivo deve ter permissão para acessar conteúdo de qualquer origem. Incluindo o acesso ao conteúdo de outros URLs de esquema de arquivos. O valor padrão é `falso`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | -------------------- | -| bool | Não | iOS, Android, macOS | - ---- - -### `allowingReadAccessToURL`[⬆](#props-index) - -Um valor String que indica quais URLs o arquivo da WebView pode referenciar em scripts, solicitações AJAX e importações CSS. Isso é usado apenas para WebViews que são carregados com um source.uri definido como um URL `'file://'`. Se não for fornecido, o padrão é permitir apenas acesso de leitura à URL fornecida no próprio source.uri. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ------------- | -| string | Não | iOS e macOS | - ---- - -### `keyboardDisplayRequiresUserAction`[⬆](#props-index) - -Se false, o conteúdo da Web pode exibir programaticamente o teclado. O valor padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | iOS | - ---- - -### `hideKeyboardAccessoryView`[⬆](#props-index) - -Se true, isso ocultará a visualização do acessório de teclado (< > e Feito). - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | iOS | - ---- - -### `allowsBackForwardNavigationGestures`[⬆](#props-index) - -Se for verdade, isso será capaz de gestos de furto horizontal. O valor padrão é `falso`. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ------------- | -| boolean | Não | iOS e macOS | - ---- - -### `incognito`[⬆](#props-index) - -Não armazena nenhum dado durante o tempo de vida da WebView. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ------------------- | -| boolean | Não | iOS, Android, macOS | - ---- - -### `allowFileAccess`[⬆](#props-index) - -Se true, isso permitirá o acesso ao sistema de arquivos por meio de URIs `file://`. O valor padrão é `falso`. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | Android | - ---- - -### `saveFormDataDisabled`[⬆](#props-index) - -Define se a WebView deve desabilitar o salvamento de dados de formulário. O valor padrão é `falso`. Esta função não tem nenhum efeito a partir do nível 26 da API do Android, pois há um recurso de preenchimento automático que armazena dados de formulário. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | Android | - ---- - -### `cacheEnabled`[⬆](#props-index) - -Define seao WebView deve usar o cache do navegador. - -| Tipo | Requerido | Padrão | Plataforma | -| ------- | --------- | ------- | ------------------- | -| boolean | Não | true | iOS, Android, macOS | - ---- - -### `cacheMode`[⬆](#props-index) - -Substitui a maneira como o cache é usado. A forma como o cache é usado é baseado no tipo de navegação. Para um carregamento de página normal, o cache é verificado e o conteúdo é revalidado conforme necessário. Ao navegar de volta, o conteúdo não é revalidado, em vez disso, o conteúdo é apenas recuperado do cache. Essa propriedade permite que o cliente substitua esse comportamento. - -Os valores possíveis são: - -- `LOAD_DEFAULT` - Modo de uso de cache padrão. Se o tipo de navegação não impor nenhum comportamento específico, use recursos em cache quando estiverem disponíveis e não expirados, caso contrário, carregue recursos da rede. -- `LOAD_CACHE_ELSE_NETWORK` - Use recursos em cache quando estiverem disponíveis, mesmo que tenham expirado. Caso contrário, carregue recursos da rede. -- `LOAD_NO_CACHE` - Não use o cache, carregue da rede. -- `LOAD_CACHE_ONLY` - Não use a rede, carregue do cache. - -| Tipo | Requerido | Padrão | Plataforma | -| ------ | --------- | ------------ | ---------- | -| string | Não | LOAD_DEFAULT | Android | - ---- - -### `pagingEnabled`[⬆](#props-index) - -Se o valor desta propriedade for true, a visualização de rolagem para em múltiplos dos limites da visualização de rolagem quando o usuário rola. O valor padrão é falso. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | -------- | -| boolean | Não | iOS | - ---- - -### `allowsLinkPreview`[⬆](#props-index) - -Um valor booleano que determina se pressionar um link exibe uma visualização do destino do link. No iOS esta propriedade está disponível em dispositivos que suportam 3D Touch. No iOS 10 e posterior, o valor padrão é true; antes disso, o valor padrão é false. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ------------- | -| boolean | Não | iOS e macOS | - ---- - -### `sharedCookiesEnabled`[⬆](#props-index) - -Defina `true` se os cookies compartilhados de `[NSHTTPCookieStorage sharedHTTPCookieStorage]` devem ser usados ​​para cada solicitação de carregamento no WebView. O valor padrão é `falso`. Para saber mais sobre cookies, leia o [Guia](Guide.portuguese.md#Managing-Cookies) - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ------------- | -| boolean | Não | iOS e macOS | - ---- - -### `textZoom`[⬆](#props-index) - -Se o usuário definiu um tamanho de fonte personalizado no sistema Android, ocorre uma escala indesejável da interface do site no WebView. - -Ao definir o tamanho padrão do parâmetro textZoom (100), esse efeito indesejável desaparece. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| number | Não | Android | - -Exemplo: - -`` - ---- - -### `pullToRefreshEnabled`[⬆](#props-index) - -Valor booleano que determina se um gesto de puxar para atualizar está disponível na `WebView`. O valor padrão é `falso`. Se `true`, define `bounces` automaticamente para `true`. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | iOS | - -### `ignoreSilentHardwareSwitch`[⬆](#props-index) - -(somente ios) - -Quando definido como true, o switch silencioso do hardware é ignorado. Padrão: `falso` - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | iOS | - -### `onFileDownload`[⬆](#props-index) -Esta propriedade é somente para iOS. - -Função que é chamada quando o cliente precisa baixar um arquivo. - -Somente iOS 13+: se a visualização da web navegar para um URL que resulta em um HTTP -resposta com um cabeçalho Content-Disposition 'attachment...', então -isso será chamado. - -iOS 8+: Se o tipo MIME indicar que o conteúdo não pode ser renderizado pelo -webview, que também fará com que isso seja chamado. Nas versões do iOS anteriores a 13, -esta é a única condição que fará com que esta função seja chamada. - -O aplicativo precisará fornecer seu próprio código para realmente fazer o download -o arquivo. - -Se não for fornecido, o padrão é permitir que o webview tente renderizar o arquivo. - -Exemplo: - -```jsx - { - // Você usa downloadUrl que é uma string para baixar arquivos como quiser. - }} -/> -``` - -| Tipo | Requerido | Plataforma | -| -------- | --------- | ---------- | -| function | Não | iOS | - ---- - -### `limitsNavigationsToAppBoundDomains`[⬆](#props-index) - -Se true indica ao WebKit que um WKWebView navegará apenas para domínios vinculados a aplicativos. Aplicável apenas para iOS 14 ou superior. - -Uma vez definido, qualquer tentativa de sair de um domínio vinculado ao aplicativo falhará com o erro "Falha no domínio vinculado ao aplicativo". -Os aplicativos podem especificar até 10 domínios "limitados ao aplicativo" usando uma nova chave Info.plist `WKAppBoundDomains`. Para obter mais informações, consulte [Domínios vinculados a aplicativos](https://webkit.org/blog/10882/app-bound-domains/). - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | iOS | - -Exemplo: - -```jsx - -``` - ---- - -### `textInteractionEnabled`[⬆](#props-index) - -Se false indica ao WebKit que um WKWebView não irá interagir com o texto, não mostrando um loop de seleção de texto. Aplicável apenas para iOS 14.5 ou superior. - -O padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | iOS | - -Exemplo: - -```jsx - -``` - ---- - -### `mediaCapturePermissionGrantType` - -Esta propriedade especifica como lidar com solicitações de permissão de captura de mídia. O padrão é `prompt`, fazendo com que o usuário seja solicitado repetidamente. Disponível no iOS 15 e posterior. - -Valores possíveis: - -- `grantIfSameHostElsePrompt`: Se o host da origem de segurança da solicitação de permissão for igual ao host da URL atual do WebView, a permissão será concedida se já tiver sido concedida antes. Caso contrário, o usuário será solicitado. -- `grantIfSameHostElseDeny`: Se o host da origem de segurança da solicitação de permissão for igual ao host da URL atual do WebView, a permissão será concedida se já tiver sido concedida antes. Caso contrário, é negado. -- `deny` -- `grant`: A permissão é concedida se já tiver sido concedida antes. -- `prompt` - -Observe que uma concessão ainda pode resultar em um prompt, por exemplo, se o usuário nunca tiver sido solicitado a fornecer a permissão antes. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| string | Não | iOS | - -Exemplo: - -```javascript - -``` - ---- - -### `autoManageStatusBarEnabled` - -Se definido como `true`, a barra de status será automaticamente ocultada/exibida pela WebView, especificamente quando o vídeo em tela cheia estiver sendo assistido. Se for `false`, a WebView não gerenciará a barra de status. O valor padrão é `true`. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | iOS | - -Exemplo: - -```javascript - -``` - -### `setSupportMultipleWindows` - -Define se a WebView oferece suporte a várias janelas. Consulte [documentação do Android]('https://developer.android.com/reference/android/webkit/WebSettings#setSupportMultipleWindows(boolean)') para obter mais informações. -Definir isso como false pode expor o aplicativo a essa [vulnerabilidade](https://alesandroortiz.com/articles/uxss-android-webview-cve-2020-6506/), permitindo que um iframe malicioso escape para o DOM da camada superior. - -| Tipo | Requerido | Padrão | Plataforma | -| ------- | --------- | ------- | ---------- | -| boolean | Não | true | Android | - -Exemplo: - -```javascript - -``` - -### `enableApplePay` - -Um valor booleano quando definido como `true`, a WebView será renderizado com suporte ao Apple Pay. Uma vez definido, os sites poderão invocar o Apple Pay a partir do React Native Webview. -Isso vem com recursos como [`injectJavaScript`](Reference.portuguese.md#injectjavascriptstr), html5 histórico, [`sharedCookiesEnabled`](Reference.portuguese.md#sharedCookiesEnabled), [`injectedJavaScript`](Reference.portuguese.md#injectedjavascript), [`injectedJavaScriptBeforeContentLoaded`](Reference.portuguese.md#injectedjavascriptbeforecontentloaded) não funcionará veja na [Nota de lançamento do Apple Pay](https://developer.apple.com/documentation/safari-release-notes/safari-13-release-notes#Payment-Request-API). - -Se você for solicitado a enviar uma mensagem para App , a página da Web deve chamar explicitamente o manipulador de mensagens do webkit e recebê-lo no manipulador `onMessage` no lado nativo. - -```javascript -window.webkit.messageHandlers.ReactNativeWebView.postMessage("hello apple pay") -``` - -| Tipo | Requerido | Padrão | Plataforma | -| ------- | --------- | ------- | --------- | -| boolean | Não | false | iOS | - -Exemplo: - -```javascript - -``` - -### `forceDarkOn` - -Configurando o tema escuro -*NOTA* : A configuração de forçar o tema escuro não é persistente. Você deve chamar o método estático sempre que o processo do aplicativo for iniciado. - -*NOTA* : A mudança do modo dia<->noite é uma alteração de configuração, portanto, por padrão, a atividade será reiniciada e serão coletados os novos valores para aplicar o tema. Tome cuidado ao substituir esse comportamento padrão para garantir que esse método ainda seja chamado quando as alterações forem feitas. - -| Tipo | Requerido | Plataforma | -| ------- | --------- | ---------- | -| boolean | Não | Android | - -Exemplo: - -```javascript - -``` -### `menuItems` - -Uma matriz de objetos de itens de menu personalizados que serão exibidos ao selecionar o texto. Uma matriz vazia suprimirá o menu. Usado em conjunto com `onCustomMenuSelection` - -| Tipo | Requerido | Plataforma | -| ------------------------------------------------------------------ | -------- | -------- | -| array of objects: {label: string, key: string} | Não | iOS, Android | - -Exemplo: - -```javascript - -``` - -### `onCustomMenuSelection` - -Função chamada quando um item de menu personalizado é selecionado. Ele recebe um evento Nativo, que inclui três chaves personalizadas: `label`, `key` e `selectedText`. - -| Tipo | Requerido | Plataforma | -| ------------------------------------------------------------------ | -------- | -------- | -| function | Não | iOS, Android | - -```javascript - { - const { label } = webViewEvent.nativeEvent; // O nome do item de menu, ou seja, 'Tweet' - const { key } = webViewEvent.nativeEvent; // A chave do item de menu, ou seja, 'tweet' - const { selectedText } = webViewEvent.nativeEvent; // Texto destacado - }} -/> -``` - -### `basicAuthCredential` - -Um objeto que especifica as credenciais de um usuário a serem usadas para autenticação básica. - -- `username` (string) - Um nome de usuário usado para autenticação básica. -- `password` (string) - Uma senha usada para autenticação básica. - -| Tipo | Requerido | -| ------ | --------- | -| object | Não | - -### `minimumFontSize` - -O Android impõe um tamanho mínimo de fonte com base nesse valor. Um número inteiro não negativo entre 1 e 72. Qualquer número fora do intervalo especificado será fixado. O valor padrão é 8. Se você estiver usando tamanhos de fonte menores e estiver tendo problemas para ajustar a janela inteira em uma tela, tente definir um valor menor. - -| Tipo | Requerido | Plataforma | -| ------ | --------- | ---------- | -| number | Não | Android | - -Exemplo: - -```javascript - -``` - -## Métodos - -### `goForward()`[⬆](#methods-index) - -```javascript -goForward(); -``` - -Avançar uma página no histórico da visualização da web. - -### `goBack()`[⬆](#methods-index) - -```javascript -goBack(); -``` - -Volte uma página no histórico da visualização da web. - -### `reload()`[⬆](#methods-index) - -```javascript -reload(); -``` - -Recarrega a página atual. - -### `stopLoading()`[⬆](#methods-index) - -```javascript -stopLoading(); -``` - -Pare de carregar a página atual. - -### `injectJavaScript(str)`[⬆](#methods-index) - -```javascript -injectJavaScript('... javascript string ...'); -``` - -Executa a string JavaScript. - -Para saber mais, leia o guia [Comunicação entre JS e Native](Guide.portuguese.md#communicating-between-js-and-native). - -### `requestFocus()`[⬆](#methods-index) - -```javascript -requestFocus(); -``` - -Solicite a webView para pedir o foco. (As pessoas que trabalham em aplicativos de TV podem querer dar uma olhada nisso!) - -### `postMessage(str)`[⬆](#methods-index) - -```javascript -postMessage('mensagem'); -``` - -Postagem de uma mensagem no WebView, tratada por [`onMessage`](Reference.portuguese.md#onmessage). - -### `clearFormData()`[⬆](#methods-index) - -(somente Android) - -```javascript -clearFormData(); -``` - -Remove o pop-up de preenchimento automático do campo de formulário em foco no momento, se presente. [referência do desenvolvedor.android.com]() - -### `clearCache(bool)`[⬆](#methods-index) - -(somente Android) - -```javascript -clearCache(true) -``` - -Limpa o cache de recursos. Observe que o cache é por aplicativo, portanto, isso limpará o cache de todos os WebViews usados. [referência do desenvolvedor.android.com]() - -### `clearHistory()`[⬆](#methods-index) - -(somente Android) - -```javascript -clearHistory(); -``` - -Diz a este WebView para limpar sua lista interna de retorno/encaminhamento. [referência do desenvolvedor.android.com]() - -## Outros documentos - -Confira também nosso [Guia de Introdução](Getting-Started.portuguese.md) e [Guia Detalhado](Guide.portuguese.md). - -## Traduções - -Esse arquivo está disponível em: - -- [Inglês](Reference.md) -- [Italiano](Reference.italian.md) - diff --git a/example/.gitignore b/example/.gitignore deleted file mode 100644 index 7a6efe5dd..000000000 --- a/example/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -*.binlog -*.hprof -*.xcworkspace/ -*.zip -.DS_Store -.gradle/ -.idea/ -.vs/ -Pods/ -build/ -dist/ -local.properties -msbuild.binlog -node_modules/ diff --git a/example/.watchmanconfig b/example/.watchmanconfig deleted file mode 100644 index 9e26dfeeb..000000000 --- a/example/.watchmanconfig +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/example/App.tsx b/example/App.tsx deleted file mode 100644 index 964bcf368..000000000 --- a/example/App.tsx +++ /dev/null @@ -1,304 +0,0 @@ -import React, {Component} from 'react'; -import { - StyleSheet, - SafeAreaView, - Text, - TouchableOpacity, - View, - Keyboard, - Button, - Platform, -} from 'react-native'; - -import Alerts from './examples/Alerts'; -import Scrolling from './examples/Scrolling'; -import Background from './examples/Background'; -import Downloads from './examples/Downloads'; -import Uploads from './examples/Uploads'; -import Injection from './examples/Injection'; -import LocalPageLoad from './examples/LocalPageLoad'; -import Messaging from './examples/Messaging'; -import NativeWebpage from './examples/NativeWebpage'; -import ApplePay from './examples/ApplePay'; -import CustomMenu from './examples/CustomMenu'; -import OpenWindow from './examples/OpenWindow'; -import SuppressMenuItems from './examples/Suppress'; - -const TESTS = { - Messaging: { - title: 'Messaging', - testId: 'messaging', - description: 'js-webview postMessage messaging test', - render() { - return ; - }, - }, - Alerts: { - title: 'Alerts', - testId: 'alerts', - description: 'Alerts tests', - render() { - return ; - }, - }, - Scrolling: { - title: 'Scrolling', - testId: 'scrolling', - description: 'Scrolling event test', - render() { - return ; - }, - }, - Background: { - title: 'Background', - testId: 'background', - description: 'Background color test', - render() { - return ; - }, - }, - Downloads: { - title: 'Downloads', - testId: 'downloads', - description: 'File downloads test', - render() { - return ; - }, - }, - Uploads: { - title: 'Uploads', - testId: 'uploads', - description: 'Upload test', - render() { - return ; - }, - }, - Injection: { - title: 'Injection', - testId: 'injection', - description: 'Injection test', - render() { - return ; - }, - }, - PageLoad: { - title: 'LocalPageLoad', - testId: 'LocalPageLoad', - description: 'Local Page load test', - render() { - return ; - }, - }, - NativeWebpage: { - title: 'NativeWebpage', - testId: 'NativeWebpage', - description: 'Test to open a new webview with a link', - render() { - return ; - }, - }, - ApplePay: { - title: 'Apple Pay ', - testId: 'ApplePay', - description: 'Test to open a apple pay supported page', - render() { - return ; - }, - }, - CustomMenu: { - title: 'Custom Menu', - testId: 'CustomMenu', - description: 'Test to custom context menu shown on highlighting text', - render() { - return ; - }, - }, - OpenWindow: { - title: 'Open Window', - testId: 'OpenWindow', - description: 'Test to intercept new window events', - render() { - return ; - }, - }, - SuppressMenuItems: { - title: 'SuppressMenuItems', - testId: 'SuppressMenuItems', - description: 'SuppressMenuItems in editable content', - render() { - return ; - } - } -}; - -interface Props {} -interface State {restarting: boolean; currentTest: Object} - -export default class App extends Component { - state = { - restarting: false, - currentTest: TESTS.Alerts, - }; - - _simulateRestart = () => { - this.setState({restarting: true}, () => this.setState({restarting: false})); - }; - - _changeTest = (testName) => { - this.setState({currentTest: TESTS[testName]}); - }; - - render() { - const {restarting, currentTest} = this.state; - return ( - - Keyboard.dismiss()} - testID="closeKeyboard" - /> - - - Simulate Restart - - - - - - -

- - - -`; - -type Props = {}; -type State = {}; - -export default class Alerts extends Component { - state = {}; - - render() { - return ( - - - - ); - } -} diff --git a/example/examples/ApplePay.tsx b/example/examples/ApplePay.tsx deleted file mode 100644 index 6bd67a425..000000000 --- a/example/examples/ApplePay.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, {Component} from 'react'; -import {View} from 'react-native'; - -import WebView from 'react-native-webview'; - -type Props = {}; -type State = {}; - -export default class Alerts extends Component { - state = {}; - - render() { - return ( - - - - ); - } -} diff --git a/example/examples/Background.tsx b/example/examples/Background.tsx deleted file mode 100644 index 79a360eb3..000000000 --- a/example/examples/Background.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React, {Component} from 'react'; -import {Text, View} from 'react-native'; - -import WebView from 'react-native-webview'; - -const HTML = ` -\n - - - Hello World - - - - - -

HTML content in transparent body.

- - -`; - -type Props = {}; -type State = { - backgroundColor: string, -}; - -export default class Background extends Component { - state = { - backgroundColor: '#FF00FF00' - }; - - render() { - return ( - - - - - - - WebView is transparent contained in a View with a red backgroundColor - - ); - } -} diff --git a/example/examples/CustomMenu.tsx b/example/examples/CustomMenu.tsx deleted file mode 100644 index bbb1f7f7d..000000000 --- a/example/examples/CustomMenu.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React, {Component} from 'react'; -import {Button, Linking, Text, View} from 'react-native'; - -import WebView from 'react-native-webview'; - -const HTML = ` -\n - - - Context Menu - - - - - - -

- Select the text to see the custom context menu. -

-

- The custom context menu will show the custom menus defined in the menuItems prop and call the onCustomMenuSelection - on clicking on the menu Item. Testing symbols ' " < & > + - = ^ % $ # @ ! ~ ; : ? -

-

- "Third Para with quotes" -

- - -`; - -interface Props {} -interface State {} - -// export default class CustomMenu extends Component { -export default CustomMenu = () => { - const [selectionInfo, setSelectionInfo] = React.useState(null) - const webviewRef = React.useRef() - - return ( - - - { - const { label, key, selectedText } = webViewEvent.nativeEvent; - setSelectionInfo(webViewEvent.nativeEvent) - // clearing the selection by sending a message. This would need a script on the source page to listen to the message. - webviewRef.current?.postMessage(JSON.stringify({what: 'clearSelection'})) - }} - /> - - {selectionInfo - && - onCustomMenuSelection called: {"\n"} - - label: {selectionInfo?.label}{"\n"} - - key: {selectionInfo?.key}{"\n"} - - selectedText: {selectionInfo?.selectedText} - - } - - ); -} \ No newline at end of file diff --git a/example/examples/Downloads.tsx b/example/examples/Downloads.tsx deleted file mode 100644 index 13c1d5f2b..000000000 --- a/example/examples/Downloads.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React, {Component} from 'react'; -import {Alert, Platform, View} from 'react-native'; - -import WebView, {FileDownload} from 'react-native-webview'; - -const HTML = ` -\n - - - Downloads - - - - - -
Example zip file download -
- Download file with non-ascii filename: "foo-ä.html" - - -`; - -interface Props {} -interface State {} - -export default class Downloads extends Component { - state = {}; - - onFileDownload = ({ nativeEvent }: { nativeEvent: FileDownload } ) => { - Alert.alert("File download detected", nativeEvent.downloadUrl); - }; - - render() { - const platformProps = Platform.select({ - ios: { - onFileDownload: this.onFileDownload, - }, - }); - - return ( - - - - ); - } -} diff --git a/example/examples/Injection.tsx b/example/examples/Injection.tsx deleted file mode 100644 index e1d52a2db..000000000 --- a/example/examples/Injection.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import React, {Component} from 'react'; -import {Text, View, ScrollView} from 'react-native'; - -import WebView from 'react-native-webview'; - -const HTML = ` - - - - - - iframe test - - -

beforeContentLoaded on the top frame failed!

-

afterContentLoaded on the top frame failed!

- - - - - -`; - -type Props = {}; -type State = { - backgroundColor: string, -}; - -export default class Injection extends Component { - state = { - backgroundColor: '#FF00FF00' - }; - - render() { - return ( - - - - {}} - injectedJavaScriptBeforeContentLoadedForMainFrameOnly={false} - injectedJavaScriptForMainFrameOnly={false} - - /* We set this property in each frame */ - injectedJavaScriptBeforeContentLoaded={` - console.log("executing injectedJavaScriptBeforeContentLoaded... " + (new Date()).toString()); - if(typeof window.top.injectedIframesBeforeContentLoaded === "undefined"){ - window.top.injectedIframesBeforeContentLoaded = []; - } - window.self.colourToUse = "orange"; - if(window.self === window.top){ - console.log("Was window.top. window.frames.length is:", window.frames.length); - window.self.numberOfFramesAtBeforeContentLoaded = window.frames.length; - function declareSuccessOfBeforeContentLoaded(head){ - var style = window.self.document.createElement('style'); - style.type = 'text/css'; - style.innerHTML = "#before_failed { display: none !important; }#before_succeeded { display: inline-block !important; }"; - head.appendChild(style); - } - - const head = (window.self.document.head || window.self.document.getElementsByTagName('head')[0]); - - if(head){ - declareSuccessOfBeforeContentLoaded(head); - } else { - window.self.document.addEventListener("DOMContentLoaded", function (event) { - const head = (window.self.document.head || window.self.document.getElementsByTagName('head')[0]); - declareSuccessOfBeforeContentLoaded(head); - }); - } - } else { - window.top.injectedIframesBeforeContentLoaded.push(window.self.name); - console.log("wasn't window.top."); - console.log("wasn't window.top. Still going..."); - } - `} - - /* We read the colourToUse property in each frame to recolour each frame */ - injectedJavaScript={` - console.log("executing injectedJavaScript... " + (new Date()).toString()); - if(typeof window.top.injectedIframesAfterContentLoaded === "undefined"){ - window.top.injectedIframesAfterContentLoaded = []; - } - - if(window.self.colourToUse){ - window.self.document.body.style.backgroundColor = window.self.colourToUse; - } else { - window.self.document.body.style.backgroundColor = "cyan"; - } - - if(window.self === window.top){ - function declareSuccessOfAfterContentLoaded(head){ - var style = window.self.document.createElement('style'); - style.type = 'text/css'; - style.innerHTML = "#after_failed { display: none !important; }#after_succeeded { display: inline-block !important; }"; - head.appendChild(style); - } - - declareSuccessOfAfterContentLoaded(window.self.document.head || window.self.document.getElementsByTagName('head')[0]); - - // var numberOfFramesAtBeforeContentLoadedEle = document.createElement('p'); - // numberOfFramesAtBeforeContentLoadedEle.textContent = "Number of iframes upon the main frame's beforeContentLoaded: " + - // window.self.numberOfFramesAtBeforeContentLoaded; - - // var numberOfFramesAtAfterContentLoadedEle = document.createElement('p'); - // numberOfFramesAtAfterContentLoadedEle.textContent = "Number of iframes upon the main frame's afterContentLoaded: " + window.frames.length; - // numberOfFramesAtAfterContentLoadedEle.id = "numberOfFramesAtAfterContentLoadedEle"; - - var namedFramesAtBeforeContentLoadedEle = document.createElement('p'); - namedFramesAtBeforeContentLoadedEle.textContent = "Names of iframes that called beforeContentLoaded: " + JSON.stringify(window.top.injectedIframesBeforeContentLoaded || []); - namedFramesAtBeforeContentLoadedEle.id = "namedFramesAtBeforeContentLoadedEle"; - - var namedFramesAtAfterContentLoadedEle = document.createElement('p'); - namedFramesAtAfterContentLoadedEle.textContent = "Names of iframes that called afterContentLoaded: " + JSON.stringify(window.top.injectedIframesAfterContentLoaded); - namedFramesAtAfterContentLoadedEle.id = "namedFramesAtAfterContentLoadedEle"; - - // document.body.appendChild(numberOfFramesAtBeforeContentLoadedEle); - // document.body.appendChild(numberOfFramesAtAfterContentLoadedEle); - document.body.appendChild(namedFramesAtBeforeContentLoadedEle); - document.body.appendChild(namedFramesAtAfterContentLoadedEle); - } else { - window.top.injectedIframesAfterContentLoaded.push(window.self.name); - window.top.document.getElementById('namedFramesAtAfterContentLoadedEle').textContent = "Names of iframes that called afterContentLoaded: " + JSON.stringify(window.top.injectedIframesAfterContentLoaded); - } - `} - /> - - - This test presents three iframes: iframe_0 (yellow); iframe_1 (pink); and iframe_2 (transparent, because its 'X-Frame-Options' is set to 'SAMEORIGIN'). - Before injection, the main frame's background is the browser's default value (transparent or white) and each frame has its natural colour. - {/*1a) At injection time "beforeContentLoaded", a variable will be set in each frame to set 'orange' as the "colour to be used".*/} - {/*1b) Also upon "beforeContentLoaded", a style element to change the text "beforeContentLoaded failed" -> "beforeContentLoaded succeeded" will be applied as soon as the head has loaded.*/} - {/*2a) At injection time "afterContentLoaded", that variable will be read – if present, the colour orange will be injected into all frames. Otherwise, cyan.*/} - {/*2b) Also upon "afterContentLoaded", a style element to change the text "afterContentLoaded failed" -> "afterContentLoaded succeeded" will be applied as soon as the head has loaded.*/} - ✅ If the main frame becomes orange, then top-frame injection both beforeContentLoaded and afterContentLoaded is supported. - ✅ If iframe_0, and iframe_1 become orange, then multi-frame injection beforeContentLoaded and afterContentLoaded is supported. - ✅ If the two texts say "beforeContentLoaded on the top frame succeeded!" and "afterContentLoaded on the top frame succeeded!", then both injection times are supported at least on the main frame. - ❌ If either of the two iframes become coloured cyan, then for that given frame, JS injection succeeded after the content loaded, but didn't occur before the content loaded. - ❌ If "Names of iframes that called beforeContentLoaded: " is [], then see above. - ❌ If "Names of iframes that called afterContentLoaded: " is [], then afterContentLoaded is not supported in iframes. - ❌ If the main frame becomes coloured cyan, then JS injection succeeded after the content loaded, but didn't occur before the content loaded. - ❌ If the text "beforeContentLoaded on the top frame failed" remains unchanged, then JS injection has failed on the main frame before the content loaded. - ❌ If the text "afterContentLoaded on the top frame failed" remains unchanged, then JS injection has failed on the main frame after the content loaded. - ❌ If the iframes remain their original colours (yellow and pink), then multi-frame injection is not supported at all. - - ); - } -} diff --git a/example/examples/LocalPageLoad.tsx b/example/examples/LocalPageLoad.tsx deleted file mode 100644 index 780e6e697..000000000 --- a/example/examples/LocalPageLoad.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React, {Component} from 'react'; -import {View, Text, Alert, TextInput, Button} from 'react-native'; -import WebView from 'react-native-webview'; -const localHtmlFile = require('../assets/test.html'); - -export default class LocalPageLoad extends Component { - render() { - return ( - - - - - - ); - } - } \ No newline at end of file diff --git a/example/examples/Messaging.tsx b/example/examples/Messaging.tsx deleted file mode 100644 index 46680d7d2..000000000 --- a/example/examples/Messaging.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, {Component} from 'react'; -import {View, Alert, TextInput} from 'react-native'; - -import WebView from 'react-native-webview'; - -const HTML = `\n - - - Messaging - - - - - - -

-

Nothing received yet

- - - -`; - -type Props = {}; -type State = {}; - -export default class Messaging extends Component { - state = {}; - - constructor(props) { - super(props); - this.webView = React.createRef(); - } - - render() { - return ( - - { - this.webView.current.postMessage(e.nativeEvent.text); - }}/> - {this.webView.current.postMessage('Hello from RN');}} - automaticallyAdjustContentInsets={false} - onMessage={(e: {nativeEvent: {data?: string}}) => { - Alert.alert('Message received from JS: ', e.nativeEvent.data); - }} - /> - - ); - } -} diff --git a/example/examples/NativeWebpage.tsx b/example/examples/NativeWebpage.tsx deleted file mode 100644 index 39c750220..000000000 --- a/example/examples/NativeWebpage.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React, { Component } from 'react'; -import { View } from 'react-native'; - -import WebView from 'react-native-webview'; - -interface Props {} -interface State {} - -export default class NativeWebpage extends Component { - state = {}; - - render() { - return ( - - { - console.log("onShouldStartLoadWithRequest", event); - return true; - }} - onLoadStart={(event) => { - console.log("onLoadStart", event.nativeEvent); - }} - /> - - ); - } -} diff --git a/example/examples/OpenWindow.tsx b/example/examples/OpenWindow.tsx deleted file mode 100644 index c927f8bad..000000000 --- a/example/examples/OpenWindow.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import React, {Component} from 'react'; -import {Button, Switch, StyleSheet, Text, View} from 'react-native'; - -import WebView from 'react-native-webview'; - -const HTML = ` -\n - - - OnOpenWindow - - - - - - - - - - - Call target=_blank link from DOM - - - -`; - -type Props = {}; -type State = { - shouldInterceptOpenWindow: boolean, - text: string, - webViewKey: number -}; - -export default class OpenWindow extends Component { - state = { - shouldInterceptOpenWindow: true, - text: 'No OpenWindow event intercepted yet', - webViewKey: 1 - }; - - interceptOpenWindow = (syntheticEvent) => { - const { nativeEvent } = syntheticEvent - const { targetUrl } = nativeEvent - this.setState({ - text: `Intercepted OpenWindow event for ${targetUrl} at ${Date.now()}` - }) - }; - - toggleShouldInterceptOpenWindow = () => { - this.setState(prevState => ({ - shouldInterceptOpenWindow: !prevState.shouldInterceptOpenWindow - })) - }; - - resetWebView = () => { - this.setState(prevState => ({ - webViewKey: prevState.webViewKey + 1 - })) - }; - - render() { - const onOpenWindow = this.state.shouldInterceptOpenWindow - ? this.interceptOpenWindow - : undefined - - return ( - - - - Intercept OpenWindow event - - - - - - {this.state.text} - -