├── .gitattributes ├── .gitignore ├── README.md ├── android ├── .editorconfig ├── build.gradle ├── gradle.properties ├── libs │ └── tbs_sdk_thirdapp_v4.3.0.67_43967_sharewithdownloadwithfile_withoutGame_obfs_20200923_120452.jar └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── indi │ │ └── fan │ │ └── webviewx5 │ │ ├── RNX5WebViewFileProvider.java │ │ ├── RNX5WebViewManager.java │ │ ├── RNX5WebViewModule.java │ │ ├── RNX5WebViewPackage.kt │ │ ├── WebViewConfig.java │ │ └── events │ │ ├── TopHttpErrorEvent.kt │ │ ├── TopLoadingErrorEvent.kt │ │ ├── TopLoadingFinishEvent.kt │ │ ├── TopLoadingProgressEvent.kt │ │ ├── TopLoadingStartEvent.kt │ │ ├── TopMessageEvent.kt │ │ ├── TopRenderProcessGoneEvent.kt │ │ └── TopShouldStartLoadWithRequestEvent.kt │ ├── jniLibs │ ├── armeabi-v7a │ │ └── liblbs.so │ ├── armeabi │ │ └── liblbs.so │ ├── mips │ │ └── liblbs.so │ └── x86 │ │ └── liblbs.so │ └── res │ └── xml │ └── file_provider_paths.xml ├── apple ├── RNCWKProcessPoolManager.h ├── RNCWKProcessPoolManager.m ├── RNCWebView.h ├── RNCWebView.m ├── RNCWebViewManager.h └── RNCWebViewManager.m ├── index.d.ts ├── index.js ├── ios ├── RNCWebView.xcodeproj │ └── project.pbxproj ├── RNWebviewx5.h ├── RNWebviewx5.m ├── RNWebviewx5.podspec ├── RNWebviewx5.xcodeproj │ └── project.pbxproj └── RNWebviewx5.xcworkspace │ └── contents.xcworkspacedata ├── lib ├── WebView.android.d.ts ├── WebView.android.d.ts.map ├── WebView.android.js ├── WebView.d.ts ├── WebView.d.ts.map ├── WebView.ios.d.ts ├── WebView.ios.d.ts.map ├── WebView.ios.js ├── WebView.js ├── WebView.macos.d.ts ├── WebView.macos.d.ts.map ├── WebView.macos.js ├── WebView.styles.d.ts ├── WebView.styles.d.ts.map ├── WebView.styles.js ├── WebView.windows.d.ts ├── WebView.windows.d.ts.map ├── WebView.windows.js ├── WebViewShared.d.ts ├── WebViewShared.d.ts.map ├── WebViewShared.js ├── WebViewTypes.d.ts ├── WebViewTypes.d.ts.map └── WebViewTypes.js ├── package.json └── react-native-webview-tencentx5.podspec /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # OSX 3 | # 4 | .DS_Store 5 | 6 | # node.js 7 | # 8 | node_modules/ 9 | npm-debug.log 10 | yarn-error.log 11 | 12 | 13 | # Xcode 14 | # 15 | build/ 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata 25 | *.xccheckout 26 | *.moved-aside 27 | DerivedData 28 | *.hmap 29 | *.ipa 30 | *.xcuserstate 31 | project.xcworkspace 32 | 33 | 34 | # Android/IntelliJ 35 | # 36 | build/ 37 | .idea 38 | .gradle 39 | local.properties 40 | *.iml 41 | 42 | # BUCK 43 | buck-out/ 44 | \.buckd/ 45 | *.keystore 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # react-native-webview-tencentx5 3 | 将安卓中webview浏览器内核替换为[腾讯X5内核](https://x5.tencent.com/docs/index.html)并保留[react-native-webview](https://github.com/react-native-webview/react-native-webview)中各种[API](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md)。
4 | 可以优化Android版本低而使浏览器内核webveiw不正常显示,同时使用腾讯X5方便扩展。
5 | 总之,等于使用腾讯浏览器打开webview页面。
6 | 其中react-native-webview的API支持版本为v10.9.3,X5内核版本SDK为v4.3.0.93_43993。
7 | ## Getting started 8 | 9 | `$ npm install react-native-webview-tencentx5 --save` 10 | 11 | or 12 | 13 | `$ yarn add react-native-webview-tencentx5` 14 | 15 | ### Mostly automatic installation 16 | 17 | Since React Native 0.60 and higher, [autolinking](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md) makes the installation process simpler. 18 | 19 | ### Manual installation 20 | 21 | 22 | #### iOS 23 | `$ cd ios && pod install` 24 | 25 | #### Android 26 | 为了保障X5内核的动态下发和正常使用,您需要在您的AndroidManifest.xml增加如下权限: 27 | ```xml 28 | 29 | 30 | 31 | 32 | 33 | ``` 34 | ## Troubleshooting 35 | 36 | ### The following situations are not errors 37 | - 首次加载成功后,可能依旧为原始内核,等待X5内核下载启动,往后都可正常使用 38 | - 首次加载可能会出现卡顿白屏现象 39 | - 请注意X5内核运行环境在模拟器下的影响,请使用真机调试 40 | 41 | ## Usage 42 | ```javascript 43 | import { WebView } from 'react-native-webview-tencentx5'; 44 | 45 | 49 | ``` 50 | 51 | -------------------------------------------------------------------------------- /android/.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset=utf-8 3 | end_of_line=lf 4 | insert_final_newline=false 5 | indent_style=space 6 | indent_size=2 7 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.getExtOrDefault = {name -> 3 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['ReactNativeWebView_' + name] 4 | } 5 | 6 | // The Android Gradle plugin is only required when opening the android folder stand-alone. 7 | // This avoids unnecessary downloads and potential conflicts when the library is included as a 8 | // module dependency in an application project. 9 | if (project == rootProject) { 10 | repositories { 11 | google() 12 | jcenter() 13 | } 14 | 15 | dependencies { 16 | classpath("com.android.tools.build:gradle:3.6.0") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}") 18 | } 19 | } else { 20 | repositories { 21 | jcenter() 22 | } 23 | 24 | dependencies { 25 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}") 26 | } 27 | } 28 | } 29 | 30 | def getExtOrIntegerDefault(name) { 31 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['ReactNativeWebView_' + name]).toInteger() 32 | } 33 | 34 | apply plugin: 'com.android.library' 35 | apply plugin: 'kotlin-android' 36 | 37 | android { 38 | compileSdkVersion getExtOrIntegerDefault('compileSdkVersion') 39 | buildToolsVersion getExtOrDefault('buildToolsVersion') 40 | defaultConfig { 41 | minSdkVersion 16 42 | targetSdkVersion getExtOrIntegerDefault('targetSdkVersion') 43 | versionCode 1 44 | versionName "1.0" 45 | } 46 | buildTypes { 47 | release { 48 | minifyEnabled false 49 | } 50 | } 51 | lintOptions { 52 | disable 'GradleCompatible' 53 | } 54 | compileOptions { 55 | sourceCompatibility JavaVersion.VERSION_1_8 56 | targetCompatibility JavaVersion.VERSION_1_8 57 | } 58 | } 59 | 60 | repositories { 61 | mavenCentral() 62 | jcenter() 63 | google() 64 | 65 | def found = false 66 | def defaultDir = null 67 | def androidSourcesName = 'React Native sources' 68 | 69 | if (rootProject.ext.has('reactNativeAndroidRoot')) { 70 | defaultDir = rootProject.ext.get('reactNativeAndroidRoot') 71 | } else { 72 | defaultDir = new File( 73 | projectDir, 74 | '/../../../node_modules/react-native/android' 75 | ) 76 | } 77 | 78 | if (defaultDir.exists()) { 79 | maven { 80 | url defaultDir.toString() 81 | name androidSourcesName 82 | } 83 | 84 | logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}") 85 | found = true 86 | } else { 87 | def parentDir = rootProject.projectDir 88 | 89 | 1.upto(5, { 90 | if (found) return true 91 | parentDir = parentDir.parentFile 92 | 93 | def androidSourcesDir = new File( 94 | parentDir, 95 | 'node_modules/react-native' 96 | ) 97 | 98 | def androidPrebuiltBinaryDir = new File( 99 | parentDir, 100 | 'node_modules/react-native/android' 101 | ) 102 | 103 | if (androidPrebuiltBinaryDir.exists()) { 104 | maven { 105 | url androidPrebuiltBinaryDir.toString() 106 | name androidSourcesName 107 | } 108 | 109 | logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}") 110 | found = true 111 | } else if (androidSourcesDir.exists()) { 112 | maven { 113 | url androidSourcesDir.toString() 114 | name androidSourcesName 115 | } 116 | 117 | logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}") 118 | found = true 119 | } 120 | }) 121 | } 122 | 123 | if (!found) { 124 | throw new GradleException( 125 | "${project.name}: unable to locate React Native android sources. " + 126 | "Ensure you have you installed React Native as a dependency in your project and try again." 127 | ) 128 | } 129 | } 130 | 131 | def kotlin_version = getExtOrDefault('kotlinVersion') 132 | 133 | dependencies { 134 | //noinspection GradleDynamicVersion 135 | implementation 'com.facebook.react:react-native:+' 136 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 137 | implementation files('libs/tbs_sdk_thirdapp_v4.3.0.67_43967_sharewithdownloadwithfile_withoutGame_obfs_20200923_120452.jar') 138 | } 139 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | ReactNativeWebView_kotlinVersion=1.3.50 2 | ReactNativeWebView_compileSdkVersion=29 3 | ReactNativeWebView_buildToolsVersion=29.0.3 4 | ReactNativeWebView_targetSdkVersion=28 -------------------------------------------------------------------------------- /android/libs/tbs_sdk_thirdapp_v4.3.0.67_43967_sharewithdownloadwithfile_withoutGame_obfs_20200923_120452.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainDrop-C/react-native-webview-tencentx5/1a8642f02ebda5a829bd19398cf4ef07b3f0d571/android/libs/tbs_sdk_thirdapp_v4.3.0.67_43967_sharewithdownloadwithfile_withoutGame_obfs_20200923_120452.jar -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/RNX5WebViewFileProvider.java: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5; 2 | 3 | import androidx.core.content.FileProvider; 4 | 5 | /** 6 | * Providing a custom {@code FileProvider} prevents manifest {@code } name collisions. 7 | *

8 | * See https://developer.android.com/guide/topics/manifest/provider-element.html for details. 9 | */ 10 | public class RNX5WebViewFileProvider extends FileProvider { 11 | 12 | // This class intentionally left blank. 13 | 14 | } 15 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/RNX5WebViewModule.java: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.app.DownloadManager; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.content.pm.PackageManager; 9 | import android.net.Uri; 10 | import android.os.Build; 11 | import android.os.Environment; 12 | import android.os.Parcelable; 13 | import android.provider.MediaStore; 14 | 15 | import androidx.annotation.Nullable; 16 | import androidx.annotation.RequiresApi; 17 | import androidx.core.content.ContextCompat; 18 | import androidx.core.content.FileProvider; 19 | import androidx.core.util.Pair; 20 | 21 | import android.util.Log; 22 | import android.webkit.MimeTypeMap; 23 | import com.tencent.smtt.sdk.ValueCallback; 24 | import com.tencent.smtt.sdk.WebChromeClient; 25 | import android.widget.Toast; 26 | 27 | import com.facebook.react.bridge.ActivityEventListener; 28 | import com.facebook.react.bridge.Promise; 29 | import com.facebook.react.bridge.ReactApplicationContext; 30 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 31 | import com.facebook.react.bridge.ReactMethod; 32 | import com.facebook.react.module.annotations.ReactModule; 33 | import com.facebook.react.modules.core.PermissionAwareActivity; 34 | import com.facebook.react.modules.core.PermissionListener; 35 | 36 | import java.io.File; 37 | import java.io.IOException; 38 | import java.util.ArrayList; 39 | import java.util.Arrays; 40 | import java.util.HashMap; 41 | import java.util.concurrent.atomic.AtomicReference; 42 | 43 | import static android.app.Activity.RESULT_OK; 44 | 45 | @ReactModule(name = RNX5WebViewModule.MODULE_NAME) 46 | public class RNX5WebViewModule extends ReactContextBaseJavaModule implements ActivityEventListener { 47 | public static final String MODULE_NAME = "RNX5WebView"; 48 | private static final int PICKER = 1; 49 | private static final int PICKER_LEGACY = 3; 50 | private static final int FILE_DOWNLOAD_PERMISSION_REQUEST = 1; 51 | private ValueCallback filePathCallbackLegacy; 52 | private ValueCallback filePathCallback; 53 | private File outputImage; 54 | private File outputVideo; 55 | private DownloadManager.Request downloadRequest; 56 | 57 | protected static class ShouldOverrideUrlLoadingLock { 58 | protected enum ShouldOverrideCallbackState { 59 | UNDECIDED, 60 | SHOULD_OVERRIDE, 61 | DO_NOT_OVERRIDE, 62 | } 63 | 64 | private int nextLockIdentifier = 1; 65 | private final HashMap> shouldOverrideLocks = new HashMap<>(); 66 | 67 | public synchronized Pair> getNewLock() { 68 | final int lockIdentifier = nextLockIdentifier++; 69 | final AtomicReference shouldOverride = new AtomicReference<>(ShouldOverrideCallbackState.UNDECIDED); 70 | shouldOverrideLocks.put(lockIdentifier, shouldOverride); 71 | return new Pair<>(lockIdentifier, shouldOverride); 72 | } 73 | 74 | @Nullable 75 | public synchronized AtomicReference getLock(Integer lockIdentifier) { 76 | return shouldOverrideLocks.get(lockIdentifier); 77 | } 78 | 79 | public synchronized void removeLock(Integer lockIdentifier) { 80 | shouldOverrideLocks.remove(lockIdentifier); 81 | } 82 | } 83 | 84 | protected static final ShouldOverrideUrlLoadingLock shouldOverrideUrlLoadingLock = new ShouldOverrideUrlLoadingLock(); 85 | 86 | private enum MimeType { 87 | DEFAULT("*/*"), 88 | IMAGE("image"), 89 | VIDEO("video"); 90 | 91 | private final String value; 92 | 93 | MimeType(String value) { 94 | this.value = value; 95 | } 96 | } 97 | 98 | private PermissionListener webviewFileDownloaderPermissionListener = new PermissionListener() { 99 | @Override 100 | public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 101 | switch (requestCode) { 102 | case FILE_DOWNLOAD_PERMISSION_REQUEST: { 103 | // If request is cancelled, the result arrays are empty. 104 | if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 105 | if (downloadRequest != null) { 106 | downloadFile(); 107 | } 108 | } else { 109 | Toast.makeText(getCurrentActivity().getApplicationContext(), "Cannot download files as permission was denied. Please provide permission to write to storage, in order to download files.", Toast.LENGTH_LONG).show(); 110 | } 111 | return true; 112 | } 113 | } 114 | return false; 115 | } 116 | }; 117 | 118 | public RNX5WebViewModule(ReactApplicationContext reactContext) { 119 | super(reactContext); 120 | reactContext.addActivityEventListener(this); 121 | } 122 | 123 | @Override 124 | public String getName() { 125 | return MODULE_NAME; 126 | } 127 | 128 | @ReactMethod 129 | public void isFileUploadSupported(final Promise promise) { 130 | Boolean result = false; 131 | int current = Build.VERSION.SDK_INT; 132 | if (current >= Build.VERSION_CODES.LOLLIPOP) { 133 | result = true; 134 | } 135 | if (current >= Build.VERSION_CODES.JELLY_BEAN && current <= Build.VERSION_CODES.JELLY_BEAN_MR2) { 136 | result = true; 137 | } 138 | promise.resolve(result); 139 | } 140 | 141 | @ReactMethod(isBlockingSynchronousMethod = true) 142 | public void onShouldStartLoadWithRequestCallback(final boolean shouldStart, final int lockIdentifier) { 143 | final AtomicReference lockObject = shouldOverrideUrlLoadingLock.getLock(lockIdentifier); 144 | if (lockObject != null) { 145 | synchronized (lockObject) { 146 | lockObject.set(shouldStart ? ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.DO_NOT_OVERRIDE : ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.SHOULD_OVERRIDE); 147 | lockObject.notify(); 148 | } 149 | } 150 | } 151 | 152 | public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { 153 | 154 | if (filePathCallback == null && filePathCallbackLegacy == null) { 155 | return; 156 | } 157 | 158 | boolean imageTaken = false; 159 | boolean videoTaken = false; 160 | 161 | if (outputImage != null && outputImage.length() > 0) { 162 | imageTaken = true; 163 | } 164 | if (outputVideo != null && outputVideo.length() > 0) { 165 | videoTaken = true; 166 | } 167 | 168 | // based off of which button was pressed, we get an activity result and a file 169 | // the camera activity doesn't properly return the filename* (I think?) so we use 170 | // this filename instead 171 | switch (requestCode) { 172 | case PICKER: 173 | if (resultCode != RESULT_OK) { 174 | if (filePathCallback != null) { 175 | filePathCallback.onReceiveValue(null); 176 | } 177 | } else { 178 | if (imageTaken) { 179 | filePathCallback.onReceiveValue(new Uri[]{getOutputUri(outputImage)}); 180 | } else if (videoTaken) { 181 | filePathCallback.onReceiveValue(new Uri[]{getOutputUri(outputVideo)}); 182 | } else { 183 | filePathCallback.onReceiveValue(this.getSelectedFiles(data, resultCode)); 184 | } 185 | } 186 | break; 187 | case PICKER_LEGACY: 188 | if (resultCode != RESULT_OK) { 189 | filePathCallbackLegacy.onReceiveValue(null); 190 | } else { 191 | if (imageTaken) { 192 | filePathCallbackLegacy.onReceiveValue(getOutputUri(outputImage)); 193 | } else if (videoTaken) { 194 | filePathCallbackLegacy.onReceiveValue(getOutputUri(outputVideo)); 195 | } else { 196 | filePathCallbackLegacy.onReceiveValue(data.getData()); 197 | } 198 | } 199 | break; 200 | 201 | } 202 | 203 | if (outputImage != null && !imageTaken) { 204 | outputImage.delete(); 205 | } 206 | if (outputVideo != null && !videoTaken) { 207 | outputVideo.delete(); 208 | } 209 | 210 | filePathCallback = null; 211 | filePathCallbackLegacy = null; 212 | outputImage = null; 213 | outputVideo = null; 214 | } 215 | 216 | public void onNewIntent(Intent intent) { 217 | } 218 | 219 | private Uri[] getSelectedFiles(Intent data, int resultCode) { 220 | if (data == null) { 221 | return null; 222 | } 223 | 224 | // we have multiple files selected 225 | if (data.getClipData() != null) { 226 | final int numSelectedFiles = data.getClipData().getItemCount(); 227 | Uri[] result = new Uri[numSelectedFiles]; 228 | for (int i = 0; i < numSelectedFiles; i++) { 229 | result[i] = data.getClipData().getItemAt(i).getUri(); 230 | } 231 | return result; 232 | } 233 | 234 | // we have one file selected 235 | if (data.getData() != null && resultCode == RESULT_OK && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 236 | return WebChromeClient.FileChooserParams.parseResult(resultCode, data); 237 | } 238 | 239 | return null; 240 | } 241 | 242 | public void startPhotoPickerIntent(ValueCallback filePathCallback, String acceptType) { 243 | filePathCallbackLegacy = filePathCallback; 244 | 245 | Intent fileChooserIntent = getFileChooserIntent(acceptType); 246 | Intent chooserIntent = Intent.createChooser(fileChooserIntent, ""); 247 | 248 | ArrayList extraIntents = new ArrayList<>(); 249 | if (acceptsImages(acceptType)) { 250 | Intent photoIntent = getPhotoIntent(); 251 | if (photoIntent != null) { 252 | extraIntents.add(photoIntent); 253 | } 254 | } 255 | if (acceptsVideo(acceptType)) { 256 | Intent videoIntent = getVideoIntent(); 257 | if (videoIntent != null) { 258 | extraIntents.add(videoIntent); 259 | } 260 | } 261 | chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{})); 262 | 263 | if (chooserIntent.resolveActivity(getCurrentActivity().getPackageManager()) != null) { 264 | getCurrentActivity().startActivityForResult(chooserIntent, PICKER_LEGACY); 265 | } else { 266 | Log.w("RNX5WebViewModule", "there is no Activity to handle this Intent"); 267 | } 268 | } 269 | 270 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 271 | public boolean startPhotoPickerIntent(final ValueCallback callback, final String[] acceptTypes, final boolean allowMultiple) { 272 | filePathCallback = callback; 273 | 274 | ArrayList extraIntents = new ArrayList<>(); 275 | if (!needsCameraPermission()) { 276 | if (acceptsImages(acceptTypes)) { 277 | Intent photoIntent = getPhotoIntent(); 278 | if (photoIntent != null) { 279 | extraIntents.add(photoIntent); 280 | } 281 | } 282 | if (acceptsVideo(acceptTypes)) { 283 | Intent videoIntent = getVideoIntent(); 284 | if (videoIntent != null) { 285 | extraIntents.add(videoIntent); 286 | } 287 | } 288 | } 289 | 290 | Intent fileSelectionIntent = getFileChooserIntent(acceptTypes, allowMultiple); 291 | 292 | Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); 293 | chooserIntent.putExtra(Intent.EXTRA_INTENT, fileSelectionIntent); 294 | chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{})); 295 | 296 | if (chooserIntent.resolveActivity(getCurrentActivity().getPackageManager()) != null) { 297 | getCurrentActivity().startActivityForResult(chooserIntent, PICKER); 298 | } else { 299 | Log.w("RNX5WebViewModule", "there is no Activity to handle this Intent"); 300 | } 301 | 302 | return true; 303 | } 304 | 305 | public void setDownloadRequest(DownloadManager.Request request) { 306 | this.downloadRequest = request; 307 | } 308 | 309 | public void downloadFile() { 310 | DownloadManager dm = (DownloadManager) getCurrentActivity().getBaseContext().getSystemService(Context.DOWNLOAD_SERVICE); 311 | String downloadMessage = "Downloading"; 312 | 313 | dm.enqueue(this.downloadRequest); 314 | 315 | Toast.makeText(getCurrentActivity().getApplicationContext(), downloadMessage, Toast.LENGTH_LONG).show(); 316 | } 317 | 318 | public boolean grantFileDownloaderPermissions() { 319 | // Permission not required for Android Q and above 320 | if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { 321 | return true; 322 | } 323 | 324 | boolean result = ContextCompat.checkSelfPermission(getCurrentActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; 325 | if (!result && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 326 | PermissionAwareActivity activity = getPermissionAwareActivity(); 327 | activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, FILE_DOWNLOAD_PERMISSION_REQUEST, webviewFileDownloaderPermissionListener); 328 | } 329 | 330 | return result; 331 | } 332 | 333 | protected boolean needsCameraPermission() { 334 | boolean needed = false; 335 | 336 | PackageManager packageManager = getCurrentActivity().getPackageManager(); 337 | try { 338 | String[] requestedPermissions = packageManager.getPackageInfo(getReactApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions; 339 | if (Arrays.asList(requestedPermissions).contains(Manifest.permission.CAMERA) 340 | && ContextCompat.checkSelfPermission(getCurrentActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { 341 | needed = true; 342 | } 343 | } catch (PackageManager.NameNotFoundException e) { 344 | needed = true; 345 | } 346 | 347 | return needed; 348 | } 349 | 350 | private Intent getPhotoIntent() { 351 | Intent intent = null; 352 | 353 | try { 354 | outputImage = getCapturedFile(MimeType.IMAGE); 355 | Uri outputImageUri = getOutputUri(outputImage); 356 | intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 357 | intent.putExtra(MediaStore.EXTRA_OUTPUT, outputImageUri); 358 | } catch (IOException | IllegalArgumentException e) { 359 | Log.e("CREATE FILE", "Error occurred while creating the File", e); 360 | e.printStackTrace(); 361 | } 362 | 363 | return intent; 364 | } 365 | 366 | private Intent getVideoIntent() { 367 | Intent intent = null; 368 | 369 | try { 370 | outputVideo = getCapturedFile(MimeType.VIDEO); 371 | Uri outputVideoUri = getOutputUri(outputVideo); 372 | intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 373 | intent.putExtra(MediaStore.EXTRA_OUTPUT, outputVideoUri); 374 | } catch (IOException | IllegalArgumentException e) { 375 | Log.e("CREATE FILE", "Error occurred while creating the File", e); 376 | e.printStackTrace(); 377 | } 378 | 379 | return intent; 380 | } 381 | 382 | private Intent getFileChooserIntent(String acceptTypes) { 383 | String _acceptTypes = acceptTypes; 384 | if (acceptTypes.isEmpty()) { 385 | _acceptTypes = MimeType.DEFAULT.value; 386 | } 387 | if (acceptTypes.matches("\\.\\w+")) { 388 | _acceptTypes = getMimeTypeFromExtension(acceptTypes.replace(".", "")); 389 | } 390 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 391 | intent.addCategory(Intent.CATEGORY_OPENABLE); 392 | intent.setType(_acceptTypes); 393 | return intent; 394 | } 395 | 396 | private Intent getFileChooserIntent(String[] acceptTypes, boolean allowMultiple) { 397 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 398 | intent.addCategory(Intent.CATEGORY_OPENABLE); 399 | intent.setType(MimeType.DEFAULT.value); 400 | intent.putExtra(Intent.EXTRA_MIME_TYPES, getAcceptedMimeType(acceptTypes)); 401 | intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple); 402 | return intent; 403 | } 404 | 405 | private Boolean acceptsImages(String types) { 406 | String mimeType = types; 407 | if (types.matches("\\.\\w+")) { 408 | mimeType = getMimeTypeFromExtension(types.replace(".", "")); 409 | } 410 | return mimeType.isEmpty() || mimeType.toLowerCase().contains(MimeType.IMAGE.value); 411 | } 412 | 413 | private Boolean acceptsImages(String[] types) { 414 | String[] mimeTypes = getAcceptedMimeType(types); 415 | return arrayContainsString(mimeTypes, MimeType.DEFAULT.value) || arrayContainsString(mimeTypes, MimeType.IMAGE.value); 416 | } 417 | 418 | private Boolean acceptsVideo(String types) { 419 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 420 | return false; 421 | } 422 | 423 | String mimeType = types; 424 | if (types.matches("\\.\\w+")) { 425 | mimeType = getMimeTypeFromExtension(types.replace(".", "")); 426 | } 427 | return mimeType.isEmpty() || mimeType.toLowerCase().contains(MimeType.VIDEO.value); 428 | } 429 | 430 | private Boolean acceptsVideo(String[] types) { 431 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 432 | return false; 433 | } 434 | 435 | String[] mimeTypes = getAcceptedMimeType(types); 436 | return arrayContainsString(mimeTypes, MimeType.DEFAULT.value) || arrayContainsString(mimeTypes, MimeType.VIDEO.value); 437 | } 438 | 439 | private Boolean arrayContainsString(String[] array, String pattern) { 440 | for (String content : array) { 441 | if (content.contains(pattern)) { 442 | return true; 443 | } 444 | } 445 | return false; 446 | } 447 | 448 | private String[] getAcceptedMimeType(String[] types) { 449 | if (noAcceptTypesSet(types)) { 450 | return new String[]{MimeType.DEFAULT.value}; 451 | } 452 | String[] mimeTypes = new String[types.length]; 453 | for (int i = 0; i < types.length; i++) { 454 | String t = types[i]; 455 | // convert file extensions to mime types 456 | if (t.matches("\\.\\w+")) { 457 | String mimeType = getMimeTypeFromExtension(t.replace(".", "")); 458 | if(mimeType != null) { 459 | mimeTypes[i] = mimeType; 460 | } else { 461 | mimeTypes[i] = t; 462 | } 463 | } else { 464 | mimeTypes[i] = t; 465 | } 466 | } 467 | return mimeTypes; 468 | } 469 | 470 | private String getMimeTypeFromExtension(String extension) { 471 | String type = null; 472 | if (extension != null) { 473 | type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); 474 | } 475 | return type; 476 | } 477 | 478 | private Uri getOutputUri(File capturedFile) { 479 | // for versions below 6.0 (23) we use the old File creation & permissions model 480 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 481 | return Uri.fromFile(capturedFile); 482 | } 483 | 484 | // for versions 6.0+ (23) we use the FileProvider to avoid runtime permissions 485 | String packageName = getReactApplicationContext().getPackageName(); 486 | return FileProvider.getUriForFile(getReactApplicationContext(), packageName + ".fileprovider", capturedFile); 487 | } 488 | 489 | private File getCapturedFile(MimeType mimeType) throws IOException { 490 | String prefix = ""; 491 | String suffix = ""; 492 | String dir = ""; 493 | 494 | switch (mimeType) { 495 | case IMAGE: 496 | prefix = "image-"; 497 | suffix = ".jpg"; 498 | dir = Environment.DIRECTORY_PICTURES; 499 | break; 500 | case VIDEO: 501 | prefix = "video-"; 502 | suffix = ".mp4"; 503 | dir = Environment.DIRECTORY_MOVIES; 504 | break; 505 | 506 | default: 507 | break; 508 | } 509 | 510 | String filename = prefix + String.valueOf(System.currentTimeMillis()) + suffix; 511 | File outputFile = null; 512 | 513 | // for versions below 6.0 (23) we use the old File creation & permissions model 514 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 515 | // only this Directory works on all tested Android versions 516 | // ctx.getExternalFilesDir(dir) was failing on Android 5.0 (sdk 21) 517 | File storageDir = Environment.getExternalStoragePublicDirectory(dir); 518 | outputFile = new File(storageDir, filename); 519 | } else { 520 | File storageDir = getReactApplicationContext().getExternalFilesDir(null); 521 | outputFile = File.createTempFile(prefix, suffix, storageDir); 522 | } 523 | 524 | return outputFile; 525 | } 526 | 527 | private Boolean noAcceptTypesSet(String[] types) { 528 | // when our array returned from getAcceptTypes() has no values set from the webview 529 | // i.e. , without any "accept" attr 530 | // will be an array with one empty string element, afaik 531 | 532 | return types.length == 0 || (types.length == 1 && types[0] != null && types[0].length() == 0); 533 | } 534 | 535 | private PermissionAwareActivity getPermissionAwareActivity() { 536 | Activity activity = getCurrentActivity(); 537 | if (activity == null) { 538 | throw new IllegalStateException("Tried to use permissions API while not attached to an Activity."); 539 | } else if (!(activity instanceof PermissionAwareActivity)) { 540 | throw new IllegalStateException("Tried to use permissions API but the host Activity doesn't implement PermissionAwareActivity."); 541 | } 542 | return (PermissionAwareActivity) activity; 543 | } 544 | } 545 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/RNX5WebViewPackage.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5 2 | 3 | import com.facebook.react.ReactPackage 4 | import com.facebook.react.bridge.ReactApplicationContext 5 | 6 | 7 | class RNX5WebViewPackage: ReactPackage { 8 | override fun createNativeModules(reactContext: ReactApplicationContext) = listOf( 9 | RNX5WebViewModule(reactContext) 10 | ) 11 | 12 | override fun createViewManagers(reactContext: ReactApplicationContext) = listOf( 13 | RNX5WebViewManager() 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/WebViewConfig.java: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5; 2 | 3 | import com.tencent.smtt.sdk.WebView; 4 | 5 | /** 6 | * Implement this interface in order to config your {@link WebView}. An instance of that 7 | * implementation will have to be given as a constructor argument to {@link RNX5WebViewManager}. 8 | */ 9 | public interface WebViewConfig { 10 | 11 | void configWebView(WebView webView); 12 | } 13 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/events/TopHttpErrorEvent.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5.events 2 | 3 | import com.facebook.react.bridge.WritableMap 4 | import com.facebook.react.uimanager.events.Event 5 | import com.facebook.react.uimanager.events.RCTEventEmitter 6 | 7 | /** 8 | * Event emitted when a http error is received from the server. 9 | */ 10 | class TopHttpErrorEvent(viewId: Int, private val mEventData: WritableMap) : 11 | Event(viewId) { 12 | companion object { 13 | const val EVENT_NAME = "topHttpError" 14 | } 15 | 16 | override fun getEventName(): String = EVENT_NAME 17 | 18 | override fun canCoalesce(): Boolean = false 19 | 20 | override fun getCoalescingKey(): Short = 0 21 | 22 | override fun dispatch(rctEventEmitter: RCTEventEmitter) = 23 | rctEventEmitter.receiveEvent(viewTag, eventName, mEventData) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/events/TopLoadingErrorEvent.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5.events 2 | 3 | import com.facebook.react.bridge.WritableMap 4 | import com.facebook.react.uimanager.events.Event 5 | import com.facebook.react.uimanager.events.RCTEventEmitter 6 | 7 | /** 8 | * Event emitted when there is an error in loading. 9 | */ 10 | class TopLoadingErrorEvent(viewId: Int, private val mEventData: WritableMap) : 11 | Event(viewId) { 12 | companion object { 13 | const val EVENT_NAME = "topLoadingError" 14 | } 15 | 16 | override fun getEventName(): String = EVENT_NAME 17 | 18 | override fun canCoalesce(): Boolean = false 19 | 20 | override fun getCoalescingKey(): Short = 0 21 | 22 | override fun dispatch(rctEventEmitter: RCTEventEmitter) = 23 | rctEventEmitter.receiveEvent(viewTag, eventName, mEventData) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/events/TopLoadingFinishEvent.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5.events 2 | 3 | import com.facebook.react.bridge.WritableMap 4 | import com.facebook.react.uimanager.events.Event 5 | import com.facebook.react.uimanager.events.RCTEventEmitter 6 | 7 | /** 8 | * Event emitted when loading is completed. 9 | */ 10 | class TopLoadingFinishEvent(viewId: Int, private val mEventData: WritableMap) : 11 | Event(viewId) { 12 | companion object { 13 | const val EVENT_NAME = "topLoadingFinish" 14 | } 15 | 16 | override fun getEventName(): String = EVENT_NAME 17 | 18 | override fun canCoalesce(): Boolean = false 19 | 20 | override fun getCoalescingKey(): Short = 0 21 | 22 | override fun dispatch(rctEventEmitter: RCTEventEmitter) = 23 | rctEventEmitter.receiveEvent(viewTag, eventName, mEventData) 24 | } 25 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/events/TopLoadingProgressEvent.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5.events 2 | 3 | import com.facebook.react.bridge.WritableMap 4 | import com.facebook.react.uimanager.events.Event 5 | import com.facebook.react.uimanager.events.RCTEventEmitter 6 | 7 | /** 8 | * Event emitted when there is a loading progress event. 9 | */ 10 | class TopLoadingProgressEvent(viewId: Int, private val mEventData: WritableMap) : 11 | Event(viewId) { 12 | companion object { 13 | const val EVENT_NAME = "topLoadingProgress" 14 | } 15 | 16 | override fun getEventName(): String = EVENT_NAME 17 | 18 | override fun canCoalesce(): Boolean = false 19 | 20 | override fun getCoalescingKey(): Short = 0 21 | 22 | override fun dispatch(rctEventEmitter: RCTEventEmitter) = 23 | rctEventEmitter.receiveEvent(viewTag, eventName, mEventData) 24 | } 25 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/events/TopLoadingStartEvent.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5.events 2 | 3 | import com.facebook.react.bridge.WritableMap 4 | import com.facebook.react.uimanager.events.Event 5 | import com.facebook.react.uimanager.events.RCTEventEmitter 6 | 7 | /** 8 | * Event emitted when loading has started 9 | */ 10 | class TopLoadingStartEvent(viewId: Int, private val mEventData: WritableMap) : 11 | Event(viewId) { 12 | companion object { 13 | const val EVENT_NAME = "topLoadingStart" 14 | } 15 | 16 | override fun getEventName(): String = EVENT_NAME 17 | 18 | override fun canCoalesce(): Boolean = false 19 | 20 | override fun getCoalescingKey(): Short = 0 21 | 22 | override fun dispatch(rctEventEmitter: RCTEventEmitter) = 23 | rctEventEmitter.receiveEvent(viewTag, eventName, mEventData) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/events/TopMessageEvent.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5.events 2 | 3 | import com.facebook.react.bridge.WritableMap 4 | import com.facebook.react.uimanager.events.Event 5 | import com.facebook.react.uimanager.events.RCTEventEmitter 6 | 7 | /** 8 | * Event emitted when there is an error in loading. 9 | */ 10 | class TopMessageEvent(viewId: Int, private val mEventData: WritableMap) : Event(viewId) { 11 | companion object { 12 | const val EVENT_NAME = "topMessage" 13 | } 14 | 15 | override fun getEventName(): String = EVENT_NAME 16 | 17 | override fun canCoalesce(): Boolean = false 18 | 19 | override fun getCoalescingKey(): Short = 0 20 | 21 | override fun dispatch(rctEventEmitter: RCTEventEmitter) { 22 | rctEventEmitter.receiveEvent(viewTag, EVENT_NAME, mEventData) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/events/TopRenderProcessGoneEvent.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5.events 2 | 3 | import com.facebook.react.bridge.WritableMap 4 | import com.facebook.react.uimanager.events.Event 5 | import com.facebook.react.uimanager.events.RCTEventEmitter 6 | 7 | /** 8 | * Event emitted when the WebView's process has crashed or 9 | was killed by the OS. 10 | */ 11 | class TopRenderProcessGoneEvent(viewId: Int, private val mEventData: WritableMap) : 12 | Event(viewId) { 13 | companion object { 14 | const val EVENT_NAME = "topRenderProcessGone" 15 | } 16 | 17 | override fun getEventName(): String = EVENT_NAME 18 | 19 | override fun canCoalesce(): Boolean = false 20 | 21 | override fun getCoalescingKey(): Short = 0 22 | 23 | override fun dispatch(rctEventEmitter: RCTEventEmitter) = 24 | rctEventEmitter.receiveEvent(viewTag, eventName, mEventData) 25 | 26 | } 27 | -------------------------------------------------------------------------------- /android/src/main/java/indi/fan/webviewx5/events/TopShouldStartLoadWithRequestEvent.kt: -------------------------------------------------------------------------------- 1 | package indi.fan.webviewx5.events 2 | 3 | import com.facebook.react.bridge.WritableMap 4 | import com.facebook.react.uimanager.events.Event 5 | import com.facebook.react.uimanager.events.RCTEventEmitter 6 | 7 | /** 8 | * Event emitted when shouldOverrideUrlLoading is called 9 | */ 10 | class TopShouldStartLoadWithRequestEvent(viewId: Int, private val mData: WritableMap) : Event(viewId) { 11 | companion object { 12 | const val EVENT_NAME = "topShouldStartLoadWithRequest" 13 | } 14 | 15 | init { 16 | mData.putString("navigationType", "other") 17 | // Android does not raise shouldOverrideUrlLoading for inner frames 18 | mData.putBoolean("isTopFrame", true) 19 | } 20 | 21 | override fun getEventName(): String = EVENT_NAME 22 | 23 | override fun canCoalesce(): Boolean = false 24 | 25 | override fun getCoalescingKey(): Short = 0 26 | 27 | override fun dispatch(rctEventEmitter: RCTEventEmitter) = 28 | rctEventEmitter.receiveEvent(viewTag, EVENT_NAME, mData) 29 | } 30 | -------------------------------------------------------------------------------- /android/src/main/jniLibs/armeabi-v7a/liblbs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainDrop-C/react-native-webview-tencentx5/1a8642f02ebda5a829bd19398cf4ef07b3f0d571/android/src/main/jniLibs/armeabi-v7a/liblbs.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/armeabi/liblbs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainDrop-C/react-native-webview-tencentx5/1a8642f02ebda5a829bd19398cf4ef07b3f0d571/android/src/main/jniLibs/armeabi/liblbs.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/mips/liblbs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainDrop-C/react-native-webview-tencentx5/1a8642f02ebda5a829bd19398cf4ef07b3f0d571/android/src/main/jniLibs/mips/liblbs.so -------------------------------------------------------------------------------- /android/src/main/jniLibs/x86/liblbs.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainDrop-C/react-native-webview-tencentx5/1a8642f02ebda5a829bd19398cf4ef07b3f0d571/android/src/main/jniLibs/x86/liblbs.so -------------------------------------------------------------------------------- /android/src/main/res/xml/file_provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /apple/RNCWKProcessPoolManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | @interface RNCWKProcessPoolManager : NSObject 11 | 12 | + (instancetype) sharedManager; 13 | - (WKProcessPool *)sharedProcessPool; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /apple/RNCWKProcessPoolManager.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import "RNCWKProcessPoolManager.h" 10 | 11 | @interface RNCWKProcessPoolManager() { 12 | WKProcessPool *_sharedProcessPool; 13 | } 14 | @end 15 | 16 | @implementation RNCWKProcessPoolManager 17 | 18 | + (id) sharedManager { 19 | static RNCWKProcessPoolManager *_sharedManager = nil; 20 | @synchronized(self) { 21 | if(_sharedManager == nil) { 22 | _sharedManager = [[super alloc] init]; 23 | } 24 | return _sharedManager; 25 | } 26 | } 27 | 28 | - (WKProcessPool *)sharedProcessPool { 29 | if (!_sharedProcessPool) { 30 | _sharedProcessPool = [[WKProcessPool alloc] init]; 31 | } 32 | return _sharedProcessPool; 33 | } 34 | 35 | @end 36 | 37 | -------------------------------------------------------------------------------- /apple/RNCWebView.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | @class RNCWebView; 13 | 14 | @protocol RNCWebViewDelegate 15 | 16 | - (BOOL)webView:(RNCWebView *_Nonnull)webView 17 | shouldStartLoadForRequest:(NSMutableDictionary *_Nonnull)request 18 | withCallback:(RCTDirectEventBlock _Nonnull)callback; 19 | 20 | @end 21 | 22 | @interface RNCWeakScriptMessageDelegate : NSObject 23 | 24 | @property (nonatomic, weak, nullable) id scriptDelegate; 25 | 26 | - (nullable instancetype)initWithDelegate:(id _Nullable)scriptDelegate; 27 | 28 | @end 29 | 30 | @interface RNCWebView : RCTView 31 | 32 | @property (nonatomic, weak) id _Nullable delegate; 33 | @property (nonatomic, copy) NSDictionary * _Nullable source; 34 | @property (nonatomic, assign) BOOL messagingEnabled; 35 | @property (nonatomic, copy) NSString * _Nullable injectedJavaScript; 36 | @property (nonatomic, copy) NSString * _Nullable injectedJavaScriptBeforeContentLoaded; 37 | @property (nonatomic, assign) BOOL injectedJavaScriptForMainFrameOnly; 38 | @property (nonatomic, assign) BOOL injectedJavaScriptBeforeContentLoadedForMainFrameOnly; 39 | @property (nonatomic, assign) BOOL scrollEnabled; 40 | @property (nonatomic, assign) BOOL sharedCookiesEnabled; 41 | @property (nonatomic, assign) BOOL autoManageStatusBarEnabled; 42 | @property (nonatomic, assign) BOOL pagingEnabled; 43 | @property (nonatomic, assign) CGFloat decelerationRate; 44 | @property (nonatomic, assign) BOOL allowsInlineMediaPlayback; 45 | @property (nonatomic, assign) BOOL bounces; 46 | @property (nonatomic, assign) BOOL mediaPlaybackRequiresUserAction; 47 | #if WEBKIT_IOS_10_APIS_AVAILABLE 48 | @property (nonatomic, assign) WKDataDetectorTypes dataDetectorTypes; 49 | #endif 50 | @property (nonatomic, assign) UIEdgeInsets contentInset; 51 | @property (nonatomic, assign) BOOL automaticallyAdjustContentInsets; 52 | @property (nonatomic, assign) BOOL keyboardDisplayRequiresUserAction; 53 | @property (nonatomic, assign) BOOL hideKeyboardAccessoryView; 54 | @property (nonatomic, assign) BOOL allowsBackForwardNavigationGestures; 55 | @property (nonatomic, assign) BOOL incognito; 56 | @property (nonatomic, assign) BOOL useSharedProcessPool; 57 | @property (nonatomic, copy) NSString * _Nullable userAgent; 58 | @property (nonatomic, copy) NSString * _Nullable applicationNameForUserAgent; 59 | @property (nonatomic, assign) BOOL cacheEnabled; 60 | @property (nonatomic, assign) BOOL javaScriptEnabled; 61 | @property (nonatomic, assign) BOOL javaScriptCanOpenWindowsAutomatically; 62 | @property (nonatomic, assign) BOOL allowFileAccessFromFileURLs; 63 | @property (nonatomic, assign) BOOL allowUniversalAccessFromFileURLs; 64 | @property (nonatomic, assign) BOOL allowsLinkPreview; 65 | @property (nonatomic, assign) BOOL showsHorizontalScrollIndicator; 66 | @property (nonatomic, assign) BOOL showsVerticalScrollIndicator; 67 | @property (nonatomic, assign) BOOL directionalLockEnabled; 68 | @property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch; 69 | @property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL; 70 | @property (nonatomic, assign) BOOL pullToRefreshEnabled; 71 | #if !TARGET_OS_OSX 72 | @property (nonatomic, weak) UIRefreshControl * _Nullable refreshControl; 73 | #endif 74 | 75 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ 76 | @property (nonatomic, assign) WKContentMode contentMode; 77 | #endif 78 | 79 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ 80 | @property (nonatomic, assign) BOOL limitsNavigationsToAppBoundDomains; 81 | #endif 82 | 83 | + (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential; 84 | + (void)setCustomCertificatesForHost:(nullable NSDictionary *)certificates; 85 | - (void)postMessage:(NSString *_Nullable)message; 86 | - (void)injectJavaScript:(NSString *_Nullable)script; 87 | - (void)goForward; 88 | - (void)goBack; 89 | - (void)reload; 90 | - (void)stopLoading; 91 | #if !TARGET_OS_OSX 92 | - (void)addPullToRefreshControl; 93 | - (void)pullToRefresh:(UIRefreshControl *_Nonnull)refreshControl; 94 | #endif 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /apple/RNCWebViewManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | @interface RNCWebViewManager : RCTViewManager 11 | @end 12 | -------------------------------------------------------------------------------- /apple/RNCWebViewManager.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "RNCWebViewManager.h" 9 | 10 | #import 11 | #import 12 | #import "RNCWebView.h" 13 | 14 | @interface RNCWebViewManager () 15 | @end 16 | 17 | @implementation RCTConvert (WKWebView) 18 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ 19 | RCT_ENUM_CONVERTER(WKContentMode, (@{ 20 | @"recommended": @(WKContentModeRecommended), 21 | @"mobile": @(WKContentModeMobile), 22 | @"desktop": @(WKContentModeDesktop), 23 | }), WKContentModeRecommended, integerValue) 24 | #endif 25 | @end 26 | 27 | @implementation RNCWebViewManager 28 | { 29 | NSConditionLock *_shouldStartLoadLock; 30 | BOOL _shouldStartLoad; 31 | } 32 | 33 | RCT_EXPORT_MODULE() 34 | 35 | #if !TARGET_OS_OSX 36 | - (UIView *)view 37 | #else 38 | - (RCTUIView *)view 39 | #endif // !TARGET_OS_OSX 40 | { 41 | RNCWebView *webView = [RNCWebView new]; 42 | webView.delegate = self; 43 | return webView; 44 | } 45 | 46 | RCT_EXPORT_VIEW_PROPERTY(source, NSDictionary) 47 | RCT_EXPORT_VIEW_PROPERTY(onFileDownload, RCTDirectEventBlock) 48 | RCT_EXPORT_VIEW_PROPERTY(onLoadingStart, RCTDirectEventBlock) 49 | RCT_EXPORT_VIEW_PROPERTY(onLoadingFinish, RCTDirectEventBlock) 50 | RCT_EXPORT_VIEW_PROPERTY(onLoadingError, RCTDirectEventBlock) 51 | RCT_EXPORT_VIEW_PROPERTY(onLoadingProgress, RCTDirectEventBlock) 52 | RCT_EXPORT_VIEW_PROPERTY(onHttpError, RCTDirectEventBlock) 53 | RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock) 54 | RCT_EXPORT_VIEW_PROPERTY(onContentProcessDidTerminate, RCTDirectEventBlock) 55 | RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString) 56 | RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptBeforeContentLoaded, NSString) 57 | RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptForMainFrameOnly, BOOL) 58 | RCT_EXPORT_VIEW_PROPERTY(injectedJavaScriptBeforeContentLoadedForMainFrameOnly, BOOL) 59 | RCT_EXPORT_VIEW_PROPERTY(javaScriptEnabled, BOOL) 60 | RCT_EXPORT_VIEW_PROPERTY(javaScriptCanOpenWindowsAutomatically, BOOL) 61 | RCT_EXPORT_VIEW_PROPERTY(allowFileAccessFromFileURLs, BOOL) 62 | RCT_EXPORT_VIEW_PROPERTY(allowUniversalAccessFromFileURLs, BOOL) 63 | RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL) 64 | RCT_EXPORT_VIEW_PROPERTY(mediaPlaybackRequiresUserAction, BOOL) 65 | #if WEBKIT_IOS_10_APIS_AVAILABLE 66 | RCT_EXPORT_VIEW_PROPERTY(dataDetectorTypes, WKDataDetectorTypes) 67 | #endif 68 | RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets) 69 | RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL) 70 | RCT_EXPORT_VIEW_PROPERTY(autoManageStatusBarEnabled, BOOL) 71 | RCT_EXPORT_VIEW_PROPERTY(hideKeyboardAccessoryView, BOOL) 72 | RCT_EXPORT_VIEW_PROPERTY(allowsBackForwardNavigationGestures, BOOL) 73 | RCT_EXPORT_VIEW_PROPERTY(incognito, BOOL) 74 | RCT_EXPORT_VIEW_PROPERTY(pagingEnabled, BOOL) 75 | RCT_EXPORT_VIEW_PROPERTY(userAgent, NSString) 76 | RCT_EXPORT_VIEW_PROPERTY(applicationNameForUserAgent, NSString) 77 | RCT_EXPORT_VIEW_PROPERTY(cacheEnabled, BOOL) 78 | RCT_EXPORT_VIEW_PROPERTY(allowsLinkPreview, BOOL) 79 | RCT_EXPORT_VIEW_PROPERTY(allowingReadAccessToURL, NSString) 80 | 81 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ 82 | RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior) 83 | #endif 84 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ 85 | RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustsScrollIndicatorInsets, BOOL) 86 | #endif 87 | 88 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ 89 | RCT_EXPORT_VIEW_PROPERTY(contentMode, WKContentMode) 90 | #endif 91 | 92 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ 93 | RCT_EXPORT_VIEW_PROPERTY(limitsNavigationsToAppBoundDomains, BOOL) 94 | #endif 95 | 96 | /** 97 | * Expose methods to enable messaging the webview. 98 | */ 99 | RCT_EXPORT_VIEW_PROPERTY(messagingEnabled, BOOL) 100 | RCT_EXPORT_VIEW_PROPERTY(onMessage, RCTDirectEventBlock) 101 | RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) 102 | 103 | RCT_EXPORT_METHOD(postMessage:(nonnull NSNumber *)reactTag message:(NSString *)message) 104 | { 105 | [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { 106 | RNCWebView *view = viewRegistry[reactTag]; 107 | if (![view isKindOfClass:[RNCWebView class]]) { 108 | RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); 109 | } else { 110 | [view postMessage:message]; 111 | } 112 | }]; 113 | } 114 | 115 | RCT_CUSTOM_VIEW_PROPERTY(pullToRefreshEnabled, BOOL, RNCWebView) { 116 | view.pullToRefreshEnabled = json == nil ? false : [RCTConvert BOOL: json]; 117 | } 118 | 119 | RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RNCWebView) { 120 | view.bounces = json == nil ? true : [RCTConvert BOOL: json]; 121 | } 122 | 123 | RCT_CUSTOM_VIEW_PROPERTY(useSharedProcessPool, BOOL, RNCWebView) { 124 | view.useSharedProcessPool = json == nil ? true : [RCTConvert BOOL: json]; 125 | } 126 | 127 | RCT_CUSTOM_VIEW_PROPERTY(scrollEnabled, BOOL, RNCWebView) { 128 | view.scrollEnabled = json == nil ? true : [RCTConvert BOOL: json]; 129 | } 130 | 131 | RCT_CUSTOM_VIEW_PROPERTY(sharedCookiesEnabled, BOOL, RNCWebView) { 132 | view.sharedCookiesEnabled = json == nil ? false : [RCTConvert BOOL: json]; 133 | } 134 | 135 | #if !TARGET_OS_OSX 136 | RCT_CUSTOM_VIEW_PROPERTY(decelerationRate, CGFloat, RNCWebView) { 137 | view.decelerationRate = json == nil ? UIScrollViewDecelerationRateNormal : [RCTConvert CGFloat: json]; 138 | } 139 | #endif // !TARGET_OS_OSX 140 | 141 | RCT_CUSTOM_VIEW_PROPERTY(directionalLockEnabled, BOOL, RNCWebView) { 142 | view.directionalLockEnabled = json == nil ? true : [RCTConvert BOOL: json]; 143 | } 144 | 145 | RCT_CUSTOM_VIEW_PROPERTY(showsHorizontalScrollIndicator, BOOL, RNCWebView) { 146 | view.showsHorizontalScrollIndicator = json == nil ? true : [RCTConvert BOOL: json]; 147 | } 148 | 149 | RCT_CUSTOM_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL, RNCWebView) { 150 | view.showsVerticalScrollIndicator = json == nil ? true : [RCTConvert BOOL: json]; 151 | } 152 | 153 | RCT_CUSTOM_VIEW_PROPERTY(keyboardDisplayRequiresUserAction, BOOL, RNCWebView) { 154 | view.keyboardDisplayRequiresUserAction = json == nil ? true : [RCTConvert BOOL: json]; 155 | } 156 | 157 | RCT_EXPORT_METHOD(injectJavaScript:(nonnull NSNumber *)reactTag script:(NSString *)script) 158 | { 159 | [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { 160 | RNCWebView *view = viewRegistry[reactTag]; 161 | if (![view isKindOfClass:[RNCWebView class]]) { 162 | RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); 163 | } else { 164 | [view injectJavaScript:script]; 165 | } 166 | }]; 167 | } 168 | 169 | RCT_EXPORT_METHOD(goBack:(nonnull NSNumber *)reactTag) 170 | { 171 | [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { 172 | RNCWebView *view = viewRegistry[reactTag]; 173 | if (![view isKindOfClass:[RNCWebView class]]) { 174 | RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); 175 | } else { 176 | [view goBack]; 177 | } 178 | }]; 179 | } 180 | 181 | RCT_EXPORT_METHOD(goForward:(nonnull NSNumber *)reactTag) 182 | { 183 | [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { 184 | RNCWebView *view = viewRegistry[reactTag]; 185 | if (![view isKindOfClass:[RNCWebView class]]) { 186 | RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); 187 | } else { 188 | [view goForward]; 189 | } 190 | }]; 191 | } 192 | 193 | RCT_EXPORT_METHOD(reload:(nonnull NSNumber *)reactTag) 194 | { 195 | [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { 196 | RNCWebView *view = viewRegistry[reactTag]; 197 | if (![view isKindOfClass:[RNCWebView class]]) { 198 | RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); 199 | } else { 200 | [view reload]; 201 | } 202 | }]; 203 | } 204 | 205 | RCT_EXPORT_METHOD(stopLoading:(nonnull NSNumber *)reactTag) 206 | { 207 | [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { 208 | RNCWebView *view = viewRegistry[reactTag]; 209 | if (![view isKindOfClass:[RNCWebView class]]) { 210 | RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); 211 | } else { 212 | [view stopLoading]; 213 | } 214 | }]; 215 | } 216 | 217 | #pragma mark - Exported synchronous methods 218 | 219 | - (BOOL) webView:(RNCWebView *)webView 220 | shouldStartLoadForRequest:(NSMutableDictionary *)request 221 | withCallback:(RCTDirectEventBlock)callback 222 | { 223 | _shouldStartLoadLock = [[NSConditionLock alloc] initWithCondition:arc4random()]; 224 | _shouldStartLoad = YES; 225 | request[@"lockIdentifier"] = @(_shouldStartLoadLock.condition); 226 | callback(request); 227 | 228 | // Block the main thread for a maximum of 250ms until the JS thread returns 229 | if ([_shouldStartLoadLock lockWhenCondition:0 beforeDate:[NSDate dateWithTimeIntervalSinceNow:.25]]) { 230 | BOOL returnValue = _shouldStartLoad; 231 | [_shouldStartLoadLock unlock]; 232 | _shouldStartLoadLock = nil; 233 | return returnValue; 234 | } else { 235 | RCTLogWarn(@"Did not receive response to shouldStartLoad in time, defaulting to YES"); 236 | return YES; 237 | } 238 | } 239 | 240 | RCT_EXPORT_METHOD(startLoadWithResult:(BOOL)result lockIdentifier:(NSInteger)lockIdentifier) 241 | { 242 | if ([_shouldStartLoadLock tryLockWhenCondition:lockIdentifier]) { 243 | _shouldStartLoad = result; 244 | [_shouldStartLoadLock unlockWithCondition:0]; 245 | } else { 246 | RCTLogWarn(@"startLoadWithResult invoked with invalid lockIdentifier: " 247 | "got %lld, expected %lld", (long long)lockIdentifier, (long long)_shouldStartLoadLock.condition); 248 | } 249 | } 250 | 251 | @end 252 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import { Component } from 'react'; 2 | // eslint-disable-next-line 3 | import { IOSWebViewProps, AndroidWebViewProps } from './lib/WebViewTypes'; 4 | 5 | export { FileDownload, WebViewMessageEvent, WebViewNavigation } from "./lib/WebViewTypes"; 6 | 7 | export type WebViewProps = IOSWebViewProps & AndroidWebViewProps; 8 | 9 | declare class WebView

extends Component { 10 | /** 11 | * Go back one page in the webview's history. 12 | */ 13 | goBack: () => void; 14 | 15 | /** 16 | * Go forward one page in the webview's history. 17 | */ 18 | goForward: () => void; 19 | 20 | /** 21 | * Reloads the current page. 22 | */ 23 | reload: () => void; 24 | 25 | /** 26 | * Stop loading the current page. 27 | */ 28 | stopLoading(): void; 29 | 30 | /** 31 | * Extra Native Component Config. 32 | */ 33 | extraNativeComponentConfig: () => any; 34 | 35 | /** 36 | * Executes the JavaScript string. 37 | */ 38 | injectJavaScript: (script: string) => void; 39 | 40 | /** 41 | * Focuses on WebView redered page. 42 | */ 43 | requestFocus: () => void; 44 | 45 | /** 46 | * Posts a message to WebView. 47 | */ 48 | postMessage: (message: string) => void; 49 | 50 | /** 51 | * (Android only) 52 | * Removes the autocomplete popup from the currently focused form field, if present. 53 | */ 54 | clearFormData: () => void; 55 | 56 | /** 57 | * (Android only) 58 | * Clears the resource cache. Note that the cache is per-application, so this will clear the cache for all WebViews used. 59 | */ 60 | clearCache: (clear: boolean) => void; 61 | 62 | /** 63 | * (Android only) 64 | * Tells this WebView to clear its internal back/forward list. 65 | */ 66 | clearHistory: () => void; 67 | } 68 | 69 | export {WebView}; 70 | export default WebView; 71 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import WebView from './lib/WebView'; 2 | 3 | export { WebView }; 4 | export default WebView; -------------------------------------------------------------------------------- /ios/RNCWebView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3515965E21A3C86000623BFA /* RNCWKProcessPoolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3515965D21A3C86000623BFA /* RNCWKProcessPoolManager.m */; }; 11 | E91B351D21446E6C00F9801F /* RNCWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351B21446E6C00F9801F /* RNCWebViewManager.m */; }; 12 | E91B351E21446E6C00F9801F /* RNCWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351C21446E6C00F9801F /* RNCWebView.m */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 2147483647; 19 | dstPath = "include/$(PRODUCT_NAME)"; 20 | dstSubfolderSpec = 16; 21 | files = ( 22 | ); 23 | runOnlyForDeploymentPostprocessing = 0; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 134814201AA4EA6300B7C361 /* libRNCWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCWebView.a; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 3515965D21A3C86000623BFA /* RNCWKProcessPoolManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNCWKProcessPoolManager.m; path = ../apple/RNCWKProcessPoolManager.m; sourceTree = ""; }; 30 | 3515965F21A3C87E00623BFA /* RNCWKProcessPoolManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNCWKProcessPoolManager.h; path = ../apple/RNCWKProcessPoolManager.h; sourceTree = ""; }; 31 | E91B351921446E6C00F9801F /* RNCWebViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNCWebViewManager.h; path = ../apple/RNCWebViewManager.h; sourceTree = ""; }; 32 | E91B351A21446E6C00F9801F /* RNCWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNCWebView.h; path = ../apple/RNCWebView.h; sourceTree = ""; }; 33 | E91B351B21446E6C00F9801F /* RNCWebViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNCWebViewManager.m; path = ../apple/RNCWebViewManager.m; sourceTree = ""; }; 34 | E91B351C21446E6C00F9801F /* RNCWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNCWebView.m; path = ../apple/RNCWebView.m; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | 134814211AA4EA7D00B7C361 /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 134814201AA4EA6300B7C361 /* libRNCWebView.a */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 58B511D21A9E6C8500147676 = { 57 | isa = PBXGroup; 58 | children = ( 59 | E91B351A21446E6C00F9801F /* RNCWebView.h */, 60 | E91B351C21446E6C00F9801F /* RNCWebView.m */, 61 | E91B351921446E6C00F9801F /* RNCWebViewManager.h */, 62 | E91B351B21446E6C00F9801F /* RNCWebViewManager.m */, 63 | 3515965F21A3C87E00623BFA /* RNCWKProcessPoolManager.h */, 64 | 3515965D21A3C86000623BFA /* RNCWKProcessPoolManager.m */, 65 | 134814211AA4EA7D00B7C361 /* Products */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | /* End PBXGroup section */ 70 | 71 | /* Begin PBXNativeTarget section */ 72 | 58B511DA1A9E6C8500147676 /* RNCWebView */ = { 73 | isa = PBXNativeTarget; 74 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCWebView" */; 75 | buildPhases = ( 76 | 58B511D71A9E6C8500147676 /* Sources */, 77 | 58B511D81A9E6C8500147676 /* Frameworks */, 78 | 58B511D91A9E6C8500147676 /* CopyFiles */, 79 | ); 80 | buildRules = ( 81 | ); 82 | dependencies = ( 83 | ); 84 | name = RNCWebView; 85 | productName = RCTDataManager; 86 | productReference = 134814201AA4EA6300B7C361 /* libRNCWebView.a */; 87 | productType = "com.apple.product-type.library.static"; 88 | }; 89 | /* End PBXNativeTarget section */ 90 | 91 | /* Begin PBXProject section */ 92 | 58B511D31A9E6C8500147676 /* Project object */ = { 93 | isa = PBXProject; 94 | attributes = { 95 | LastUpgradeCheck = 0830; 96 | ORGANIZATIONNAME = Facebook; 97 | TargetAttributes = { 98 | 58B511DA1A9E6C8500147676 = { 99 | CreatedOnToolsVersion = 6.1.1; 100 | }; 101 | }; 102 | }; 103 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCWebView" */; 104 | compatibilityVersion = "Xcode 3.2"; 105 | developmentRegion = en; 106 | hasScannedForEncodings = 0; 107 | knownRegions = ( 108 | en, 109 | ); 110 | mainGroup = 58B511D21A9E6C8500147676; 111 | productRefGroup = 58B511D21A9E6C8500147676; 112 | projectDirPath = ""; 113 | projectRoot = ""; 114 | targets = ( 115 | 58B511DA1A9E6C8500147676 /* RNCWebView */, 116 | ); 117 | }; 118 | /* End PBXProject section */ 119 | 120 | /* Begin PBXSourcesBuildPhase section */ 121 | 58B511D71A9E6C8500147676 /* Sources */ = { 122 | isa = PBXSourcesBuildPhase; 123 | buildActionMask = 2147483647; 124 | files = ( 125 | E91B351D21446E6C00F9801F /* RNCWebViewManager.m in Sources */, 126 | E91B351E21446E6C00F9801F /* RNCWebView.m in Sources */, 127 | 3515965E21A3C86000623BFA /* RNCWKProcessPoolManager.m in Sources */, 128 | ); 129 | runOnlyForDeploymentPostprocessing = 0; 130 | }; 131 | /* End PBXSourcesBuildPhase section */ 132 | 133 | /* Begin XCBuildConfiguration section */ 134 | 58B511ED1A9E6C8500147676 /* Debug */ = { 135 | isa = XCBuildConfiguration; 136 | buildSettings = { 137 | ALWAYS_SEARCH_USER_PATHS = NO; 138 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 139 | CLANG_CXX_LIBRARY = "libc++"; 140 | CLANG_ENABLE_MODULES = YES; 141 | CLANG_ENABLE_OBJC_ARC = YES; 142 | CLANG_WARN_BOOL_CONVERSION = YES; 143 | CLANG_WARN_CONSTANT_CONVERSION = YES; 144 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 145 | CLANG_WARN_EMPTY_BODY = YES; 146 | CLANG_WARN_ENUM_CONVERSION = YES; 147 | CLANG_WARN_INFINITE_RECURSION = YES; 148 | CLANG_WARN_INT_CONVERSION = YES; 149 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 150 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 151 | CLANG_WARN_UNREACHABLE_CODE = YES; 152 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 153 | COPY_PHASE_STRIP = NO; 154 | ENABLE_STRICT_OBJC_MSGSEND = YES; 155 | ENABLE_TESTABILITY = YES; 156 | GCC_C_LANGUAGE_STANDARD = gnu99; 157 | GCC_DYNAMIC_NO_PIC = NO; 158 | GCC_NO_COMMON_BLOCKS = YES; 159 | GCC_OPTIMIZATION_LEVEL = 0; 160 | GCC_PREPROCESSOR_DEFINITIONS = ( 161 | "DEBUG=1", 162 | "$(inherited)", 163 | ); 164 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 165 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 166 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 167 | GCC_WARN_UNDECLARED_SELECTOR = YES; 168 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 169 | GCC_WARN_UNUSED_FUNCTION = YES; 170 | GCC_WARN_UNUSED_VARIABLE = YES; 171 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 172 | MTL_ENABLE_DEBUG_INFO = YES; 173 | ONLY_ACTIVE_ARCH = YES; 174 | SDKROOT = iphoneos; 175 | }; 176 | name = Debug; 177 | }; 178 | 58B511EE1A9E6C8500147676 /* Release */ = { 179 | isa = XCBuildConfiguration; 180 | buildSettings = { 181 | ALWAYS_SEARCH_USER_PATHS = NO; 182 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 183 | CLANG_CXX_LIBRARY = "libc++"; 184 | CLANG_ENABLE_MODULES = YES; 185 | CLANG_ENABLE_OBJC_ARC = YES; 186 | CLANG_WARN_BOOL_CONVERSION = YES; 187 | CLANG_WARN_CONSTANT_CONVERSION = YES; 188 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 189 | CLANG_WARN_EMPTY_BODY = YES; 190 | CLANG_WARN_ENUM_CONVERSION = YES; 191 | CLANG_WARN_INFINITE_RECURSION = YES; 192 | CLANG_WARN_INT_CONVERSION = YES; 193 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 194 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 195 | CLANG_WARN_UNREACHABLE_CODE = YES; 196 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 197 | COPY_PHASE_STRIP = YES; 198 | ENABLE_NS_ASSERTIONS = NO; 199 | ENABLE_STRICT_OBJC_MSGSEND = YES; 200 | GCC_C_LANGUAGE_STANDARD = gnu99; 201 | GCC_NO_COMMON_BLOCKS = YES; 202 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 203 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 204 | GCC_WARN_UNDECLARED_SELECTOR = YES; 205 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 206 | GCC_WARN_UNUSED_FUNCTION = YES; 207 | GCC_WARN_UNUSED_VARIABLE = YES; 208 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 209 | MTL_ENABLE_DEBUG_INFO = NO; 210 | SDKROOT = iphoneos; 211 | VALIDATE_PRODUCT = YES; 212 | }; 213 | name = Release; 214 | }; 215 | 58B511F01A9E6C8500147676 /* Debug */ = { 216 | isa = XCBuildConfiguration; 217 | buildSettings = { 218 | FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/**"; 219 | HEADER_SEARCH_PATHS = ( 220 | "$(inherited)", 221 | "$(SRCROOT)/../node_modules/react-native/React/**", 222 | "$(SRCROOT)/../../react-native/React/**", 223 | ); 224 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 225 | OTHER_LDFLAGS = "-ObjC"; 226 | PRODUCT_NAME = RNCWebView; 227 | SKIP_INSTALL = YES; 228 | }; 229 | name = Debug; 230 | }; 231 | 58B511F11A9E6C8500147676 /* Release */ = { 232 | isa = XCBuildConfiguration; 233 | buildSettings = { 234 | FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/**"; 235 | HEADER_SEARCH_PATHS = ( 236 | "$(inherited)", 237 | "$(SRCROOT)/../node_modules/react-native/React/**", 238 | "$(SRCROOT)/../../react-native/React/**", 239 | ); 240 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 241 | OTHER_LDFLAGS = "-ObjC"; 242 | PRODUCT_NAME = RNCWebView; 243 | SKIP_INSTALL = YES; 244 | }; 245 | name = Release; 246 | }; 247 | /* End XCBuildConfiguration section */ 248 | 249 | /* Begin XCConfigurationList section */ 250 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCWebView" */ = { 251 | isa = XCConfigurationList; 252 | buildConfigurations = ( 253 | 58B511ED1A9E6C8500147676 /* Debug */, 254 | 58B511EE1A9E6C8500147676 /* Release */, 255 | ); 256 | defaultConfigurationIsVisible = 0; 257 | defaultConfigurationName = Release; 258 | }; 259 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCWebView" */ = { 260 | isa = XCConfigurationList; 261 | buildConfigurations = ( 262 | 58B511F01A9E6C8500147676 /* Debug */, 263 | 58B511F11A9E6C8500147676 /* Release */, 264 | ); 265 | defaultConfigurationIsVisible = 0; 266 | defaultConfigurationName = Release; 267 | }; 268 | /* End XCConfigurationList section */ 269 | }; 270 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 271 | } 272 | -------------------------------------------------------------------------------- /ios/RNWebviewx5.h: -------------------------------------------------------------------------------- 1 | 2 | #if __has_include("RCTBridgeModule.h") 3 | #import "RCTBridgeModule.h" 4 | #else 5 | #import 6 | #endif 7 | 8 | @interface RNWebviewx5 : NSObject 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /ios/RNWebviewx5.m: -------------------------------------------------------------------------------- 1 | 2 | #import "RNWebviewx5.h" 3 | 4 | @implementation RNWebviewx5 5 | 6 | - (dispatch_queue_t)methodQueue 7 | { 8 | return dispatch_get_main_queue(); 9 | } 10 | RCT_EXPORT_MODULE() 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /ios/RNWebviewx5.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = "RNWebviewx5" 4 | s.version = "1.0.0" 5 | s.summary = "RNWebviewx5" 6 | s.description = <<-DESC 7 | RNWebviewx5 8 | DESC 9 | s.homepage = "" 10 | s.license = "MIT" 11 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 12 | s.author = { "author" => "author@domain.cn" } 13 | s.platform = :ios, "7.0" 14 | s.source = { :git => "https://github.com/author/RNWebviewx5.git", :tag => "master" } 15 | s.source_files = "RNWebviewx5/**/*.{h,m}" 16 | s.requires_arc = true 17 | 18 | 19 | s.dependency "React" 20 | #s.dependency "others" 21 | 22 | end 23 | 24 | -------------------------------------------------------------------------------- /ios/RNWebviewx5.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B3E7B58A1CC2AC0600A0062D /* RNWebviewx5.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNWebviewx5.m */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = "include/$(PRODUCT_NAME)"; 18 | dstSubfolderSpec = 16; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 0; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 134814201AA4EA6300B7C361 /* libRNWebviewx5.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNWebviewx5.a; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | B3E7B5881CC2AC0600A0062D /* RNWebviewx5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNWebviewx5.h; sourceTree = ""; }; 28 | B3E7B5891CC2AC0600A0062D /* RNWebviewx5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNWebviewx5.m; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 134814211AA4EA7D00B7C361 /* Products */ = { 43 | isa = PBXGroup; 44 | children = ( 45 | 134814201AA4EA6300B7C361 /* libRNWebviewx5.a */, 46 | ); 47 | name = Products; 48 | sourceTree = ""; 49 | }; 50 | 58B511D21A9E6C8500147676 = { 51 | isa = PBXGroup; 52 | children = ( 53 | B3E7B5881CC2AC0600A0062D /* RNWebviewx5.h */, 54 | B3E7B5891CC2AC0600A0062D /* RNWebviewx5.m */, 55 | 134814211AA4EA7D00B7C361 /* Products */, 56 | ); 57 | sourceTree = ""; 58 | }; 59 | /* End PBXGroup section */ 60 | 61 | /* Begin PBXNativeTarget section */ 62 | 58B511DA1A9E6C8500147676 /* RNWebviewx5 */ = { 63 | isa = PBXNativeTarget; 64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNWebviewx5" */; 65 | buildPhases = ( 66 | 58B511D71A9E6C8500147676 /* Sources */, 67 | 58B511D81A9E6C8500147676 /* Frameworks */, 68 | 58B511D91A9E6C8500147676 /* CopyFiles */, 69 | ); 70 | buildRules = ( 71 | ); 72 | dependencies = ( 73 | ); 74 | name = RNWebviewx5; 75 | productName = RCTDataManager; 76 | productReference = 134814201AA4EA6300B7C361 /* libRNWebviewx5.a */; 77 | productType = "com.apple.product-type.library.static"; 78 | }; 79 | /* End PBXNativeTarget section */ 80 | 81 | /* Begin PBXProject section */ 82 | 58B511D31A9E6C8500147676 /* Project object */ = { 83 | isa = PBXProject; 84 | attributes = { 85 | LastUpgradeCheck = 0830; 86 | ORGANIZATIONNAME = Facebook; 87 | TargetAttributes = { 88 | 58B511DA1A9E6C8500147676 = { 89 | CreatedOnToolsVersion = 6.1.1; 90 | }; 91 | }; 92 | }; 93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNWebviewx5" */; 94 | compatibilityVersion = "Xcode 3.2"; 95 | developmentRegion = English; 96 | hasScannedForEncodings = 0; 97 | knownRegions = ( 98 | en, 99 | ); 100 | mainGroup = 58B511D21A9E6C8500147676; 101 | productRefGroup = 58B511D21A9E6C8500147676; 102 | projectDirPath = ""; 103 | projectRoot = ""; 104 | targets = ( 105 | 58B511DA1A9E6C8500147676 /* RNWebviewx5 */, 106 | ); 107 | }; 108 | /* End PBXProject section */ 109 | 110 | /* Begin PBXSourcesBuildPhase section */ 111 | 58B511D71A9E6C8500147676 /* Sources */ = { 112 | isa = PBXSourcesBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | B3E7B58A1CC2AC0600A0062D /* RNWebviewx5.m in Sources */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXSourcesBuildPhase section */ 120 | 121 | /* Begin XCBuildConfiguration section */ 122 | 58B511ED1A9E6C8500147676 /* Debug */ = { 123 | isa = XCBuildConfiguration; 124 | buildSettings = { 125 | ALWAYS_SEARCH_USER_PATHS = NO; 126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 127 | CLANG_CXX_LIBRARY = "libc++"; 128 | CLANG_ENABLE_MODULES = YES; 129 | CLANG_ENABLE_OBJC_ARC = YES; 130 | CLANG_WARN_BOOL_CONVERSION = YES; 131 | CLANG_WARN_CONSTANT_CONVERSION = YES; 132 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 133 | CLANG_WARN_EMPTY_BODY = YES; 134 | CLANG_WARN_ENUM_CONVERSION = YES; 135 | CLANG_WARN_INFINITE_RECURSION = YES; 136 | CLANG_WARN_INT_CONVERSION = YES; 137 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 138 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 139 | CLANG_WARN_UNREACHABLE_CODE = YES; 140 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 141 | COPY_PHASE_STRIP = NO; 142 | ENABLE_STRICT_OBJC_MSGSEND = YES; 143 | ENABLE_TESTABILITY = YES; 144 | GCC_C_LANGUAGE_STANDARD = gnu99; 145 | GCC_DYNAMIC_NO_PIC = NO; 146 | GCC_NO_COMMON_BLOCKS = YES; 147 | GCC_OPTIMIZATION_LEVEL = 0; 148 | GCC_PREPROCESSOR_DEFINITIONS = ( 149 | "DEBUG=1", 150 | "$(inherited)", 151 | ); 152 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 153 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 154 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 155 | GCC_WARN_UNDECLARED_SELECTOR = YES; 156 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 157 | GCC_WARN_UNUSED_FUNCTION = YES; 158 | GCC_WARN_UNUSED_VARIABLE = YES; 159 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 160 | MTL_ENABLE_DEBUG_INFO = YES; 161 | ONLY_ACTIVE_ARCH = YES; 162 | SDKROOT = iphoneos; 163 | }; 164 | name = Debug; 165 | }; 166 | 58B511EE1A9E6C8500147676 /* Release */ = { 167 | isa = XCBuildConfiguration; 168 | buildSettings = { 169 | ALWAYS_SEARCH_USER_PATHS = NO; 170 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 171 | CLANG_CXX_LIBRARY = "libc++"; 172 | CLANG_ENABLE_MODULES = YES; 173 | CLANG_ENABLE_OBJC_ARC = YES; 174 | CLANG_WARN_BOOL_CONVERSION = YES; 175 | CLANG_WARN_CONSTANT_CONVERSION = YES; 176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 177 | CLANG_WARN_EMPTY_BODY = YES; 178 | CLANG_WARN_ENUM_CONVERSION = YES; 179 | CLANG_WARN_INFINITE_RECURSION = YES; 180 | CLANG_WARN_INT_CONVERSION = YES; 181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 182 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 183 | CLANG_WARN_UNREACHABLE_CODE = YES; 184 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 185 | COPY_PHASE_STRIP = YES; 186 | ENABLE_NS_ASSERTIONS = NO; 187 | ENABLE_STRICT_OBJC_MSGSEND = YES; 188 | GCC_C_LANGUAGE_STANDARD = gnu99; 189 | GCC_NO_COMMON_BLOCKS = YES; 190 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 191 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 192 | GCC_WARN_UNDECLARED_SELECTOR = YES; 193 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 194 | GCC_WARN_UNUSED_FUNCTION = YES; 195 | GCC_WARN_UNUSED_VARIABLE = YES; 196 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 197 | MTL_ENABLE_DEBUG_INFO = NO; 198 | SDKROOT = iphoneos; 199 | VALIDATE_PRODUCT = YES; 200 | }; 201 | name = Release; 202 | }; 203 | 58B511F01A9E6C8500147676 /* Debug */ = { 204 | isa = XCBuildConfiguration; 205 | buildSettings = { 206 | HEADER_SEARCH_PATHS = ( 207 | "$(inherited)", 208 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 209 | "$(SRCROOT)/../../../React/**", 210 | "$(SRCROOT)/../../react-native/React/**", 211 | ); 212 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 213 | OTHER_LDFLAGS = "-ObjC"; 214 | PRODUCT_NAME = RNWebviewx5; 215 | SKIP_INSTALL = YES; 216 | }; 217 | name = Debug; 218 | }; 219 | 58B511F11A9E6C8500147676 /* Release */ = { 220 | isa = XCBuildConfiguration; 221 | buildSettings = { 222 | HEADER_SEARCH_PATHS = ( 223 | "$(inherited)", 224 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 225 | "$(SRCROOT)/../../../React/**", 226 | "$(SRCROOT)/../../react-native/React/**", 227 | ); 228 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 229 | OTHER_LDFLAGS = "-ObjC"; 230 | PRODUCT_NAME = RNWebviewx5; 231 | SKIP_INSTALL = YES; 232 | }; 233 | name = Release; 234 | }; 235 | /* End XCBuildConfiguration section */ 236 | 237 | /* Begin XCConfigurationList section */ 238 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNWebviewx5" */ = { 239 | isa = XCConfigurationList; 240 | buildConfigurations = ( 241 | 58B511ED1A9E6C8500147676 /* Debug */, 242 | 58B511EE1A9E6C8500147676 /* Release */, 243 | ); 244 | defaultConfigurationIsVisible = 0; 245 | defaultConfigurationName = Release; 246 | }; 247 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNWebviewx5" */ = { 248 | isa = XCConfigurationList; 249 | buildConfigurations = ( 250 | 58B511F01A9E6C8500147676 /* Debug */, 251 | 58B511F11A9E6C8500147676 /* Release */, 252 | ); 253 | defaultConfigurationIsVisible = 0; 254 | defaultConfigurationName = Release; 255 | }; 256 | /* End XCConfigurationList section */ 257 | }; 258 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 259 | } 260 | -------------------------------------------------------------------------------- /ios/RNWebviewx5.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | 3 | 5 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/WebView.android.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createOnShouldStartLoadWithRequest } from './WebViewShared'; 3 | import { WebViewRenderProcessGoneEvent, WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, WebViewNavigationEvent, WebViewProgressEvent, AndroidWebViewProps, NativeWebViewAndroid, State } from './WebViewTypes'; 4 | /** 5 | * Renders a native WebView. 6 | */ 7 | declare class WebView extends React.Component { 8 | static defaultProps: { 9 | overScrollMode: string; 10 | javaScriptEnabled: boolean; 11 | thirdPartyCookiesEnabled: boolean; 12 | scalesPageToFit: boolean; 13 | allowsFullscreenVideo: boolean; 14 | allowFileAccess: boolean; 15 | saveFormDataDisabled: boolean; 16 | cacheEnabled: boolean; 17 | androidHardwareAccelerationDisabled: boolean; 18 | androidLayerType: string; 19 | originWhitelist: string[]; 20 | }; 21 | static isFileUploadSupported: () => Promise; 22 | startUrl: string | null; 23 | state: State; 24 | onShouldStartLoadWithRequest: ReturnType | null; 25 | webViewRef: React.RefObject; 26 | messagingModuleName: string; 27 | componentDidMount: () => void; 28 | getCommands: () => { 29 | goForward: number; 30 | goBack: number; 31 | reload: number; 32 | stopLoading: number; 33 | postMessage: number; 34 | injectJavaScript: number; 35 | loadUrl: number; 36 | requestFocus: number; 37 | clearHistory: number; 38 | clearCache: number; 39 | clearFormData: number; 40 | }; 41 | goForward: () => void; 42 | goBack: () => void; 43 | reload: () => void; 44 | stopLoading: () => void; 45 | requestFocus: () => void; 46 | postMessage: (data: string) => void; 47 | clearFormData: () => void; 48 | clearCache: (includeDiskFiles: boolean) => void; 49 | clearHistory: () => void; 50 | /** 51 | * Injects a javascript string into the referenced WebView. Deliberately does not 52 | * return a response because using eval() to return a response breaks this method 53 | * on pages with a Content Security Policy that disallows eval(). If you need that 54 | * functionality, look into postMessage/onMessage. 55 | */ 56 | injectJavaScript: (data: string) => void; 57 | /** 58 | * We return an event with a bunch of fields including: 59 | * url, title, loading, canGoBack, canGoForward 60 | */ 61 | updateNavigationState: (event: WebViewNavigationEvent) => void; 62 | /** 63 | * Returns the native `WebView` node. 64 | */ 65 | getWebViewHandle: () => number; 66 | onLoadingStart: (event: WebViewNavigationEvent) => void; 67 | onLoadingError: (event: WebViewErrorEvent) => void; 68 | onHttpError: (event: WebViewHttpErrorEvent) => void; 69 | onRenderProcessGone: (event: WebViewRenderProcessGoneEvent) => void; 70 | onLoadingFinish: (event: WebViewNavigationEvent) => void; 71 | onMessage: (event: WebViewMessageEvent) => void; 72 | onLoadingProgress: (event: WebViewProgressEvent) => void; 73 | onShouldStartLoadWithRequestCallback: (shouldStart: boolean, url: string, lockIdentifier?: number | undefined) => void; 74 | render(): JSX.Element; 75 | } 76 | export default WebView; 77 | //# sourceMappingURL=WebView.android.d.ts.map -------------------------------------------------------------------------------- /lib/WebView.android.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WebView.android.d.ts","sourceRoot":"","sources":["../src/WebView.android.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAgB1B,OAAO,EAEL,kCAAkC,EAGnC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,6BAA6B,EAC7B,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,EAEN,MAAM,gBAAgB,CAAC;AAgBxB;;GAEG;AACH,cAAM,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC,mBAAmB,EAAE,KAAK,CAAC;IAC/D,MAAM,CAAC,YAAY;;;;;;;;;;;;MAYjB;IAEF,MAAM,CAAC,qBAAqB,qBAG1B;IAEF,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE/B,KAAK,EAAE,KAAK,CAGV;IAEF,4BAA4B,EAAE,UAAU,CAAC,OAAO,kCAAkC,CAAC,GAAG,IAAI,CAAQ;IAElG,UAAU,wCAA2C;IAErD,mBAAmB,SAA0C;IAE7D,iBAAiB,aAEf;IAEF,WAAW;;;;;;;;;;;;MAA+D;IAE1E,SAAS,aAMP;IAEF,MAAM,aAMJ;IAEF,MAAM,aASJ;IAEF,WAAW,aAMT;IAEF,YAAY,aAMV;IAEF,WAAW,yBAMT;IAEF,aAAa,aAMZ;IAED,UAAU,sCAMR;IAEF,YAAY,aAMV;IAEF;;;;;OAKG;IACH,gBAAgB,yBAMd;IAEF;;;OAGG;IACH,qBAAqB,0CAInB;IAEF;;OAEG;IACH,gBAAgB,eAId;IAEF,cAAc,0CAQZ;IAEF,cAAc,qCAeZ;IAEF,WAAW,yCAKV;IAED,mBAAmB,iDAKlB;IAED,eAAe,0CAeb;IAEF,SAAS,uCAKP;IAEF,iBAAiB,wCAcf;IAEF,oCAAoC,mFAclC;IAEF,MAAM;CAoFP;AAED,eAAe,OAAO,CAAC"} -------------------------------------------------------------------------------- /lib/WebView.android.js: -------------------------------------------------------------------------------- 1 | var __extends = (this && this.__extends) || (function () { 2 | var extendStatics = function (d, b) { 3 | extendStatics = Object.setPrototypeOf || 4 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 5 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 6 | return extendStatics(d, b); 7 | }; 8 | return function (d, b) { 9 | extendStatics(d, b); 10 | function __() { this.constructor = d; } 11 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 12 | }; 13 | })(); 14 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 15 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 16 | return new (P || (P = Promise))(function (resolve, reject) { 17 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 18 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 19 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 20 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 21 | }); 22 | }; 23 | var __generator = (this && this.__generator) || function (thisArg, body) { 24 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 25 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 26 | function verb(n) { return function (v) { return step([n, v]); }; } 27 | function step(op) { 28 | if (f) throw new TypeError("Generator is already executing."); 29 | while (_) try { 30 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 31 | if (y = 0, t) op = [op[0] & 2, t.value]; 32 | switch (op[0]) { 33 | case 0: case 1: t = op; break; 34 | case 4: _.label++; return { value: op[1], done: false }; 35 | case 5: _.label++; y = op[1]; op = [0]; continue; 36 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 37 | default: 38 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 39 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 40 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 41 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 42 | if (t[2]) _.ops.pop(); 43 | _.trys.pop(); continue; 44 | } 45 | op = body.call(thisArg, _); 46 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 47 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 48 | } 49 | }; 50 | var __rest = (this && this.__rest) || function (s, e) { 51 | var t = {}; 52 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 53 | t[p] = s[p]; 54 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 55 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 56 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 57 | t[p[i]] = s[p[i]]; 58 | } 59 | return t; 60 | }; 61 | import React from 'react'; 62 | import { Image, requireNativeComponent, UIManager as NotTypedUIManager, View, NativeModules, findNodeHandle, } from 'react-native'; 63 | import BatchedBridge from 'react-native/Libraries/BatchedBridge/BatchedBridge'; 64 | import invariant from 'invariant'; 65 | import { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderError, defaultRenderLoading, } from './WebViewShared'; 66 | import styles from './WebView.styles'; 67 | var UIManager = NotTypedUIManager; 68 | var RNX5WebView = requireNativeComponent('RNX5WebView'); 69 | var resolveAssetSource = Image.resolveAssetSource; 70 | /** 71 | * A simple counter to uniquely identify WebView instances. Do not use this for anything else. 72 | */ 73 | var uniqueRef = 0; 74 | /** 75 | * Renders a native WebView. 76 | */ 77 | var WebView = /** @class */ (function (_super) { 78 | __extends(WebView, _super); 79 | function WebView() { 80 | var _this = _super !== null && _super.apply(this, arguments) || this; 81 | _this.startUrl = null; 82 | _this.state = { 83 | viewState: _this.props.startInLoadingState ? 'LOADING' : 'IDLE', 84 | lastErrorEvent: null 85 | }; 86 | _this.onShouldStartLoadWithRequest = null; 87 | _this.webViewRef = React.createRef(); 88 | _this.messagingModuleName = "WebViewMessageHandler" + (uniqueRef += 1); 89 | _this.componentDidMount = function () { 90 | BatchedBridge.registerCallableModule(_this.messagingModuleName, _this); 91 | }; 92 | _this.getCommands = function () { return UIManager.getViewManagerConfig('RNX5WebView').Commands; }; 93 | _this.goForward = function () { 94 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goForward, undefined); 95 | }; 96 | _this.goBack = function () { 97 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goBack, undefined); 98 | }; 99 | _this.reload = function () { 100 | _this.setState({ 101 | viewState: 'LOADING' 102 | }); 103 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().reload, undefined); 104 | }; 105 | _this.stopLoading = function () { 106 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().stopLoading, undefined); 107 | }; 108 | _this.requestFocus = function () { 109 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().requestFocus, undefined); 110 | }; 111 | _this.postMessage = function (data) { 112 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().postMessage, [String(data)]); 113 | }; 114 | _this.clearFormData = function () { 115 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().clearFormData, undefined); 116 | }; 117 | _this.clearCache = function (includeDiskFiles) { 118 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().clearCache, [includeDiskFiles]); 119 | }; 120 | _this.clearHistory = function () { 121 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().clearHistory, undefined); 122 | }; 123 | /** 124 | * Injects a javascript string into the referenced WebView. Deliberately does not 125 | * return a response because using eval() to return a response breaks this method 126 | * on pages with a Content Security Policy that disallows eval(). If you need that 127 | * functionality, look into postMessage/onMessage. 128 | */ 129 | _this.injectJavaScript = function (data) { 130 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().injectJavaScript, [data]); 131 | }; 132 | /** 133 | * We return an event with a bunch of fields including: 134 | * url, title, loading, canGoBack, canGoForward 135 | */ 136 | _this.updateNavigationState = function (event) { 137 | if (_this.props.onNavigationStateChange) { 138 | _this.props.onNavigationStateChange(event.nativeEvent); 139 | } 140 | }; 141 | /** 142 | * Returns the native `WebView` node. 143 | */ 144 | _this.getWebViewHandle = function () { 145 | var nodeHandle = findNodeHandle(_this.webViewRef.current); 146 | invariant(nodeHandle != null, 'nodeHandle expected to be non-null'); 147 | return nodeHandle; 148 | }; 149 | _this.onLoadingStart = function (event) { 150 | var onLoadStart = _this.props.onLoadStart; 151 | var url = event.nativeEvent.url; 152 | _this.startUrl = url; 153 | if (onLoadStart) { 154 | onLoadStart(event); 155 | } 156 | _this.updateNavigationState(event); 157 | }; 158 | _this.onLoadingError = function (event) { 159 | event.persist(); // persist this event because we need to store it 160 | var _a = _this.props, onError = _a.onError, onLoadEnd = _a.onLoadEnd; 161 | if (onError) { 162 | onError(event); 163 | } 164 | if (onLoadEnd) { 165 | onLoadEnd(event); 166 | } 167 | console.warn('Encountered an error loading page', event.nativeEvent); 168 | _this.setState({ 169 | lastErrorEvent: event.nativeEvent, 170 | viewState: 'ERROR' 171 | }); 172 | }; 173 | _this.onHttpError = function (event) { 174 | var onHttpError = _this.props.onHttpError; 175 | if (onHttpError) { 176 | onHttpError(event); 177 | } 178 | }; 179 | _this.onRenderProcessGone = function (event) { 180 | var onRenderProcessGone = _this.props.onRenderProcessGone; 181 | if (onRenderProcessGone) { 182 | onRenderProcessGone(event); 183 | } 184 | }; 185 | _this.onLoadingFinish = function (event) { 186 | var _a = _this.props, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd; 187 | var url = event.nativeEvent.url; 188 | if (onLoad) { 189 | onLoad(event); 190 | } 191 | if (onLoadEnd) { 192 | onLoadEnd(event); 193 | } 194 | if (url === _this.startUrl) { 195 | _this.setState({ 196 | viewState: 'IDLE' 197 | }); 198 | } 199 | _this.updateNavigationState(event); 200 | }; 201 | _this.onMessage = function (event) { 202 | var onMessage = _this.props.onMessage; 203 | if (onMessage) { 204 | onMessage(event); 205 | } 206 | }; 207 | _this.onLoadingProgress = function (event) { 208 | var onLoadProgress = _this.props.onLoadProgress; 209 | var progress = event.nativeEvent.progress; 210 | if (progress === 1) { 211 | _this.setState(function (state) { 212 | if (state.viewState === 'LOADING') { 213 | return { viewState: 'IDLE' }; 214 | } 215 | return null; 216 | }); 217 | } 218 | if (onLoadProgress) { 219 | onLoadProgress(event); 220 | } 221 | }; 222 | _this.onShouldStartLoadWithRequestCallback = function (shouldStart, url, lockIdentifier) { 223 | if (lockIdentifier) { 224 | NativeModules.RNX5WebView.onShouldStartLoadWithRequestCallback(shouldStart, lockIdentifier); 225 | } 226 | else if (shouldStart) { 227 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().loadUrl, [String(url)]); 228 | } 229 | }; 230 | return _this; 231 | } 232 | WebView.prototype.render = function () { 233 | var _a = this.props, onMessage = _a.onMessage, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, originWhitelist = _a.originWhitelist, renderError = _a.renderError, renderLoading = _a.renderLoading, source = _a.source, style = _a.style, containerStyle = _a.containerStyle, _b = _a.nativeConfig, nativeConfig = _b === void 0 ? {} : _b, otherProps = __rest(_a, ["onMessage", "onShouldStartLoadWithRequest", "originWhitelist", "renderError", "renderLoading", "source", "style", "containerStyle", "nativeConfig"]); 234 | var otherView = null; 235 | if (this.state.viewState === 'LOADING') { 236 | otherView = (renderLoading || defaultRenderLoading)(); 237 | } 238 | else if (this.state.viewState === 'ERROR') { 239 | var errorEvent = this.state.lastErrorEvent; 240 | invariant(errorEvent != null, 'lastErrorEvent expected to be non-null'); 241 | otherView = (renderError || defaultRenderError)(errorEvent.domain, errorEvent.code, errorEvent.description); 242 | } 243 | else if (this.state.viewState !== 'IDLE') { 244 | console.error("RNX5WebView invalid state encountered: " + this.state.viewState); 245 | } 246 | var webViewStyles = [styles.container, styles.webView, style]; 247 | var webViewContainerStyle = [styles.container, containerStyle]; 248 | if (typeof source !== "number" && source && 'method' in source) { 249 | if (source.method === 'POST' && source.headers) { 250 | console.warn('WebView: `source.headers` is not supported when using POST.'); 251 | } 252 | else if (source.method === 'GET' && source.body) { 253 | console.warn('WebView: `source.body` is not supported when using GET.'); 254 | } 255 | } 256 | var NativeWebView = nativeConfig.component || RNX5WebView; 257 | this.onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(this.onShouldStartLoadWithRequestCallback, 258 | // casting cause it's in the default props 259 | originWhitelist, onShouldStartLoadWithRequestProp); 260 | var webView = (); 263 | return ( 264 | {webView} 265 | {otherView} 266 | ); 267 | }; 268 | WebView.defaultProps = { 269 | overScrollMode: 'always', 270 | javaScriptEnabled: true, 271 | thirdPartyCookiesEnabled: true, 272 | scalesPageToFit: true, 273 | allowsFullscreenVideo: false, 274 | allowFileAccess: false, 275 | saveFormDataDisabled: false, 276 | cacheEnabled: true, 277 | androidHardwareAccelerationDisabled: false, 278 | androidLayerType: 'none', 279 | originWhitelist: defaultOriginWhitelist 280 | }; 281 | WebView.isFileUploadSupported = function () { return __awaiter(void 0, void 0, void 0, function () { 282 | return __generator(this, function (_a) { 283 | // native implementation should return "true" only for Android 5+ 284 | return [2 /*return*/, NativeModules.RNX5WebView.isFileUploadSupported()]; 285 | }); 286 | }); }; 287 | return WebView; 288 | }(React.Component)); 289 | export default WebView; 290 | -------------------------------------------------------------------------------- /lib/WebView.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { IOSWebViewProps, AndroidWebViewProps } from './WebViewTypes'; 3 | export declare type WebViewProps = IOSWebViewProps & AndroidWebViewProps; 4 | declare const WebView: React.FunctionComponent; 5 | export { WebView }; 6 | export default WebView; 7 | //# sourceMappingURL=WebView.d.ts.map -------------------------------------------------------------------------------- /lib/WebView.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WebView.d.ts","sourceRoot":"","sources":["../src/WebView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,oBAAY,YAAY,GAAG,eAAe,GAAG,mBAAmB,CAAC;AAMjE,QAAA,MAAM,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,YAAY,CAMlD,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,eAAe,OAAO,CAAC"} -------------------------------------------------------------------------------- /lib/WebView.ios.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, WebViewNavigationEvent, WebViewProgressEvent, WebViewTerminatedEvent, IOSWebViewProps, NativeWebViewIOS, State } from './WebViewTypes'; 3 | declare class WebView extends React.Component { 4 | static defaultProps: { 5 | javaScriptEnabled: boolean; 6 | cacheEnabled: boolean; 7 | originWhitelist: string[]; 8 | useSharedProcessPool: boolean; 9 | }; 10 | static isFileUploadSupported: () => Promise; 11 | state: State; 12 | webViewRef: React.RefObject; 13 | getCommands: () => { 14 | goForward: number; 15 | goBack: number; 16 | reload: number; 17 | stopLoading: number; 18 | postMessage: number; 19 | injectJavaScript: number; 20 | loadUrl: number; 21 | requestFocus: number; 22 | }; 23 | /** 24 | * Go forward one page in the web view's history. 25 | */ 26 | goForward: () => void; 27 | /** 28 | * Go back one page in the web view's history. 29 | */ 30 | goBack: () => void; 31 | /** 32 | * Reloads the current page. 33 | */ 34 | reload: () => void; 35 | /** 36 | * Stop loading the current page. 37 | */ 38 | stopLoading: () => void; 39 | /** 40 | * Request focus on WebView rendered page. 41 | */ 42 | requestFocus: () => void; 43 | /** 44 | * Posts a message to the web view, which will emit a `message` event. 45 | * Accepts one argument, `data`, which must be a string. 46 | * 47 | * In your webview, you'll need to something like the following. 48 | * 49 | * ```js 50 | * document.addEventListener('message', e => { document.title = e.data; }); 51 | * ``` 52 | */ 53 | postMessage: (data: string) => void; 54 | /** 55 | * Injects a javascript string into the referenced WebView. Deliberately does not 56 | * return a response because using eval() to return a response breaks this method 57 | * on pages with a Content Security Policy that disallows eval(). If you need that 58 | * functionality, look into postMessage/onMessage. 59 | */ 60 | injectJavaScript: (data: string) => void; 61 | /** 62 | * We return an event with a bunch of fields including: 63 | * url, title, loading, canGoBack, canGoForward 64 | */ 65 | updateNavigationState: (event: WebViewNavigationEvent) => void; 66 | /** 67 | * Returns the native `WebView` node. 68 | */ 69 | getWebViewHandle: () => number; 70 | onLoadingStart: (event: WebViewNavigationEvent) => void; 71 | onLoadingError: (event: WebViewErrorEvent) => void; 72 | onHttpError: (event: WebViewHttpErrorEvent) => void; 73 | onLoadingFinish: (event: WebViewNavigationEvent) => void; 74 | onMessage: (event: WebViewMessageEvent) => void; 75 | onLoadingProgress: (event: WebViewProgressEvent) => void; 76 | onShouldStartLoadWithRequestCallback: (shouldStart: boolean, _url: string, lockIdentifier: number) => void; 77 | onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void; 78 | componentDidUpdate(prevProps: IOSWebViewProps): void; 79 | showRedboxOnPropChanges(prevProps: IOSWebViewProps, propName: keyof IOSWebViewProps): void; 80 | render(): JSX.Element; 81 | } 82 | export default WebView; 83 | //# sourceMappingURL=WebView.ios.d.ts.map -------------------------------------------------------------------------------- /lib/WebView.ios.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WebView.ios.d.ts","sourceRoot":"","sources":["../src/WebView.ios.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkB1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EAEf,gBAAgB,EAEhB,KAAK,EAEN,MAAM,gBAAgB,CAAC;AAyBxB,cAAM,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,CAAC;IAC3D,MAAM,CAAC,YAAY;;;;;MAKjB;IAEF,MAAM,CAAC,qBAAqB,yBAG1B;IAEF,KAAK,EAAE,KAAK,CAGV;IAEF,UAAU,oCAAuC;IAGjD,WAAW;;;;;;;;;MAA+D;IAE1E;;OAEG;IACH,SAAS,aAMP;IAEF;;OAEG;IACH,MAAM,aAMJ;IAEF;;OAEG;IACH,MAAM,aAOJ;IAEF;;OAEG;IACH,WAAW,aAMT;IAEF;;OAEG;IACH,YAAY,aAMV;IAEF;;;;;;;;;OASG;IACH,WAAW,yBAMT;IAEF;;;;;OAKG;IACH,gBAAgB,yBAMd;IAEF;;;OAGG;IACH,qBAAqB,0CAInB;IAEF;;OAEG;IACH,gBAAgB,eAId;IAEF,cAAc,0CAMZ;IAEF,cAAc,qCAeZ;IAEF,WAAW,yCAKV;IAED,eAAe,0CAYb;IAEF,SAAS,uCAKP;IAEF,iBAAiB,wCAKf;IAEF,oCAAoC,uEAUlC;IAEF,4BAA4B,0CAK1B;IAEF,kBAAkB,CAAC,SAAS,EAAE,eAAe;IAO7C,uBAAuB,CACrB,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,MAAM,eAAe;IASjC,MAAM;CAqFP;AAED,eAAe,OAAO,CAAC"} -------------------------------------------------------------------------------- /lib/WebView.ios.js: -------------------------------------------------------------------------------- 1 | var __extends = (this && this.__extends) || (function () { 2 | var extendStatics = function (d, b) { 3 | extendStatics = Object.setPrototypeOf || 4 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 5 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 6 | return extendStatics(d, b); 7 | }; 8 | return function (d, b) { 9 | extendStatics(d, b); 10 | function __() { this.constructor = d; } 11 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 12 | }; 13 | })(); 14 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 15 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 16 | return new (P || (P = Promise))(function (resolve, reject) { 17 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 18 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 19 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 20 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 21 | }); 22 | }; 23 | var __generator = (this && this.__generator) || function (thisArg, body) { 24 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 25 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 26 | function verb(n) { return function (v) { return step([n, v]); }; } 27 | function step(op) { 28 | if (f) throw new TypeError("Generator is already executing."); 29 | while (_) try { 30 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 31 | if (y = 0, t) op = [op[0] & 2, t.value]; 32 | switch (op[0]) { 33 | case 0: case 1: t = op; break; 34 | case 4: _.label++; return { value: op[1], done: false }; 35 | case 5: _.label++; y = op[1]; op = [0]; continue; 36 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 37 | default: 38 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 39 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 40 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 41 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 42 | if (t[2]) _.ops.pop(); 43 | _.trys.pop(); continue; 44 | } 45 | op = body.call(thisArg, _); 46 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 47 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 48 | } 49 | }; 50 | var __rest = (this && this.__rest) || function (s, e) { 51 | var t = {}; 52 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 53 | t[p] = s[p]; 54 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 55 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 56 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 57 | t[p[i]] = s[p[i]]; 58 | } 59 | return t; 60 | }; 61 | import React from 'react'; 62 | import { UIManager as NotTypedUIManager, View, requireNativeComponent, NativeModules, Image, findNodeHandle, } from 'react-native'; 63 | import invariant from 'invariant'; 64 | import { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderError, defaultRenderLoading, } from './WebViewShared'; 65 | import styles from './WebView.styles'; 66 | var UIManager = NotTypedUIManager; 67 | var resolveAssetSource = Image.resolveAssetSource; 68 | var processDecelerationRate = function (decelerationRate) { 69 | var newDecelerationRate = decelerationRate; 70 | if (newDecelerationRate === 'normal') { 71 | newDecelerationRate = 0.998; 72 | } 73 | else if (newDecelerationRate === 'fast') { 74 | newDecelerationRate = 0.99; 75 | } 76 | return newDecelerationRate; 77 | }; 78 | var RNX5WebViewManager = NativeModules.RNX5WebViewManager; 79 | var RNX5WebView = requireNativeComponent('RNX5WebView'); 80 | var WebView = /** @class */ (function (_super) { 81 | __extends(WebView, _super); 82 | function WebView() { 83 | var _this = _super !== null && _super.apply(this, arguments) || this; 84 | _this.state = { 85 | viewState: _this.props.startInLoadingState ? 'LOADING' : 'IDLE', 86 | lastErrorEvent: null 87 | }; 88 | _this.webViewRef = React.createRef(); 89 | // eslint-disable-next-line react/sort-comp 90 | _this.getCommands = function () { return UIManager.getViewManagerConfig('RNX5WebView').Commands; }; 91 | /** 92 | * Go forward one page in the web view's history. 93 | */ 94 | _this.goForward = function () { 95 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goForward, undefined); 96 | }; 97 | /** 98 | * Go back one page in the web view's history. 99 | */ 100 | _this.goBack = function () { 101 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goBack, undefined); 102 | }; 103 | /** 104 | * Reloads the current page. 105 | */ 106 | _this.reload = function () { 107 | _this.setState({ viewState: 'LOADING' }); 108 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().reload, undefined); 109 | }; 110 | /** 111 | * Stop loading the current page. 112 | */ 113 | _this.stopLoading = function () { 114 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().stopLoading, undefined); 115 | }; 116 | /** 117 | * Request focus on WebView rendered page. 118 | */ 119 | _this.requestFocus = function () { 120 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().requestFocus, undefined); 121 | }; 122 | /** 123 | * Posts a message to the web view, which will emit a `message` event. 124 | * Accepts one argument, `data`, which must be a string. 125 | * 126 | * In your webview, you'll need to something like the following. 127 | * 128 | * ```js 129 | * document.addEventListener('message', e => { document.title = e.data; }); 130 | * ``` 131 | */ 132 | _this.postMessage = function (data) { 133 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().postMessage, [String(data)]); 134 | }; 135 | /** 136 | * Injects a javascript string into the referenced WebView. Deliberately does not 137 | * return a response because using eval() to return a response breaks this method 138 | * on pages with a Content Security Policy that disallows eval(). If you need that 139 | * functionality, look into postMessage/onMessage. 140 | */ 141 | _this.injectJavaScript = function (data) { 142 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().injectJavaScript, [data]); 143 | }; 144 | /** 145 | * We return an event with a bunch of fields including: 146 | * url, title, loading, canGoBack, canGoForward 147 | */ 148 | _this.updateNavigationState = function (event) { 149 | if (_this.props.onNavigationStateChange) { 150 | _this.props.onNavigationStateChange(event.nativeEvent); 151 | } 152 | }; 153 | /** 154 | * Returns the native `WebView` node. 155 | */ 156 | _this.getWebViewHandle = function () { 157 | var nodeHandle = findNodeHandle(_this.webViewRef.current); 158 | invariant(nodeHandle != null, 'nodeHandle expected to be non-null'); 159 | return nodeHandle; 160 | }; 161 | _this.onLoadingStart = function (event) { 162 | var onLoadStart = _this.props.onLoadStart; 163 | if (onLoadStart) { 164 | onLoadStart(event); 165 | } 166 | _this.updateNavigationState(event); 167 | }; 168 | _this.onLoadingError = function (event) { 169 | event.persist(); // persist this event because we need to store it 170 | var _a = _this.props, onError = _a.onError, onLoadEnd = _a.onLoadEnd; 171 | if (onLoadEnd) { 172 | onLoadEnd(event); 173 | } 174 | if (onError) { 175 | onError(event); 176 | } 177 | console.warn('Encountered an error loading page', event.nativeEvent); 178 | _this.setState({ 179 | lastErrorEvent: event.nativeEvent, 180 | viewState: 'ERROR' 181 | }); 182 | }; 183 | _this.onHttpError = function (event) { 184 | var onHttpError = _this.props.onHttpError; 185 | if (onHttpError) { 186 | onHttpError(event); 187 | } 188 | }; 189 | _this.onLoadingFinish = function (event) { 190 | var _a = _this.props, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd; 191 | if (onLoad) { 192 | onLoad(event); 193 | } 194 | if (onLoadEnd) { 195 | onLoadEnd(event); 196 | } 197 | _this.setState({ 198 | viewState: 'IDLE' 199 | }); 200 | _this.updateNavigationState(event); 201 | }; 202 | _this.onMessage = function (event) { 203 | var onMessage = _this.props.onMessage; 204 | if (onMessage) { 205 | onMessage(event); 206 | } 207 | }; 208 | _this.onLoadingProgress = function (event) { 209 | var onLoadProgress = _this.props.onLoadProgress; 210 | if (onLoadProgress) { 211 | onLoadProgress(event); 212 | } 213 | }; 214 | _this.onShouldStartLoadWithRequestCallback = function (shouldStart, _url, lockIdentifier) { 215 | var viewManager = (_this.props.nativeConfig && _this.props.nativeConfig.viewManager) 216 | || RNX5WebViewManager; 217 | viewManager.startLoadWithResult(!!shouldStart, lockIdentifier); 218 | }; 219 | _this.onContentProcessDidTerminate = function (event) { 220 | var onContentProcessDidTerminate = _this.props.onContentProcessDidTerminate; 221 | if (onContentProcessDidTerminate) { 222 | onContentProcessDidTerminate(event); 223 | } 224 | }; 225 | return _this; 226 | } 227 | WebView.prototype.componentDidUpdate = function (prevProps) { 228 | this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback'); 229 | this.showRedboxOnPropChanges(prevProps, 'incognito'); 230 | this.showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction'); 231 | this.showRedboxOnPropChanges(prevProps, 'dataDetectorTypes'); 232 | }; 233 | WebView.prototype.showRedboxOnPropChanges = function (prevProps, propName) { 234 | if (this.props[propName] !== prevProps[propName]) { 235 | console.error("Changes to property " + propName + " do nothing after the initial render."); 236 | } 237 | }; 238 | WebView.prototype.render = function () { 239 | var _a = this.props, decelerationRateProp = _a.decelerationRate, _b = _a.nativeConfig, nativeConfig = _b === void 0 ? {} : _b, onMessage = _a.onMessage, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, originWhitelist = _a.originWhitelist, renderError = _a.renderError, renderLoading = _a.renderLoading, _c = _a.injectedJavaScriptForMainFrameOnly, injectedJavaScriptForMainFrameOnly = _c === void 0 ? true : _c, _d = _a.injectedJavaScriptBeforeContentLoadedForMainFrameOnly, injectedJavaScriptBeforeContentLoadedForMainFrameOnly = _d === void 0 ? true : _d, style = _a.style, containerStyle = _a.containerStyle, otherProps = __rest(_a, ["decelerationRate", "nativeConfig", "onMessage", "onShouldStartLoadWithRequest", "originWhitelist", "renderError", "renderLoading", "injectedJavaScriptForMainFrameOnly", "injectedJavaScriptBeforeContentLoadedForMainFrameOnly", "style", "containerStyle"]); 240 | var otherView = null; 241 | if (this.state.viewState === 'LOADING') { 242 | otherView = (renderLoading || defaultRenderLoading)(); 243 | } 244 | else if (this.state.viewState === 'ERROR') { 245 | var errorEvent = this.state.lastErrorEvent; 246 | invariant(errorEvent != null, 'lastErrorEvent expected to be non-null'); 247 | otherView = (renderError || defaultRenderError)(errorEvent.domain, errorEvent.code, errorEvent.description); 248 | } 249 | else if (this.state.viewState !== 'IDLE') { 250 | console.error("RNX5WebView invalid state encountered: " + this.state.viewState); 251 | } 252 | var webViewStyles = [styles.container, styles.webView, style]; 253 | var webViewContainerStyle = [styles.container, containerStyle]; 254 | var onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(this.onShouldStartLoadWithRequestCallback, 255 | // casting cause it's in the default props 256 | originWhitelist, onShouldStartLoadWithRequestProp); 257 | var decelerationRate = processDecelerationRate(decelerationRateProp); 258 | var NativeWebView = nativeConfig.component 259 | || RNX5WebView; 260 | var webView = (); 263 | return ( 264 | {webView} 265 | {otherView} 266 | ); 267 | }; 268 | WebView.defaultProps = { 269 | javaScriptEnabled: true, 270 | cacheEnabled: true, 271 | originWhitelist: defaultOriginWhitelist, 272 | useSharedProcessPool: true 273 | }; 274 | WebView.isFileUploadSupported = function () { return __awaiter(void 0, void 0, void 0, function () { 275 | return __generator(this, function (_a) { 276 | // no native implementation for iOS, depends only on permissions 277 | return [2 /*return*/, true]; 278 | }); 279 | }); }; 280 | return WebView; 281 | }(React.Component)); 282 | export default WebView; 283 | -------------------------------------------------------------------------------- /lib/WebView.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | // This "dummy" WebView is to render something for unsupported platforms, 4 | // like for example Expo SDK "web" platform. It matches the previous react-native 5 | // implementation which is produced by Expo SDK 37.0.0.1 implementation, with 6 | // similar interface than the native ones have. 7 | var WebView = function () { return (); }; 12 | export { WebView }; 13 | export default WebView; 14 | -------------------------------------------------------------------------------- /lib/WebView.macos.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, WebViewNavigationEvent, WebViewProgressEvent, WebViewTerminatedEvent, MacOSWebViewProps, NativeWebViewMacOS, State } from './WebViewTypes'; 3 | declare class WebView extends React.Component { 4 | static defaultProps: { 5 | javaScriptEnabled: boolean; 6 | cacheEnabled: boolean; 7 | originWhitelist: string[]; 8 | useSharedProcessPool: boolean; 9 | }; 10 | static isFileUploadSupported: () => Promise; 11 | state: State; 12 | webViewRef: React.RefObject; 13 | getCommands: () => { 14 | goForward: number; 15 | goBack: number; 16 | reload: number; 17 | stopLoading: number; 18 | postMessage: number; 19 | injectJavaScript: number; 20 | loadUrl: number; 21 | requestFocus: number; 22 | }; 23 | /** 24 | * Go forward one page in the web view's history. 25 | */ 26 | goForward: () => void; 27 | /** 28 | * Go back one page in the web view's history. 29 | */ 30 | goBack: () => void; 31 | /** 32 | * Reloads the current page. 33 | */ 34 | reload: () => void; 35 | /** 36 | * Stop loading the current page. 37 | */ 38 | stopLoading: () => void; 39 | /** 40 | * Request focus on WebView rendered page. 41 | */ 42 | requestFocus: () => void; 43 | /** 44 | * Posts a message to the web view, which will emit a `message` event. 45 | * Accepts one argument, `data`, which must be a string. 46 | * 47 | * In your webview, you'll need to something like the following. 48 | * 49 | * ```js 50 | * document.addEventListener('message', e => { document.title = e.data; }); 51 | * ``` 52 | */ 53 | postMessage: (data: string) => void; 54 | /** 55 | * Injects a javascript string into the referenced WebView. Deliberately does not 56 | * return a response because using eval() to return a response breaks this method 57 | * on pages with a Content Security Policy that disallows eval(). If you need that 58 | * functionality, look into postMessage/onMessage. 59 | */ 60 | injectJavaScript: (data: string) => void; 61 | /** 62 | * We return an event with a bunch of fields including: 63 | * url, title, loading, canGoBack, canGoForward 64 | */ 65 | updateNavigationState: (event: WebViewNavigationEvent) => void; 66 | /** 67 | * Returns the native `WebView` node. 68 | */ 69 | getWebViewHandle: () => number; 70 | onLoadingStart: (event: WebViewNavigationEvent) => void; 71 | onLoadingError: (event: WebViewErrorEvent) => void; 72 | onHttpError: (event: WebViewHttpErrorEvent) => void; 73 | onLoadingFinish: (event: WebViewNavigationEvent) => void; 74 | onMessage: (event: WebViewMessageEvent) => void; 75 | onLoadingProgress: (event: WebViewProgressEvent) => void; 76 | onShouldStartLoadWithRequestCallback: (shouldStart: boolean, _url: string, lockIdentifier: number) => void; 77 | onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void; 78 | componentDidUpdate(prevProps: MacOSWebViewProps): void; 79 | showRedboxOnPropChanges(prevProps: MacOSWebViewProps, propName: keyof MacOSWebViewProps): void; 80 | render(): JSX.Element; 81 | } 82 | export default WebView; 83 | //# sourceMappingURL=WebView.macos.d.ts.map -------------------------------------------------------------------------------- /lib/WebView.macos.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WebView.macos.d.ts","sourceRoot":"","sources":["../src/WebView.macos.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAkB1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAElB,KAAK,EAEN,MAAM,gBAAgB,CAAC;AAcxB,cAAM,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC,iBAAiB,EAAE,KAAK,CAAC;IAC7D,MAAM,CAAC,YAAY;;;;;MAKjB;IAEF,MAAM,CAAC,qBAAqB,yBAG1B;IAEF,KAAK,EAAE,KAAK,CAGV;IAEF,UAAU,sCAAyC;IAGnD,WAAW;;;;;;;;;MAA+D;IAE1E;;OAEG;IACH,SAAS,aAMP;IAEF;;OAEG;IACH,MAAM,aAMJ;IAEF;;OAEG;IACH,MAAM,aAOJ;IAEF;;OAEG;IACH,WAAW,aAMT;IAEF;;OAEG;IACH,YAAY,aAMV;IAEF;;;;;;;;;OASG;IACH,WAAW,yBAMT;IAEF;;;;;OAKG;IACH,gBAAgB,yBAMd;IAEF;;;OAGG;IACH,qBAAqB,0CAInB;IAEF;;OAEG;IACH,gBAAgB,eAId;IAEF,cAAc,0CAMZ;IAEF,cAAc,qCAeZ;IAEF,WAAW,yCAKV;IAED,eAAe,0CAYb;IAEF,SAAS,uCAKP;IAEF,iBAAiB,wCAKf;IAEF,oCAAoC,uEAUlC;IAEF,4BAA4B,0CAK1B;IAEF,kBAAkB,CAAC,SAAS,EAAE,iBAAiB;IAM/C,uBAAuB,CACrB,SAAS,EAAE,iBAAiB,EAC5B,QAAQ,EAAE,MAAM,iBAAiB;IASnC,MAAM;CA0EP;AAED,eAAe,OAAO,CAAC"} -------------------------------------------------------------------------------- /lib/WebView.macos.js: -------------------------------------------------------------------------------- 1 | var __extends = (this && this.__extends) || (function () { 2 | var extendStatics = function (d, b) { 3 | extendStatics = Object.setPrototypeOf || 4 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 5 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 6 | return extendStatics(d, b); 7 | }; 8 | return function (d, b) { 9 | extendStatics(d, b); 10 | function __() { this.constructor = d; } 11 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 12 | }; 13 | })(); 14 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 15 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 16 | return new (P || (P = Promise))(function (resolve, reject) { 17 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 18 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 19 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 20 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 21 | }); 22 | }; 23 | var __generator = (this && this.__generator) || function (thisArg, body) { 24 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 25 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 26 | function verb(n) { return function (v) { return step([n, v]); }; } 27 | function step(op) { 28 | if (f) throw new TypeError("Generator is already executing."); 29 | while (_) try { 30 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 31 | if (y = 0, t) op = [op[0] & 2, t.value]; 32 | switch (op[0]) { 33 | case 0: case 1: t = op; break; 34 | case 4: _.label++; return { value: op[1], done: false }; 35 | case 5: _.label++; y = op[1]; op = [0]; continue; 36 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 37 | default: 38 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 39 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 40 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 41 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 42 | if (t[2]) _.ops.pop(); 43 | _.trys.pop(); continue; 44 | } 45 | op = body.call(thisArg, _); 46 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 47 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 48 | } 49 | }; 50 | var __rest = (this && this.__rest) || function (s, e) { 51 | var t = {}; 52 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 53 | t[p] = s[p]; 54 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 55 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 56 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 57 | t[p[i]] = s[p[i]]; 58 | } 59 | return t; 60 | }; 61 | import React from 'react'; 62 | import { UIManager as NotTypedUIManager, View, requireNativeComponent, NativeModules, Image, findNodeHandle, } from 'react-native'; 63 | import invariant from 'invariant'; 64 | import { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderError, defaultRenderLoading, } from './WebViewShared'; 65 | import styles from './WebView.styles'; 66 | var UIManager = NotTypedUIManager; 67 | var resolveAssetSource = Image.resolveAssetSource; 68 | var RNCWebViewManager = NativeModules.RNCWebViewManager; 69 | var RNCWebView = requireNativeComponent('RNCWebView'); 70 | var WebView = /** @class */ (function (_super) { 71 | __extends(WebView, _super); 72 | function WebView() { 73 | var _this = _super !== null && _super.apply(this, arguments) || this; 74 | _this.state = { 75 | viewState: _this.props.startInLoadingState ? 'LOADING' : 'IDLE', 76 | lastErrorEvent: null 77 | }; 78 | _this.webViewRef = React.createRef(); 79 | // eslint-disable-next-line react/sort-comp 80 | _this.getCommands = function () { return UIManager.getViewManagerConfig('RNCWebView').Commands; }; 81 | /** 82 | * Go forward one page in the web view's history. 83 | */ 84 | _this.goForward = function () { 85 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goForward, undefined); 86 | }; 87 | /** 88 | * Go back one page in the web view's history. 89 | */ 90 | _this.goBack = function () { 91 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().goBack, undefined); 92 | }; 93 | /** 94 | * Reloads the current page. 95 | */ 96 | _this.reload = function () { 97 | _this.setState({ viewState: 'LOADING' }); 98 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().reload, undefined); 99 | }; 100 | /** 101 | * Stop loading the current page. 102 | */ 103 | _this.stopLoading = function () { 104 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().stopLoading, undefined); 105 | }; 106 | /** 107 | * Request focus on WebView rendered page. 108 | */ 109 | _this.requestFocus = function () { 110 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().requestFocus, undefined); 111 | }; 112 | /** 113 | * Posts a message to the web view, which will emit a `message` event. 114 | * Accepts one argument, `data`, which must be a string. 115 | * 116 | * In your webview, you'll need to something like the following. 117 | * 118 | * ```js 119 | * document.addEventListener('message', e => { document.title = e.data; }); 120 | * ``` 121 | */ 122 | _this.postMessage = function (data) { 123 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().postMessage, [String(data)]); 124 | }; 125 | /** 126 | * Injects a javascript string into the referenced WebView. Deliberately does not 127 | * return a response because using eval() to return a response breaks this method 128 | * on pages with a Content Security Policy that disallows eval(). If you need that 129 | * functionality, look into postMessage/onMessage. 130 | */ 131 | _this.injectJavaScript = function (data) { 132 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), _this.getCommands().injectJavaScript, [data]); 133 | }; 134 | /** 135 | * We return an event with a bunch of fields including: 136 | * url, title, loading, canGoBack, canGoForward 137 | */ 138 | _this.updateNavigationState = function (event) { 139 | if (_this.props.onNavigationStateChange) { 140 | _this.props.onNavigationStateChange(event.nativeEvent); 141 | } 142 | }; 143 | /** 144 | * Returns the native `WebView` node. 145 | */ 146 | _this.getWebViewHandle = function () { 147 | var nodeHandle = findNodeHandle(_this.webViewRef.current); 148 | invariant(nodeHandle != null, 'nodeHandle expected to be non-null'); 149 | return nodeHandle; 150 | }; 151 | _this.onLoadingStart = function (event) { 152 | var onLoadStart = _this.props.onLoadStart; 153 | if (onLoadStart) { 154 | onLoadStart(event); 155 | } 156 | _this.updateNavigationState(event); 157 | }; 158 | _this.onLoadingError = function (event) { 159 | event.persist(); // persist this event because we need to store it 160 | var _a = _this.props, onError = _a.onError, onLoadEnd = _a.onLoadEnd; 161 | if (onLoadEnd) { 162 | onLoadEnd(event); 163 | } 164 | if (onError) { 165 | onError(event); 166 | } 167 | console.warn('Encountered an error loading page', event.nativeEvent); 168 | _this.setState({ 169 | lastErrorEvent: event.nativeEvent, 170 | viewState: 'ERROR' 171 | }); 172 | }; 173 | _this.onHttpError = function (event) { 174 | var onHttpError = _this.props.onHttpError; 175 | if (onHttpError) { 176 | onHttpError(event); 177 | } 178 | }; 179 | _this.onLoadingFinish = function (event) { 180 | var _a = _this.props, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd; 181 | if (onLoad) { 182 | onLoad(event); 183 | } 184 | if (onLoadEnd) { 185 | onLoadEnd(event); 186 | } 187 | _this.setState({ 188 | viewState: 'IDLE' 189 | }); 190 | _this.updateNavigationState(event); 191 | }; 192 | _this.onMessage = function (event) { 193 | var onMessage = _this.props.onMessage; 194 | if (onMessage) { 195 | onMessage(event); 196 | } 197 | }; 198 | _this.onLoadingProgress = function (event) { 199 | var onLoadProgress = _this.props.onLoadProgress; 200 | if (onLoadProgress) { 201 | onLoadProgress(event); 202 | } 203 | }; 204 | _this.onShouldStartLoadWithRequestCallback = function (shouldStart, _url, lockIdentifier) { 205 | var viewManager = (_this.props.nativeConfig && _this.props.nativeConfig.viewManager) 206 | || RNCWebViewManager; 207 | viewManager.startLoadWithResult(!!shouldStart, lockIdentifier); 208 | }; 209 | _this.onContentProcessDidTerminate = function (event) { 210 | var onContentProcessDidTerminate = _this.props.onContentProcessDidTerminate; 211 | if (onContentProcessDidTerminate) { 212 | onContentProcessDidTerminate(event); 213 | } 214 | }; 215 | return _this; 216 | } 217 | WebView.prototype.componentDidUpdate = function (prevProps) { 218 | this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback'); 219 | this.showRedboxOnPropChanges(prevProps, 'incognito'); 220 | this.showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction'); 221 | }; 222 | WebView.prototype.showRedboxOnPropChanges = function (prevProps, propName) { 223 | if (this.props[propName] !== prevProps[propName]) { 224 | console.error("Changes to property " + propName + " do nothing after the initial render."); 225 | } 226 | }; 227 | WebView.prototype.render = function () { 228 | var _a = this.props, _b = _a.nativeConfig, nativeConfig = _b === void 0 ? {} : _b, onMessage = _a.onMessage, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, originWhitelist = _a.originWhitelist, renderError = _a.renderError, renderLoading = _a.renderLoading, style = _a.style, containerStyle = _a.containerStyle, otherProps = __rest(_a, ["nativeConfig", "onMessage", "onShouldStartLoadWithRequest", "originWhitelist", "renderError", "renderLoading", "style", "containerStyle"]); 229 | var otherView = null; 230 | if (this.state.viewState === 'LOADING') { 231 | otherView = (renderLoading || defaultRenderLoading)(); 232 | } 233 | else if (this.state.viewState === 'ERROR') { 234 | var errorEvent = this.state.lastErrorEvent; 235 | invariant(errorEvent != null, 'lastErrorEvent expected to be non-null'); 236 | otherView = (renderError || defaultRenderError)(errorEvent.domain, errorEvent.code, errorEvent.description); 237 | } 238 | else if (this.state.viewState !== 'IDLE') { 239 | console.error("RNCWebView invalid state encountered: " + this.state.viewState); 240 | } 241 | var webViewStyles = [styles.container, styles.webView, style]; 242 | var webViewContainerStyle = [styles.container, containerStyle]; 243 | var onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(this.onShouldStartLoadWithRequestCallback, 244 | // casting cause it's in the default props 245 | originWhitelist, onShouldStartLoadWithRequestProp); 246 | var NativeWebView = nativeConfig.component 247 | || RNCWebView; 248 | var webView = (); 251 | return ( 252 | {webView} 253 | {otherView} 254 | ); 255 | }; 256 | WebView.defaultProps = { 257 | javaScriptEnabled: true, 258 | cacheEnabled: true, 259 | originWhitelist: defaultOriginWhitelist, 260 | useSharedProcessPool: true 261 | }; 262 | WebView.isFileUploadSupported = function () { return __awaiter(void 0, void 0, void 0, function () { 263 | return __generator(this, function (_a) { 264 | // no native implementation for macOS, depends only on permissions 265 | return [2 /*return*/, true]; 266 | }); 267 | }); }; 268 | return WebView; 269 | }(React.Component)); 270 | export default WebView; 271 | -------------------------------------------------------------------------------- /lib/WebView.styles.d.ts: -------------------------------------------------------------------------------- 1 | import { ViewStyle, TextStyle } from 'react-native'; 2 | interface Styles { 3 | container: ViewStyle; 4 | errorText: TextStyle; 5 | errorTextTitle: TextStyle; 6 | loadingOrErrorView: ViewStyle; 7 | webView: ViewStyle; 8 | loadingProgressBar: ViewStyle; 9 | } 10 | declare const styles: Styles; 11 | export default styles; 12 | //# sourceMappingURL=WebView.styles.d.ts.map -------------------------------------------------------------------------------- /lib/WebView.styles.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WebView.styles.d.ts","sourceRoot":"","sources":["../src/WebView.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEhE,UAAU,MAAM;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,cAAc,EAAE,SAAS,CAAC;IAC1B,kBAAkB,EAAE,SAAS,CAAC;IAC9B,OAAO,EAAE,SAAS,CAAC;IACnB,kBAAkB,EAAE,SAAS,CAAC;CAC/B;AAED,QAAA,MAAM,MAAM,QA8BV,CAAC;AAEH,eAAe,MAAM,CAAC"} -------------------------------------------------------------------------------- /lib/WebView.styles.js: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | var styles = StyleSheet.create({ 3 | container: { 4 | flex: 1, 5 | overflow: 'hidden' 6 | }, 7 | loadingOrErrorView: { 8 | position: 'absolute', 9 | flex: 1, 10 | justifyContent: 'center', 11 | alignItems: 'center', 12 | height: '100%', 13 | width: '100%', 14 | backgroundColor: 'white' 15 | }, 16 | loadingProgressBar: { 17 | height: 20 18 | }, 19 | errorText: { 20 | fontSize: 14, 21 | textAlign: 'center', 22 | marginBottom: 2 23 | }, 24 | errorTextTitle: { 25 | fontSize: 15, 26 | fontWeight: '500', 27 | marginBottom: 10 28 | }, 29 | webView: { 30 | backgroundColor: '#ffffff' 31 | } 32 | }); 33 | export default styles; 34 | -------------------------------------------------------------------------------- /lib/WebView.windows.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * Portions copyright for react-native-windows: 8 | * 9 | * Copyright (c) Microsoft Corporation. All rights reserved. 10 | * Licensed under the MIT License. 11 | */ 12 | import React from 'react'; 13 | import { NativeWebViewWindows, WebViewSharedProps, WebViewProgressEvent, WebViewNavigationEvent, WebViewErrorEvent, WebViewHttpErrorEvent, WebViewMessageEvent, State } from './WebViewTypes'; 14 | export default class WebView extends React.Component { 15 | static defaultProps: { 16 | javaScriptEnabled: boolean; 17 | }; 18 | state: State; 19 | webViewRef: React.RefObject; 20 | goForward: () => void; 21 | goBack: () => void; 22 | reload: () => void; 23 | injectJavaScript: (data: string) => void; 24 | postMessage: (data: string) => void; 25 | /** 26 | * We return an event with a bunch of fields including: 27 | * url, title, loading, canGoBack, canGoForward 28 | */ 29 | updateNavigationState: (event: WebViewNavigationEvent) => void; 30 | getWebViewHandle: () => number | null; 31 | onLoadingStart: (event: WebViewNavigationEvent) => void; 32 | onLoadingProgress: (event: WebViewProgressEvent) => void; 33 | onLoadingError: (event: WebViewErrorEvent) => void; 34 | onLoadingFinish: (event: WebViewNavigationEvent) => void; 35 | onMessage: (event: WebViewMessageEvent) => void; 36 | onHttpError: (event: WebViewHttpErrorEvent) => void; 37 | render(): JSX.Element; 38 | } 39 | //# sourceMappingURL=WebView.windows.d.ts.map -------------------------------------------------------------------------------- /lib/WebView.windows.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WebView.windows.d.ts","sourceRoot":"","sources":["../src/WebView.windows.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EAEnB,KAAK,EACN,MAAM,gBAAgB,CAAC;AA0BxB,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,KAAK,CAAC,SAAS,CAAC,kBAAkB,EAAE,KAAK,CAAC;IAE7E,MAAM,CAAC,YAAY;;MAEjB;IAEF,KAAK,EAAE,KAAK,CAGX;IAED,UAAU,wCAA2C;IAErD,SAAS,aAMR;IAED,MAAM,aAML;IAED,MAAM,aAML;IAED,gBAAgB,yBAMf;IAED,WAAW,yBAMT;IAEF;;;OAGG;IACH,qBAAqB,0CAIpB;IAED,gBAAgB,sBAGf;IAED,cAAc,0CAMb;IAED,iBAAiB,wCAKf;IAEF,cAAc,qCAcb;IAED,eAAe,0CAYd;IAED,SAAS,uCAKR;IAED,WAAW,yCAKV;IAED,MAAM;CA6EP"} -------------------------------------------------------------------------------- /lib/WebView.windows.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * Portions copyright for react-native-windows: 8 | * 9 | * Copyright (c) Microsoft Corporation. All rights reserved. 10 | * Licensed under the MIT License. 11 | */ 12 | var __extends = (this && this.__extends) || (function () { 13 | var extendStatics = function (d, b) { 14 | extendStatics = Object.setPrototypeOf || 15 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 16 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 17 | return extendStatics(d, b); 18 | }; 19 | return function (d, b) { 20 | extendStatics(d, b); 21 | function __() { this.constructor = d; } 22 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 23 | }; 24 | })(); 25 | var __rest = (this && this.__rest) || function (s, e) { 26 | var t = {}; 27 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 28 | t[p] = s[p]; 29 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 30 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 31 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 32 | t[p[i]] = s[p[i]]; 33 | } 34 | return t; 35 | }; 36 | import React from 'react'; 37 | import { UIManager as NotTypedUIManager, View, requireNativeComponent, StyleSheet, Image, findNodeHandle, } from 'react-native'; 38 | import { createOnShouldStartLoadWithRequest, } from './WebViewShared'; 39 | var UIManager = NotTypedUIManager; 40 | var resolveAssetSource = Image.resolveAssetSource; 41 | var RCTWebView = requireNativeComponent('RCTWebView'); 42 | var styles = StyleSheet.create({ 43 | container: { 44 | flex: 1 45 | }, 46 | hidden: { 47 | height: 0, 48 | flex: 0 49 | }, 50 | loadingView: { 51 | flex: 1, 52 | justifyContent: 'center', 53 | alignItems: 'center' 54 | }, 55 | loadingProgressBar: { 56 | height: 20 57 | } 58 | }); 59 | var WebView = /** @class */ (function (_super) { 60 | __extends(WebView, _super); 61 | function WebView() { 62 | var _this = _super !== null && _super.apply(this, arguments) || this; 63 | _this.state = { 64 | viewState: _this.props.startInLoadingState ? 'LOADING' : 'IDLE', 65 | lastErrorEvent: null 66 | }; 67 | _this.webViewRef = React.createRef(); 68 | _this.goForward = function () { 69 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.goForward, undefined); 70 | }; 71 | _this.goBack = function () { 72 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.goBack, undefined); 73 | }; 74 | _this.reload = function () { 75 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.reload, undefined); 76 | }; 77 | _this.injectJavaScript = function (data) { 78 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.injectJavaScript, [data]); 79 | }; 80 | _this.postMessage = function (data) { 81 | UIManager.dispatchViewManagerCommand(_this.getWebViewHandle(), UIManager.getViewManagerConfig('RCTWebView').Commands.postMessage, [String(data)]); 82 | }; 83 | /** 84 | * We return an event with a bunch of fields including: 85 | * url, title, loading, canGoBack, canGoForward 86 | */ 87 | _this.updateNavigationState = function (event) { 88 | if (_this.props.onNavigationStateChange) { 89 | _this.props.onNavigationStateChange(event.nativeEvent); 90 | } 91 | }; 92 | _this.getWebViewHandle = function () { 93 | // eslint-disable-next-line react/no-string-refs 94 | return findNodeHandle(_this.webViewRef.current); 95 | }; 96 | _this.onLoadingStart = function (event) { 97 | var onLoadStart = _this.props.onLoadStart; 98 | if (onLoadStart) { 99 | onLoadStart(event); 100 | } 101 | _this.updateNavigationState(event); 102 | }; 103 | _this.onLoadingProgress = function (event) { 104 | var onLoadProgress = _this.props.onLoadProgress; 105 | if (onLoadProgress) { 106 | onLoadProgress(event); 107 | } 108 | }; 109 | _this.onLoadingError = function (event) { 110 | event.persist(); // persist this event because we need to store it 111 | var _a = _this.props, onError = _a.onError, onLoadEnd = _a.onLoadEnd; 112 | if (onError) { 113 | onError(event); 114 | } 115 | if (onLoadEnd) { 116 | onLoadEnd(event); 117 | } 118 | console.error('Encountered an error loading page', event.nativeEvent); 119 | _this.setState({ 120 | lastErrorEvent: event.nativeEvent, 121 | viewState: 'ERROR' 122 | }); 123 | }; 124 | _this.onLoadingFinish = function (event) { 125 | var _a = _this.props, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd; 126 | if (onLoad) { 127 | onLoad(event); 128 | } 129 | if (onLoadEnd) { 130 | onLoadEnd(event); 131 | } 132 | _this.setState({ 133 | viewState: 'IDLE' 134 | }); 135 | _this.updateNavigationState(event); 136 | }; 137 | _this.onMessage = function (event) { 138 | var onMessage = _this.props.onMessage; 139 | if (onMessage) { 140 | onMessage(event); 141 | } 142 | }; 143 | _this.onHttpError = function (event) { 144 | var onHttpError = _this.props.onHttpError; 145 | if (onHttpError) { 146 | onHttpError(event); 147 | } 148 | }; 149 | return _this; 150 | } 151 | WebView.prototype.render = function () { 152 | var _a = this.props, _b = _a.nativeConfig, nativeConfig = _b === void 0 ? {} : _b, onMessage = _a.onMessage, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, originWhitelist = _a.originWhitelist, renderError = _a.renderError, renderLoading = _a.renderLoading, style = _a.style, containerStyle = _a.containerStyle, otherProps = __rest(_a, ["nativeConfig", "onMessage", "onShouldStartLoadWithRequest", "originWhitelist", "renderError", "renderLoading", "style", "containerStyle"]); 153 | var otherView = null; 154 | if (this.state.viewState === 'LOADING') { 155 | otherView = this.props.renderLoading && this.props.renderLoading(); 156 | } 157 | else if (this.state.viewState === 'ERROR') { 158 | var errorEvent = this.state.lastErrorEvent; 159 | otherView = this.props.renderError 160 | && this.props.renderError(errorEvent.domain, errorEvent.code, errorEvent.description); 161 | } 162 | else if (this.state.viewState !== 'IDLE') { 163 | console.error('RCTWebView invalid state encountered: ', this.state.viewState); 164 | } 165 | var webViewStyles = [styles.container, this.props.style]; 166 | if (this.state.viewState === 'LOADING' 167 | || this.state.viewState === 'ERROR') { 168 | // if we're in either LOADING or ERROR states, don't show the webView 169 | webViewStyles.push(styles.hidden); 170 | } 171 | var onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(function () { }, 172 | // casting cause it's in the default props 173 | originWhitelist, onShouldStartLoadWithRequestProp); 174 | var NativeWebView = nativeConfig.component 175 | || RCTWebView; 176 | var webView = (); 177 | return ( 178 | {webView} 179 | {otherView} 180 | ); 181 | }; 182 | WebView.defaultProps = { 183 | javaScriptEnabled: true 184 | }; 185 | return WebView; 186 | }(React.Component)); 187 | export default WebView; 188 | -------------------------------------------------------------------------------- /lib/WebViewShared.d.ts: -------------------------------------------------------------------------------- 1 | import { OnShouldStartLoadWithRequest, ShouldStartLoadRequestEvent } from './WebViewTypes'; 2 | declare const defaultOriginWhitelist: string[]; 3 | declare const createOnShouldStartLoadWithRequest: (loadRequest: (shouldStart: boolean, url: string, lockIdentifier: number) => void, originWhitelist: readonly string[], onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest | undefined) => ({ nativeEvent }: ShouldStartLoadRequestEvent) => void; 4 | declare const defaultRenderLoading: () => JSX.Element; 5 | declare const defaultRenderError: (errorDomain: string | undefined, errorCode: number, errorDesc: string) => JSX.Element; 6 | export { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderLoading, defaultRenderError, }; 7 | //# sourceMappingURL=WebViewShared.d.ts.map -------------------------------------------------------------------------------- /lib/WebViewShared.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WebViewShared.d.ts","sourceRoot":"","sources":["../src/WebViewShared.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AAGxB,QAAA,MAAM,sBAAsB,UAA4B,CAAC;AAuBzD,QAAA,MAAM,kCAAkC,2PA8BvC,CAAC;AAEF,QAAA,MAAM,oBAAoB,mBAIzB,CAAC;AACF,QAAA,MAAM,kBAAkB,wFAWvB,CAAC;AAEF,OAAO,EACL,sBAAsB,EACtB,kCAAkC,EAClC,oBAAoB,EACpB,kBAAkB,GACnB,CAAC"} -------------------------------------------------------------------------------- /lib/WebViewShared.js: -------------------------------------------------------------------------------- 1 | var __spreadArrays = (this && this.__spreadArrays) || function () { 2 | for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 3 | for (var r = Array(s), k = 0, i = 0; i < il; i++) 4 | for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 5 | r[k] = a[j]; 6 | return r; 7 | }; 8 | import escapeStringRegexp from 'escape-string-regexp'; 9 | import React from 'react'; 10 | import { Linking, View, ActivityIndicator, Text } from 'react-native'; 11 | import styles from './WebView.styles'; 12 | var defaultOriginWhitelist = ['http://*', 'https://*']; 13 | var extractOrigin = function (url) { 14 | var result = /^[A-Za-z][A-Za-z0-9+\-.]+:(\/\/)?[^/]*/.exec(url); 15 | return result === null ? '' : result[0]; 16 | }; 17 | var originWhitelistToRegex = function (originWhitelist) { 18 | return "^" + escapeStringRegexp(originWhitelist).replace(/\\\*/g, '.*'); 19 | }; 20 | var passesWhitelist = function (compiledWhitelist, url) { 21 | var origin = extractOrigin(url); 22 | return compiledWhitelist.some(function (x) { return new RegExp(x).test(origin); }); 23 | }; 24 | var compileWhitelist = function (originWhitelist) { 25 | return __spreadArrays(['about:blank'], (originWhitelist || [])).map(originWhitelistToRegex); 26 | }; 27 | var createOnShouldStartLoadWithRequest = function (loadRequest, originWhitelist, onShouldStartLoadWithRequest) { 28 | return function (_a) { 29 | var nativeEvent = _a.nativeEvent; 30 | var shouldStart = true; 31 | var url = nativeEvent.url, lockIdentifier = nativeEvent.lockIdentifier; 32 | if (!passesWhitelist(compileWhitelist(originWhitelist), url)) { 33 | Linking.canOpenURL(url).then(function (supported) { 34 | if (supported) { 35 | return Linking.openURL(url); 36 | } 37 | console.warn("Can't open url: " + url); 38 | return undefined; 39 | })["catch"](function (e) { 40 | console.warn('Error opening URL: ', e); 41 | }); 42 | shouldStart = false; 43 | } 44 | else if (onShouldStartLoadWithRequest) { 45 | shouldStart = onShouldStartLoadWithRequest(nativeEvent); 46 | } 47 | loadRequest(shouldStart, url, lockIdentifier); 48 | }; 49 | }; 50 | var defaultRenderLoading = function () { return ( 51 | 52 | ); }; 53 | var defaultRenderError = function (errorDomain, errorCode, errorDesc) { return ( 54 | Error loading page 55 | {"Domain: " + errorDomain} 56 | {"Error Code: " + errorCode} 57 | {"Description: " + errorDesc} 58 | ); }; 59 | export { defaultOriginWhitelist, createOnShouldStartLoadWithRequest, defaultRenderLoading, defaultRenderError, }; 60 | -------------------------------------------------------------------------------- /lib/WebViewTypes.d.ts: -------------------------------------------------------------------------------- 1 | import { ReactElement, Component } from 'react'; 2 | import { NativeSyntheticEvent, ViewProps, StyleProp, ViewStyle, NativeMethodsMixin, Constructor, UIManagerStatic, NativeScrollEvent } from 'react-native'; 3 | declare type WebViewCommands = 'goForward' | 'goBack' | 'reload' | 'stopLoading' | 'postMessage' | 'injectJavaScript' | 'loadUrl' | 'requestFocus'; 4 | declare type AndroidWebViewCommands = 'clearHistory' | 'clearCache' | 'clearFormData'; 5 | interface RNCWebViewUIManager extends UIManagerStatic { 6 | getViewManagerConfig: (name: string) => { 7 | Commands: { 8 | [key in Commands]: number; 9 | }; 10 | }; 11 | } 12 | export declare type RNCWebViewUIManagerAndroid = RNCWebViewUIManager; 13 | export declare type RNCWebViewUIManagerIOS = RNCWebViewUIManager; 14 | export declare type RNCWebViewUIManagerMacOS = RNCWebViewUIManager; 15 | export declare type RNCWebViewUIManagerWindows = RNCWebViewUIManager; 16 | declare type WebViewState = 'IDLE' | 'LOADING' | 'ERROR'; 17 | interface BaseState { 18 | viewState: WebViewState; 19 | } 20 | interface NormalState extends BaseState { 21 | viewState: 'IDLE' | 'LOADING'; 22 | lastErrorEvent: WebViewError | null; 23 | } 24 | interface ErrorState extends BaseState { 25 | viewState: 'ERROR'; 26 | lastErrorEvent: WebViewError; 27 | } 28 | export declare type State = NormalState | ErrorState; 29 | declare class NativeWebViewIOSComponent extends Component { 30 | } 31 | declare const NativeWebViewIOSBase: Constructor & typeof NativeWebViewIOSComponent; 32 | export declare class NativeWebViewIOS extends NativeWebViewIOSBase { 33 | } 34 | declare class NativeWebViewMacOSComponent extends Component { 35 | } 36 | declare const NativeWebViewMacOSBase: Constructor & typeof NativeWebViewMacOSComponent; 37 | export declare class NativeWebViewMacOS extends NativeWebViewMacOSBase { 38 | } 39 | declare class NativeWebViewAndroidComponent extends Component { 40 | } 41 | declare const NativeWebViewAndroidBase: Constructor & typeof NativeWebViewAndroidComponent; 42 | export declare class NativeWebViewAndroid extends NativeWebViewAndroidBase { 43 | } 44 | declare class NativeWebViewWindowsComponent extends Component { 45 | } 46 | declare const NativeWebViewWindowsBase: Constructor & typeof NativeWebViewWindowsComponent; 47 | export declare class NativeWebViewWindows extends NativeWebViewWindowsBase { 48 | } 49 | export interface ContentInsetProp { 50 | top?: number; 51 | left?: number; 52 | bottom?: number; 53 | right?: number; 54 | } 55 | export interface WebViewNativeEvent { 56 | url: string; 57 | loading: boolean; 58 | title: string; 59 | canGoBack: boolean; 60 | canGoForward: boolean; 61 | lockIdentifier: number; 62 | } 63 | export interface WebViewNativeProgressEvent extends WebViewNativeEvent { 64 | progress: number; 65 | } 66 | export interface WebViewNavigation extends WebViewNativeEvent { 67 | navigationType: 'click' | 'formsubmit' | 'backforward' | 'reload' | 'formresubmit' | 'other'; 68 | mainDocumentURL?: string; 69 | } 70 | export interface ShouldStartLoadRequest extends WebViewNavigation { 71 | isTopFrame: boolean; 72 | } 73 | export interface FileDownload { 74 | downloadUrl: string; 75 | } 76 | export declare type DecelerationRateConstant = 'normal' | 'fast'; 77 | export interface WebViewMessage extends WebViewNativeEvent { 78 | data: string; 79 | } 80 | export interface WebViewError extends WebViewNativeEvent { 81 | /** 82 | * `domain` is only used on iOS and macOS 83 | */ 84 | domain?: string; 85 | code: number; 86 | description: string; 87 | } 88 | export interface WebViewHttpError extends WebViewNativeEvent { 89 | description: string; 90 | statusCode: number; 91 | } 92 | export interface WebViewRenderProcessGoneDetail { 93 | didCrash: boolean; 94 | } 95 | export declare type WebViewEvent = NativeSyntheticEvent; 96 | export declare type WebViewProgressEvent = NativeSyntheticEvent; 97 | export declare type WebViewNavigationEvent = NativeSyntheticEvent; 98 | export declare type ShouldStartLoadRequestEvent = NativeSyntheticEvent; 99 | export declare type FileDownloadEvent = NativeSyntheticEvent; 100 | export declare type WebViewMessageEvent = NativeSyntheticEvent; 101 | export declare type WebViewErrorEvent = NativeSyntheticEvent; 102 | export declare type WebViewTerminatedEvent = NativeSyntheticEvent; 103 | export declare type WebViewHttpErrorEvent = NativeSyntheticEvent; 104 | export declare type WebViewRenderProcessGoneEvent = NativeSyntheticEvent; 105 | export declare type DataDetectorTypes = 'phoneNumber' | 'link' | 'address' | 'calendarEvent' | 'trackingNumber' | 'flightNumber' | 'lookupSuggestion' | 'none' | 'all'; 106 | export declare type OverScrollModeType = 'always' | 'content' | 'never'; 107 | export declare type CacheMode = 'LOAD_DEFAULT' | 'LOAD_CACHE_ONLY' | 'LOAD_CACHE_ELSE_NETWORK' | 'LOAD_NO_CACHE'; 108 | export declare type AndroidLayerType = 'none' | 'software' | 'hardware'; 109 | export interface WebViewSourceUri { 110 | /** 111 | * The URI to load in the `WebView`. Can be a local or remote file. 112 | */ 113 | uri: string; 114 | /** 115 | * The HTTP Method to use. Defaults to GET if not specified. 116 | * NOTE: On Android, only GET and POST are supported. 117 | */ 118 | method?: string; 119 | /** 120 | * Additional HTTP headers to send with the request. 121 | * NOTE: On Android, this can only be used with GET requests. 122 | */ 123 | headers?: Object; 124 | /** 125 | * The HTTP body to send with the request. This must be a valid 126 | * UTF-8 string, and will be sent exactly as specified, with no 127 | * additional encoding (e.g. URL-escaping or base64) applied. 128 | * NOTE: On Android, this can only be used with POST requests. 129 | */ 130 | body?: string; 131 | } 132 | export interface WebViewSourceHtml { 133 | /** 134 | * A static HTML page to display in the WebView. 135 | */ 136 | html: string; 137 | /** 138 | * The base URL to be used for any relative links in the HTML. 139 | */ 140 | baseUrl?: string; 141 | } 142 | export declare type WebViewSource = WebViewSourceUri | WebViewSourceHtml; 143 | export interface ViewManager { 144 | startLoadWithResult: Function; 145 | } 146 | export interface WebViewNativeConfig { 147 | /** 148 | * The native component used to render the WebView. 149 | */ 150 | component?: typeof NativeWebViewIOS | typeof NativeWebViewMacOS | typeof NativeWebViewAndroid; 151 | /** 152 | * Set props directly on the native component WebView. Enables custom props which the 153 | * original WebView doesn't pass through. 154 | */ 155 | props?: Object; 156 | /** 157 | * Set the ViewManager to use for communication with the native side. 158 | * @platform ios, macos 159 | */ 160 | viewManager?: ViewManager; 161 | } 162 | export declare type OnShouldStartLoadWithRequest = (event: ShouldStartLoadRequest) => boolean; 163 | export interface CommonNativeWebViewProps extends ViewProps { 164 | cacheEnabled?: boolean; 165 | incognito?: boolean; 166 | injectedJavaScript?: string; 167 | injectedJavaScriptBeforeContentLoaded?: string; 168 | injectedJavaScriptForMainFrameOnly?: boolean; 169 | injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean; 170 | javaScriptCanOpenWindowsAutomatically?: boolean; 171 | mediaPlaybackRequiresUserAction?: boolean; 172 | messagingEnabled: boolean; 173 | onScroll?: (event: NativeScrollEvent) => void; 174 | onLoadingError: (event: WebViewErrorEvent) => void; 175 | onLoadingFinish: (event: WebViewNavigationEvent) => void; 176 | onLoadingProgress: (event: WebViewProgressEvent) => void; 177 | onLoadingStart: (event: WebViewNavigationEvent) => void; 178 | onHttpError: (event: WebViewHttpErrorEvent) => void; 179 | onMessage: (event: WebViewMessageEvent) => void; 180 | onShouldStartLoadWithRequest: (event: ShouldStartLoadRequestEvent) => void; 181 | showsHorizontalScrollIndicator?: boolean; 182 | showsVerticalScrollIndicator?: boolean; 183 | source: any; 184 | userAgent?: string; 185 | /** 186 | * Append to the existing user-agent. Overridden if `userAgent` is set. 187 | */ 188 | applicationNameForUserAgent?: string; 189 | } 190 | export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps { 191 | cacheMode?: CacheMode; 192 | allowFileAccess?: boolean; 193 | scalesPageToFit?: boolean; 194 | allowFileAccessFromFileURLs?: boolean; 195 | allowUniversalAccessFromFileURLs?: boolean; 196 | androidHardwareAccelerationDisabled?: boolean; 197 | androidLayerType?: AndroidLayerType; 198 | domStorageEnabled?: boolean; 199 | geolocationEnabled?: boolean; 200 | javaScriptEnabled?: boolean; 201 | mixedContentMode?: 'never' | 'always' | 'compatibility'; 202 | onContentSizeChange?: (event: WebViewEvent) => void; 203 | onRenderProcessGone?: (event: WebViewRenderProcessGoneEvent) => void; 204 | overScrollMode?: OverScrollModeType; 205 | saveFormDataDisabled?: boolean; 206 | textZoom?: number; 207 | thirdPartyCookiesEnabled?: boolean; 208 | messagingModuleName?: string; 209 | readonly urlPrefixesForDefaultIntent?: string[]; 210 | } 211 | export declare type ContentInsetAdjustmentBehavior = 'automatic' | 'scrollableAxes' | 'never' | 'always'; 212 | export declare type ContentMode = 'recommended' | 'mobile' | 'desktop'; 213 | export interface IOSNativeWebViewProps extends CommonNativeWebViewProps { 214 | allowingReadAccessToURL?: string; 215 | allowsBackForwardNavigationGestures?: boolean; 216 | allowsInlineMediaPlayback?: boolean; 217 | allowsLinkPreview?: boolean; 218 | automaticallyAdjustContentInsets?: boolean; 219 | autoManageStatusBarEnabled?: boolean; 220 | bounces?: boolean; 221 | contentInset?: ContentInsetProp; 222 | contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior; 223 | contentMode?: ContentMode; 224 | readonly dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[]; 225 | decelerationRate?: number; 226 | directionalLockEnabled?: boolean; 227 | hideKeyboardAccessoryView?: boolean; 228 | pagingEnabled?: boolean; 229 | scrollEnabled?: boolean; 230 | useSharedProcessPool?: boolean; 231 | onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void; 232 | injectedJavaScriptForMainFrameOnly?: boolean; 233 | injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean; 234 | onFileDownload?: (event: FileDownloadEvent) => void; 235 | } 236 | export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps { 237 | allowingReadAccessToURL?: string; 238 | allowsBackForwardNavigationGestures?: boolean; 239 | allowsInlineMediaPlayback?: boolean; 240 | allowsLinkPreview?: boolean; 241 | automaticallyAdjustContentInsets?: boolean; 242 | bounces?: boolean; 243 | contentInset?: ContentInsetProp; 244 | contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior; 245 | directionalLockEnabled?: boolean; 246 | hideKeyboardAccessoryView?: boolean; 247 | pagingEnabled?: boolean; 248 | scrollEnabled?: boolean; 249 | useSharedProcessPool?: boolean; 250 | onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void; 251 | } 252 | export interface WindowsNativeWebViewProps extends CommonNativeWebViewProps { 253 | testID?: string; 254 | } 255 | export interface IOSWebViewProps extends WebViewSharedProps { 256 | /** 257 | * Does not store any data within the lifetime of the WebView. 258 | */ 259 | incognito?: boolean; 260 | /** 261 | * Boolean value that determines whether the web view bounces 262 | * when it reaches the edge of the content. The default value is `true`. 263 | * @platform ios 264 | */ 265 | bounces?: boolean; 266 | /** 267 | * A floating-point number that determines how quickly the scroll view 268 | * decelerates after the user lifts their finger. You may also use the 269 | * string shortcuts `"normal"` and `"fast"` which match the underlying iOS 270 | * settings for `UIScrollViewDecelerationRateNormal` and 271 | * `UIScrollViewDecelerationRateFast` respectively: 272 | * 273 | * - normal: 0.998 274 | * - fast: 0.99 (the default for iOS web view) 275 | * @platform ios 276 | */ 277 | decelerationRate?: DecelerationRateConstant | number; 278 | /** 279 | * Boolean value that determines whether scrolling is enabled in the 280 | * `WebView`. The default value is `true`. 281 | * @platform ios 282 | */ 283 | scrollEnabled?: boolean; 284 | /** 285 | * If the value of this property is true, the scroll view stops on multiples 286 | * of the scroll view’s bounds when the user scrolls. 287 | * The default value is false. 288 | * @platform ios 289 | */ 290 | pagingEnabled?: boolean; 291 | /** 292 | * Controls whether to adjust the content inset for web views that are 293 | * placed behind a navigation bar, tab bar, or toolbar. The default value 294 | * is `true`. 295 | * @platform ios 296 | */ 297 | automaticallyAdjustContentInsets?: boolean; 298 | /** 299 | * This property specifies how the safe area insets are used to modify the 300 | * content area of the scroll view. The default value of this property is 301 | * "never". Available on iOS 11 and later. 302 | */ 303 | contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior; 304 | /** 305 | * The amount by which the web view content is inset from the edges of 306 | * the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}. 307 | * @platform ios 308 | */ 309 | contentInset?: ContentInsetProp; 310 | /** 311 | * Defaults to `recommended`, which loads mobile content on iPhone 312 | * and iPad Mini but desktop content on other iPads. 313 | * 314 | * Possible values are: 315 | * - `'recommended'` 316 | * - `'mobile'` 317 | * - `'desktop'` 318 | * @platform ios 319 | */ 320 | contentMode?: ContentMode; 321 | /** 322 | * Determines the types of data converted to clickable URLs in the web view's content. 323 | * By default only phone numbers are detected. 324 | * 325 | * You can provide one type or an array of many types. 326 | * 327 | * Possible values for `dataDetectorTypes` are: 328 | * 329 | * - `'phoneNumber'` 330 | * - `'link'` 331 | * - `'address'` 332 | * - `'calendarEvent'` 333 | * - `'none'` 334 | * - `'all'` 335 | * 336 | * With the new WebKit implementation, we have three new values: 337 | * - `'trackingNumber'`, 338 | * - `'flightNumber'`, 339 | * - `'lookupSuggestion'`, 340 | * 341 | * @platform ios 342 | */ 343 | readonly dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[]; 344 | /** 345 | * Boolean that determines whether HTML5 videos play inline or use the 346 | * native full-screen controller. The default value is `false`. 347 | * 348 | * **NOTE** : In order for video to play inline, not only does this 349 | * property need to be set to `true`, but the video element in the HTML 350 | * document must also include the `webkit-playsinline` attribute. 351 | * @platform ios 352 | */ 353 | allowsInlineMediaPlayback?: boolean; 354 | /** 355 | * Hide the accessory view when the keyboard is open. Default is false to be 356 | * backward compatible. 357 | */ 358 | hideKeyboardAccessoryView?: boolean; 359 | /** 360 | * A Boolean value indicating whether horizontal swipe gestures will trigger 361 | * back-forward list navigations. 362 | */ 363 | allowsBackForwardNavigationGestures?: boolean; 364 | /** 365 | * A Boolean value indicating whether WebKit WebView should be created using a shared 366 | * process pool, enabling WebViews to share cookies and localStorage between each other. 367 | * Default is true but can be set to false for backwards compatibility. 368 | * @platform ios 369 | */ 370 | useSharedProcessPool?: boolean; 371 | /** 372 | * The custom user agent string. 373 | */ 374 | userAgent?: string; 375 | /** 376 | * A Boolean value that determines whether pressing on a link 377 | * displays a preview of the destination for the link. 378 | * 379 | * This property is available on devices that support 3D Touch. 380 | * In iOS 10 and later, the default value is `true`; before that, the default value is `false`. 381 | * @platform ios 382 | */ 383 | allowsLinkPreview?: boolean; 384 | /** 385 | * Set true if shared cookies from HTTPCookieStorage should used for every load request. 386 | * The default value is `false`. 387 | * @platform ios 388 | */ 389 | sharedCookiesEnabled?: boolean; 390 | /** 391 | * Set true if StatusBar should be light when user watch video fullscreen. 392 | * The default value is `true`. 393 | * @platform ios 394 | */ 395 | autoManageStatusBarEnabled?: boolean; 396 | /** 397 | * A Boolean value that determines whether scrolling is disabled in a particular direction. 398 | * The default value is `true`. 399 | * @platform ios 400 | */ 401 | directionalLockEnabled?: boolean; 402 | /** 403 | * A Boolean value indicating whether web content can programmatically display the keyboard. 404 | * 405 | * When this property is set to true, the user must explicitly tap the elements in the 406 | * web view to display the keyboard (or other relevant input view) for that element. 407 | * When set to false, a focus event on an element causes the input view to be displayed 408 | * and associated with that element automatically. 409 | * 410 | * The default value is `true`. 411 | * @platform ios 412 | */ 413 | keyboardDisplayRequiresUserAction?: boolean; 414 | /** 415 | * A String value that indicates which URLs the WebView's file can then 416 | * reference in scripts, AJAX requests, and CSS imports. This is only used 417 | * for WebViews that are loaded with a source.uri set to a `'file://'` URL. 418 | * 419 | * If not provided, the default is to only allow read access to the URL 420 | * provided in source.uri itself. 421 | * @platform ios 422 | */ 423 | allowingReadAccessToURL?: string; 424 | /** 425 | * Function that is invoked when the WebKit WebView content process gets terminated. 426 | * @platform ios 427 | */ 428 | onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void; 429 | /** 430 | * If `true` (default), loads the `injectedJavaScript` only into the main frame. 431 | * If `false`, loads it into all frames (e.g. iframes). 432 | * @platform ios 433 | */ 434 | injectedJavaScriptForMainFrameOnly?: boolean; 435 | /** 436 | * If `true` (default), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame. 437 | * If `false`, loads it into all frames (e.g. iframes). 438 | * @platform ios 439 | */ 440 | injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean; 441 | /** 442 | * Boolean value that determines whether a pull to refresh gesture is 443 | * available in the `WebView`. The default value is `false`. 444 | * If `true`, sets `bounces` automatically to `true` 445 | * @platform ios 446 | * 447 | */ 448 | pullToRefreshEnabled?: boolean; 449 | /** 450 | * Function that is invoked when the client needs to download a file. 451 | * 452 | * iOS 13+ only: If the webview navigates to a URL that results in an HTTP 453 | * response with a Content-Disposition header 'attachment...', then 454 | * this will be called. 455 | * 456 | * iOS 8+: If the MIME type indicates that the content is not renderable by the 457 | * webview, that will also cause this to be called. On iOS versions before 13, 458 | * this is the only condition that will cause this function to be called. 459 | * 460 | * The application will need to provide its own code to actually download 461 | * the file. 462 | * 463 | * If not provided, the default is to let the webview try to render the file. 464 | */ 465 | onFileDownload?: (event: FileDownloadEvent) => void; 466 | } 467 | export interface MacOSWebViewProps extends WebViewSharedProps { 468 | /** 469 | * Does not store any data within the lifetime of the WebView. 470 | */ 471 | incognito?: boolean; 472 | /** 473 | * Boolean value that determines whether the web view bounces 474 | * when it reaches the edge of the content. The default value is `true`. 475 | * @platform macos 476 | */ 477 | bounces?: boolean; 478 | /** 479 | * Boolean value that determines whether scrolling is enabled in the 480 | * `WebView`. The default value is `true`. 481 | * @platform macos 482 | */ 483 | scrollEnabled?: boolean; 484 | /** 485 | * If the value of this property is true, the scroll view stops on multiples 486 | * of the scroll view’s bounds when the user scrolls. 487 | * The default value is false. 488 | * @platform macos 489 | */ 490 | pagingEnabled?: boolean; 491 | /** 492 | * Controls whether to adjust the content inset for web views that are 493 | * placed behind a navigation bar, tab bar, or toolbar. The default value 494 | * is `true`. 495 | * @platform macos 496 | */ 497 | automaticallyAdjustContentInsets?: boolean; 498 | /** 499 | * This property specifies how the safe area insets are used to modify the 500 | * content area of the scroll view. The default value of this property is 501 | * "never". Available on iOS 11 and later. 502 | */ 503 | contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior; 504 | /** 505 | * The amount by which the web view content is inset from the edges of 506 | * the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}. 507 | * @platform macos 508 | */ 509 | contentInset?: ContentInsetProp; 510 | /** 511 | * Boolean that determines whether HTML5 videos play inline or use the 512 | * native full-screen controller. The default value is `false`. 513 | * 514 | * **NOTE** : In order for video to play inline, not only does this 515 | * property need to be set to `true`, but the video element in the HTML 516 | * document must also include the `webkit-playsinline` attribute. 517 | * @platform macos 518 | */ 519 | allowsInlineMediaPlayback?: boolean; 520 | /** 521 | * Hide the accessory view when the keyboard is open. Default is false to be 522 | * backward compatible. 523 | */ 524 | hideKeyboardAccessoryView?: boolean; 525 | /** 526 | * A Boolean value indicating whether horizontal swipe gestures will trigger 527 | * back-forward list navigations. 528 | */ 529 | allowsBackForwardNavigationGestures?: boolean; 530 | /** 531 | * A Boolean value indicating whether WebKit WebView should be created using a shared 532 | * process pool, enabling WebViews to share cookies and localStorage between each other. 533 | * Default is true but can be set to false for backwards compatibility. 534 | * @platform macos 535 | */ 536 | useSharedProcessPool?: boolean; 537 | /** 538 | * The custom user agent string. 539 | */ 540 | userAgent?: string; 541 | /** 542 | * A Boolean value that determines whether pressing on a link 543 | * displays a preview of the destination for the link. 544 | * 545 | * This property is available on devices that support Force Touch trackpad. 546 | * @platform macos 547 | */ 548 | allowsLinkPreview?: boolean; 549 | /** 550 | * Set true if shared cookies from HTTPCookieStorage should used for every load request. 551 | * The default value is `false`. 552 | * @platform macos 553 | */ 554 | sharedCookiesEnabled?: boolean; 555 | /** 556 | * A Boolean value that determines whether scrolling is disabled in a particular direction. 557 | * The default value is `true`. 558 | * @platform macos 559 | */ 560 | directionalLockEnabled?: boolean; 561 | /** 562 | * A Boolean value indicating whether web content can programmatically display the keyboard. 563 | * 564 | * When this property is set to true, the user must explicitly tap the elements in the 565 | * web view to display the keyboard (or other relevant input view) for that element. 566 | * When set to false, a focus event on an element causes the input view to be displayed 567 | * and associated with that element automatically. 568 | * 569 | * The default value is `true`. 570 | * @platform macos 571 | */ 572 | keyboardDisplayRequiresUserAction?: boolean; 573 | /** 574 | * A String value that indicates which URLs the WebView's file can then 575 | * reference in scripts, AJAX requests, and CSS imports. This is only used 576 | * for WebViews that are loaded with a source.uri set to a `'file://'` URL. 577 | * 578 | * If not provided, the default is to only allow read access to the URL 579 | * provided in source.uri itself. 580 | * @platform macos 581 | */ 582 | allowingReadAccessToURL?: string; 583 | /** 584 | * Function that is invoked when the WebKit WebView content process gets terminated. 585 | * @platform macos 586 | */ 587 | onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void; 588 | } 589 | export interface AndroidWebViewProps extends WebViewSharedProps { 590 | onNavigationStateChange?: (event: WebViewNavigation) => void; 591 | onContentSizeChange?: (event: WebViewEvent) => void; 592 | /** 593 | * Function that is invoked when the `WebView` process crashes or is killed by the OS. 594 | * Works only on Android (minimum API level 26). 595 | */ 596 | onRenderProcessGone?: (event: WebViewRenderProcessGoneEvent) => void; 597 | /** 598 | * https://developer.android.com/reference/android/webkit/WebSettings.html#setCacheMode(int) 599 | * Set the cacheMode. Possible values are: 600 | * 601 | * - `'LOAD_DEFAULT'` (default) 602 | * - `'LOAD_CACHE_ELSE_NETWORK'` 603 | * - `'LOAD_NO_CACHE'` 604 | * - `'LOAD_CACHE_ONLY'` 605 | * 606 | * @platform android 607 | */ 608 | cacheMode?: CacheMode; 609 | /** 610 | * https://developer.android.com/reference/android/view/View#OVER_SCROLL_NEVER 611 | * Sets the overScrollMode. Possible values are: 612 | * 613 | * - `'always'` (default) 614 | * - `'content'` 615 | * - `'never'` 616 | * 617 | * @platform android 618 | */ 619 | overScrollMode?: OverScrollModeType; 620 | /** 621 | * Boolean that controls whether the web content is scaled to fit 622 | * the view and enables the user to change the scale. The default value 623 | * is `true`. 624 | */ 625 | scalesPageToFit?: boolean; 626 | /** 627 | * Sets whether Geolocation is enabled. The default is false. 628 | * @platform android 629 | */ 630 | geolocationEnabled?: boolean; 631 | /** 632 | * Boolean that sets whether JavaScript running in the context of a file 633 | * scheme URL should be allowed to access content from other file scheme URLs. 634 | * Including accessing content from other file scheme URLs 635 | * @platform android 636 | */ 637 | allowFileAccessFromFileURLs?: boolean; 638 | /** 639 | * Boolean that sets whether JavaScript running in the context of a file 640 | * scheme URL should be allowed to access content from any origin. 641 | * Including accessing content from other file scheme URLs 642 | * @platform android 643 | */ 644 | allowUniversalAccessFromFileURLs?: boolean; 645 | /** 646 | * Sets whether the webview allow access to file system. 647 | * @platform android 648 | */ 649 | allowFileAccess?: boolean; 650 | /** 651 | * Used on Android only, controls whether form autocomplete data should be saved 652 | * @platform android 653 | */ 654 | saveFormDataDisabled?: boolean; 655 | /** 656 | * Used on Android only, controls whether the given list of URL prefixes should 657 | * make {@link com.facebook.react.views.webview.ReactWebViewClient} to launch a 658 | * default activity intent for those URL instead of loading it within the webview. 659 | * Use this to list URLs that WebView cannot handle, e.g. a PDF url. 660 | * @platform android 661 | */ 662 | readonly urlPrefixesForDefaultIntent?: string[]; 663 | /** 664 | * Boolean value to disable Hardware Acceleration in the `WebView`. Used on Android only 665 | * as Hardware Acceleration is a feature only for Android. The default value is `false`. 666 | * @platform android 667 | */ 668 | androidHardwareAccelerationDisabled?: boolean; 669 | /** 670 | * https://developer.android.com/reference/android/webkit/WebView#setLayerType(int,%20android.graphics.Paint) 671 | * Sets the layerType. Possible values are: 672 | * 673 | * - `'none'` (default) 674 | * - `'software'` 675 | * - `'hardware'` 676 | * 677 | * @platform android 678 | */ 679 | androidLayerType?: AndroidLayerType; 680 | /** 681 | * Boolean value to enable third party cookies in the `WebView`. Used on 682 | * Android Lollipop and above only as third party cookies are enabled by 683 | * default on Android Kitkat and below and on iOS. The default value is `true`. 684 | * @platform android 685 | */ 686 | thirdPartyCookiesEnabled?: boolean; 687 | /** 688 | * Boolean value to control whether DOM Storage is enabled. Used only in 689 | * Android. 690 | * @platform android 691 | */ 692 | domStorageEnabled?: boolean; 693 | /** 694 | * Sets the user-agent for the `WebView`. 695 | * @platform android 696 | */ 697 | userAgent?: string; 698 | /** 699 | * Sets number that controls text zoom of the page in percent. 700 | * @platform android 701 | */ 702 | textZoom?: number; 703 | /** 704 | * Specifies the mixed content mode. i.e WebView will allow a secure origin to load content from any other origin. 705 | * 706 | * Possible values for `mixedContentMode` are: 707 | * 708 | * - `'never'` (default) - WebView will not allow a secure origin to load content from an insecure origin. 709 | * - `'always'` - WebView will allow a secure origin to load content from any other origin, even if that origin is insecure. 710 | * - `'compatibility'` - WebView will attempt to be compatible with the approach of a modern web browser with regard to mixed content. 711 | * @platform android 712 | */ 713 | mixedContentMode?: 'never' | 'always' | 'compatibility'; 714 | /** 715 | * Sets ability to open fullscreen videos on Android devices. 716 | */ 717 | allowsFullscreenVideo?: boolean; 718 | } 719 | export interface WebViewSharedProps extends ViewProps { 720 | /** 721 | * Loads static html or a uri (with optional headers) in the WebView. 722 | */ 723 | source?: WebViewSource; 724 | /** 725 | * Boolean value to enable JavaScript in the `WebView`. Used on Android only 726 | * as JavaScript is enabled by default on iOS. The default value is `true`. 727 | * @platform android 728 | */ 729 | javaScriptEnabled?: boolean; 730 | /** 731 | * A Boolean value indicating whether JavaScript can open windows without user interaction. 732 | * The default value is `false`. 733 | */ 734 | javaScriptCanOpenWindowsAutomatically?: boolean; 735 | /** 736 | * Stylesheet object to set the style of the container view. 737 | */ 738 | containerStyle?: StyleProp; 739 | /** 740 | * Function that returns a view to show if there's an error. 741 | */ 742 | renderError?: (errorDomain: string | undefined, errorCode: number, errorDesc: string) => ReactElement; 743 | /** 744 | * Function that returns a loading indicator. 745 | */ 746 | renderLoading?: () => ReactElement; 747 | /** 748 | * Function that is invoked when the `WebView` scrolls. 749 | */ 750 | onScroll?: (event: NativeScrollEvent) => void; 751 | /** 752 | * Function that is invoked when the `WebView` has finished loading. 753 | */ 754 | onLoad?: (event: WebViewNavigationEvent) => void; 755 | /** 756 | * Function that is invoked when the `WebView` load succeeds or fails. 757 | */ 758 | onLoadEnd?: (event: WebViewNavigationEvent | WebViewErrorEvent) => void; 759 | /** 760 | * Function that is invoked when the `WebView` starts loading. 761 | */ 762 | onLoadStart?: (event: WebViewNavigationEvent) => void; 763 | /** 764 | * Function that is invoked when the `WebView` load fails. 765 | */ 766 | onError?: (event: WebViewErrorEvent) => void; 767 | /** 768 | * Function that is invoked when the `WebView` receives an error status code. 769 | * Works on iOS and Android (minimum API level 23). 770 | */ 771 | onHttpError?: (event: WebViewHttpErrorEvent) => void; 772 | /** 773 | * Function that is invoked when the `WebView` loading starts or ends. 774 | */ 775 | onNavigationStateChange?: (event: WebViewNavigation) => void; 776 | /** 777 | * Function that is invoked when the webview calls `window.ReactNativeWebView.postMessage`. 778 | * Setting this property will inject this global into your webview. 779 | * 780 | * `window.ReactNativeWebView.postMessage` accepts one argument, `data`, which will be 781 | * available on the event object, `event.nativeEvent.data`. `data` must be a string. 782 | */ 783 | onMessage?: (event: WebViewMessageEvent) => void; 784 | /** 785 | * Function that is invoked when the `WebView` is loading. 786 | */ 787 | onLoadProgress?: (event: WebViewProgressEvent) => void; 788 | /** 789 | * Boolean value that forces the `WebView` to show the loading view 790 | * on the first load. 791 | */ 792 | startInLoadingState?: boolean; 793 | /** 794 | * Set this to provide JavaScript that will be injected into the web page 795 | * when the view loads. 796 | */ 797 | injectedJavaScript?: string; 798 | /** 799 | * Set this to provide JavaScript that will be injected into the web page 800 | * once the webview is initialized but before the view loads any content. 801 | */ 802 | injectedJavaScriptBeforeContentLoaded?: string; 803 | /** 804 | * If `true` (default; mandatory for Android), loads the `injectedJavaScript` only into the main frame. 805 | * If `false` (only supported on iOS and macOS), loads it into all frames (e.g. iframes). 806 | */ 807 | injectedJavaScriptForMainFrameOnly?: boolean; 808 | /** 809 | * If `true` (default; mandatory for Android), loads the `injectedJavaScriptBeforeContentLoaded` only into the main frame. 810 | * If `false` (only supported on iOS and macOS), loads it into all frames (e.g. iframes). 811 | */ 812 | injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean; 813 | /** 814 | * Boolean value that determines whether a horizontal scroll indicator is 815 | * shown in the `WebView`. The default value is `true`. 816 | */ 817 | showsHorizontalScrollIndicator?: boolean; 818 | /** 819 | * Boolean value that determines whether a vertical scroll indicator is 820 | * shown in the `WebView`. The default value is `true`. 821 | */ 822 | showsVerticalScrollIndicator?: boolean; 823 | /** 824 | * Boolean that determines whether HTML5 audio and video requires the user 825 | * to tap them before they start playing. The default value is `true`. 826 | */ 827 | mediaPlaybackRequiresUserAction?: boolean; 828 | /** 829 | * List of origin strings to allow being navigated to. The strings allow 830 | * wildcards and get matched against *just* the origin (not the full URL). 831 | * If the user taps to navigate to a new page but the new page is not in 832 | * this whitelist, we will open the URL in Safari. 833 | * The default whitelisted origins are "http://*" and "https://*". 834 | */ 835 | readonly originWhitelist?: string[]; 836 | /** 837 | * Function that allows custom handling of any web view requests. Return 838 | * `true` from the function to continue loading the request and `false` 839 | * to stop loading. The `navigationType` is always `other` on android. 840 | */ 841 | onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest; 842 | /** 843 | * Override the native component used to render the WebView. Enables a custom native 844 | * WebView which uses the same JavaScript as the original WebView. 845 | */ 846 | nativeConfig?: WebViewNativeConfig; 847 | /** 848 | * Should caching be enabled. Default is true. 849 | */ 850 | cacheEnabled?: boolean; 851 | /** 852 | * Append to the existing user-agent. Overridden if `userAgent` is set. 853 | */ 854 | applicationNameForUserAgent?: string; 855 | } 856 | export {}; 857 | //# sourceMappingURL=WebViewTypes.d.ts.map -------------------------------------------------------------------------------- /lib/WebViewTypes.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"WebViewTypes.d.ts","sourceRoot":"","sources":["../src/WebViewTypes.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /lib/WebViewTypes.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/no-multi-comp, max-classes-per-file */ 2 | var __extends = (this && this.__extends) || (function () { 3 | var extendStatics = function (d, b) { 4 | extendStatics = Object.setPrototypeOf || 5 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 6 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 7 | return extendStatics(d, b); 8 | }; 9 | return function (d, b) { 10 | extendStatics(d, b); 11 | function __() { this.constructor = d; } 12 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 13 | }; 14 | })(); 15 | import { Component } from 'react'; 16 | var NativeWebViewIOS = /** @class */ (function (_super) { 17 | __extends(NativeWebViewIOS, _super); 18 | function NativeWebViewIOS() { 19 | return _super !== null && _super.apply(this, arguments) || this; 20 | } 21 | return NativeWebViewIOS; 22 | }(NativeWebViewIOSBase)); 23 | export { NativeWebViewIOS }; 24 | var NativeWebViewMacOS = /** @class */ (function (_super) { 25 | __extends(NativeWebViewMacOS, _super); 26 | function NativeWebViewMacOS() { 27 | return _super !== null && _super.apply(this, arguments) || this; 28 | } 29 | return NativeWebViewMacOS; 30 | }(NativeWebViewMacOSBase)); 31 | export { NativeWebViewMacOS }; 32 | var NativeWebViewAndroid = /** @class */ (function (_super) { 33 | __extends(NativeWebViewAndroid, _super); 34 | function NativeWebViewAndroid() { 35 | return _super !== null && _super.apply(this, arguments) || this; 36 | } 37 | return NativeWebViewAndroid; 38 | }(NativeWebViewAndroidBase)); 39 | export { NativeWebViewAndroid }; 40 | var NativeWebViewWindows = /** @class */ (function (_super) { 41 | __extends(NativeWebViewWindows, _super); 42 | function NativeWebViewWindows() { 43 | return _super !== null && _super.apply(this, arguments) || this; 44 | } 45 | return NativeWebViewWindows; 46 | }(NativeWebViewWindowsBase)); 47 | export { NativeWebViewWindows }; 48 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-webview-tencentx5", 3 | "description": "React Native WebView component for Android, Use Tencent TBSX5", 4 | "main": "index.js", 5 | "typings": "index.d.ts", 6 | "author": { 7 | "name": "raindrop-c", 8 | "email": "353144270@qq.com" 9 | }, 10 | "license": "MIT", 11 | "version": "1.0.2", 12 | "scripts": { 13 | "start": "node node_modules/react-native/local-cli/cli.js start", 14 | "start:android": "react-native run-android", 15 | "start:ios": "react-native run-ios", 16 | "start:macos": "node node_modules/react-native-macos/local-cli/cli.js start --use-react-native-macos", 17 | "start:windows": "react-native start --use-react-native-windows", 18 | "ci": "CI=true && yarn lint", 19 | "ci:publish": "yarn semantic-release" 20 | }, 21 | "rn-docs": { 22 | "title": "Webview", 23 | "type": "Component" 24 | }, 25 | "peerDependencies": { 26 | "react-native": ">=0.60 <0.64" 27 | }, 28 | "dependencies": { 29 | "escape-string-regexp": "2.0.0", 30 | "invariant": "2.2.4" 31 | }, 32 | "devDependencies": { 33 | "@babel/core": "7.4.5", 34 | "@babel/runtime": "7.4.5", 35 | "@react-native-community/cli": "^4.8.0", 36 | "@react-native-community/cli-platform-android": "^4.8.0", 37 | "@react-native-community/cli-platform-ios": "^4.8.0", 38 | "@semantic-release/git": "7.0.16", 39 | "@types/invariant": "^2.2.30", 40 | "@types/jest": "24.0.18", 41 | "@types/react": "16.9.34", 42 | "@types/react-native": "0.62.5", 43 | "@types/selenium-webdriver": "4.0.9", 44 | "@typescript-eslint/eslint-plugin": "2.1.0", 45 | "@typescript-eslint/parser": "2.1.0", 46 | "babel-eslint": "10.0.3", 47 | "babel-jest": "24.8.0", 48 | "babel-plugin-module-resolver": "3.1.3", 49 | "eslint": "6.3.0", 50 | "eslint-config-airbnb": "18.0.1", 51 | "eslint-config-prettier": "6.2.0", 52 | "eslint-plugin-import": "2.18.2", 53 | "eslint-plugin-jsx-a11y": "6.2.3", 54 | "eslint-plugin-react": "7.14.3", 55 | "eslint-plugin-react-native": "3.7.0", 56 | "jest": "24.9.0", 57 | "metro": "0.56.4", 58 | "metro-react-native-babel-preset": "^0.59.0", 59 | "react": "16.11.0", 60 | "react-native": "0.62.2", 61 | "react-native-macos": "0.60.0-microsoft.73", 62 | "react-native-windows": "^0.62.0-0", 63 | "semantic-release": "15.13.24", 64 | "typescript": "3.8.3", 65 | "appium": "1.17.0", 66 | "selenium-appium": "0.0.15", 67 | "selenium-webdriver": "4.0.0-alpha.7" 68 | }, 69 | "repository": { 70 | "type": "git", 71 | "url": "https://github.com/RainDrop-C/react-native-webview-tencentx5.git" 72 | }, 73 | "files": [ 74 | "android", 75 | "ios", 76 | "lib", 77 | "index.js", 78 | "index.d.ts" 79 | ] 80 | } 81 | -------------------------------------------------------------------------------- /react-native-webview-tencentx5.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = package['name'] 7 | s.version = package['version'] 8 | s.summary = package['description'] 9 | s.license = package['license'] 10 | s.homepage = 'https://github.com/baiachen/react-native-webview-tencentx5' 11 | 12 | s.authors = package['author'] 13 | s.platforms = { :ios => "9.0", :osx => "10.13" } 14 | 15 | s.source = { :git => "https://github.com/RainDrop-C/react-native-webview-tencentx5.git" } 16 | s.source_files = "apple/**/*.{h,m}" 17 | 18 | s.dependency 'React' 19 | end 20 | --------------------------------------------------------------------------------