Browse Source

Merge branch 'master' into docs-cookies

Jason Safaiyeh 4 years ago
parent
commit
a679d4e657
No account linked to committer's email address
51 changed files with 5100 additions and 6961 deletions
  1. 1
    0
      README.md
  2. 1
    1
      android/build.gradle
  3. 0
    27
      android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java
  4. 15
    0
      android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.kt
  5. 1
    0
      babel.config.js
  6. 38
    0
      docs/Contributing.md
  7. 15
    7
      docs/Getting-Started.md
  8. 18
    18
      docs/Reference.md
  9. 4
    1
      example/.gitignore
  10. 155
    13
      example/App.tsx
  11. 7
    4
      example/android/app/build.gradle
  12. 3
    1
      example/android/app/src/main/java/com/example/MainApplication.java
  13. 2
    2
      example/android/build.gradle
  14. 3
    1
      example/android/settings.gradle
  15. 72
    0
      example/examples/Alerts.tsx
  16. 54
    0
      example/examples/Background.tsx
  17. 68
    0
      example/examples/Scrolling.tsx
  18. 34
    31
      example/ios/Podfile
  19. 59
    59
      example/ios/Podfile.lock
  20. 4
    4
      example/ios/example.xcodeproj/project.pbxproj
  21. 1
    1
      example/ios/example/AppDelegate.m
  22. 16
    0
      example/macos/example-macOS/AppDelegate.h
  23. 39
    0
      example/macos/example-macOS/AppDelegate.m
  24. 45
    0
      example/macos/example-macOS/Info.plist
  25. 713
    0
      example/macos/example-macOS/Main.storyboard
  26. 12
    0
      example/macos/example-macOS/ViewController.h
  27. 29
    0
      example/macos/example-macOS/ViewController.m
  28. 12
    0
      example/macos/example-macOS/main.m
  29. 1569
    0
      example/macos/example.xcodeproj/project.pbxproj
  30. 10
    0
      example/macos/example.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  31. 92
    0
      example/macos/example.xcodeproj/xcshareddata/xcschemes/example-macOS.xcscheme
  32. 92
    0
      example/macos/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme
  33. 15
    0
      example/macos/example/AppDelegate.h
  34. 42
    0
      example/macos/example/AppDelegate.m
  35. 42
    0
      example/macos/example/Base.lproj/LaunchScreen.xib
  36. 53
    0
      example/macos/example/Images.xcassets/AppIcon.appiconset/Contents.json
  37. 6
    0
      example/macos/example/Images.xcassets/Contents.json
  38. 57
    0
      example/macos/example/Info.plist
  39. 16
    0
      example/macos/example/main.m
  40. 0
    39
      example/package.json
  41. 0
    6591
      example/yarn.lock
  42. 168
    38
      ios/RNCWebView.m
  43. 6
    13
      ios/RNCWebViewManager.m
  44. 363
    0
      macos/RNCWebView.xcodeproj/project.pbxproj
  45. 12
    0
      metro.config.js
  46. 19
    0
      metro.config.macos.js
  47. 18
    8
      package.json
  48. 26
    0
      react-native.config.js
  49. 347
    0
      src/WebView.macos.tsx
  50. 175
    14
      src/WebViewTypes.ts
  51. 551
    88
      yarn.lock

+ 1
- 0
README.md View File

@@ -20,6 +20,7 @@ _This project is maintained for free by these people using both their free time
20 20
 
21 21
 - [x] iOS
22 22
 - [x] Android
23
+- [x] macOS
23 24
 
24 25
 _Note: Expo support for React Native WebView started with [Expo SDK v33.0.0](https://blog.expo.io/expo-sdk-v33-0-0-is-now-available-52d1c99dfe4c)._
25 26
 

+ 1
- 1
android/build.gradle View File

@@ -123,6 +123,6 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
123 123
 
124 124
 dependencies {
125 125
   //noinspection GradleDynamicVersion
126
-  api 'com.facebook.react:react-native:+'
126
+  implementation 'com.facebook.react:react-native:+'
127 127
   implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
128 128
 }

+ 0
- 27
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java View File

@@ -1,27 +0,0 @@
1
-package com.reactnativecommunity.webview;
2
-
3
-import com.facebook.react.ReactPackage;
4
-import com.facebook.react.bridge.JavaScriptModule;
5
-import com.facebook.react.bridge.NativeModule;
6
-import com.facebook.react.bridge.ReactApplicationContext;
7
-import com.facebook.react.uimanager.ViewManager;
8
-
9
-import java.util.Collections;
10
-import java.util.List;
11
-
12
-public class RNCWebViewPackage implements ReactPackage {
13
-  @Override
14
-  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
15
-    return Collections.singletonList(new RNCWebViewModule(reactContext));
16
-  }
17
-
18
-  // Deprecated from RN 0.47
19
-  public List<Class<? extends JavaScriptModule>> createJSModules() {
20
-    return Collections.emptyList();
21
-  }
22
-
23
-  @Override
24
-  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
25
-    return Collections.singletonList(new RNCWebViewManager());
26
-  }
27
-}

+ 15
- 0
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.kt View File

@@ -0,0 +1,15 @@
1
+package com.reactnativecommunity.webview
2
+
3
+import com.facebook.react.ReactPackage
4
+import com.facebook.react.bridge.ReactApplicationContext
5
+
6
+
7
+class RNCWebViewPackage: ReactPackage {
8
+  override fun createNativeModules(reactContext: ReactApplicationContext) = listOf(
9
+    RNCWebViewModule(reactContext)
10
+  )
11
+
12
+  override fun createViewManagers(reactContext: ReactApplicationContext) = listOf(
13
+    RNCWebViewManager()
14
+  )
15
+}

+ 1
- 0
babel.config.js View File

@@ -6,5 +6,6 @@ module.exports = function(api) {
6 6
         presets: ['module:metro-react-native-babel-preset'],
7 7
       },
8 8
     },
9
+    presets: ['module:metro-react-native-babel-preset'],
9 10
   };
10 11
 };

+ 38
- 0
docs/Contributing.md View File

@@ -8,6 +8,44 @@ Secondly, we'd like the contribution experience to be as good as possible. While
8 8
 
9 9
 After you fork the repo, clone it to your machine, and make your changes, you'll want to test them in an app.
10 10
 
11
+There are two methods of testing:
12
+1) Testing within a clone of react-native-webview
13
+2) Testing in a new `react-native init` project
14
+
15
+### Testing within react-native-webview
16
+
17
+#### For all platforms:
18
+```
19
+$ yarn install
20
+```
21
+
22
+#### For Android:
23
+```
24
+$ yarn start:android
25
+```
26
+
27
+The Android example app will built, the Metro Bundler will launch, and the example app will be installed and started in the Android emulator.
28
+
29
+#### For iOS:
30
+```
31
+$ cd example/ios
32
+$ pod install
33
+$ cd ../..
34
+$ yarn start:ios
35
+```
36
+
37
+The iOS example app will be built, the Metro bundler will launch, and the example app will be install and started in the Simulator.
38
+
39
+#### for macOS:
40
+```
41
+$ open example/macos/example.xcodeproj
42
+$ yarn start:macos
43
+```
44
+
45
+The Metro Bundler will now be running in the Terminal for react-native-macos.  In XCode select the `example-macos` target and Run.
46
+
47
+### Testing in a new `react-native init` project
48
+
11 49
 In a new `react-native init` project, do this:
12 50
 
13 51
 ```

+ 15
- 7
docs/Getting-Started.md View File

@@ -2,7 +2,7 @@
2 2
 
3 3
 Here's how to get started quickly with the React Native WebView.
4 4
 
5
-#### 1. Add react-native-webview to your dependencies
5
+## 1. Add react-native-webview to your dependencies
6 6
 
7 7
 ```
8 8
 $ yarn add react-native-webview
@@ -14,7 +14,7 @@ $ yarn add react-native-webview
14 14
 $ npm install --save react-native-webview
15 15
 ```
16 16
 
17
-#### 2. Link native dependencies
17
+## 2. Link native dependencies
18 18
 
19 19
 From react-native 0.60 autolinking will take care of the link step but don't forget to run `pod install`
20 20
 
@@ -24,13 +24,20 @@ React Native modules that include native Objective-C, Swift, Java, or Kotlin cod
24 24
 $ react-native link react-native-webview
25 25
 ```
26 26
 
27
-iOS:
27
+_NOTE: If you ever need to uninstall React Native WebView, run `react-native unlink react-native-webview` to unlink it._
28
+
29
+### iOS:
28 30
 
29 31
 If using cocoapods in the `ios/` directory run
30 32
 ```
31 33
 $ pod install
32 34
 ```
33 35
 
36
+For iOS, while you can manually link the old way using [react-native own tutorial](https://facebook.github.io/react-native/docs/linking-libraries-ios), we find it easier to use cocoapods.
37
+If you wish to use cocoapods and haven't set it up yet, please instead refer to [that article](https://engineering.brigad.co/demystifying-react-native-modules-linking-ae6c017a6b4a).
38
+
39
+### Android:
40
+
34 41
 Android - react-native-webview version <6:
35 42
 This module does not require any extra step after running the link command 🎉
36 43
 
@@ -44,12 +51,13 @@ android.enableJetifier=true
44 51
 
45 52
 For Android manual installation, please refer to [this article](https://engineering.brigad.co/demystifying-react-native-modules-linking-964399ec731b) where you can find detailed step on how to link any react-native project.
46 53
 
47
-For iOS, while you can manually link the old way using [react-native own tutorial](https://facebook.github.io/react-native/docs/linking-libraries-ios), we find it easier to use cocoapods.
48
-If you wish to use cocoapods and haven't set it up yet, please instead refer to [that article](https://engineering.brigad.co/demystifying-react-native-modules-linking-ae6c017a6b4a).
54
+### macOS:
49 55
 
50
-_NOTE: If you ever need to uninstall React Native WebView, run `react-native unlink react-native-webview` to unlink it._
56
+Cocoapod and autolinking is not yet support for react-native macOS but is coming soon.  In the meantime you must manually link.
57
+
58
+The method is nearly identical to the [manual linking method for iOS](https://facebook.github.io/react-native/docs/linking-libraries-ios#manual-linking) except that you will include the `node_modules/react-native-webview/macos/RNCWebView.xcodeproj` project in your main project and link the `RNCWebView-macOS.a` library. 
51 59
 
52
-#### 3. Import the webview into your component
60
+## 3. Import the webview into your component
53 61
 
54 62
 ```js
55 63
 import React, { Component } from 'react';

+ 18
- 18
docs/Reference.md View File

@@ -474,9 +474,9 @@ Note that this method will not be invoked on hash URL changes (e.g. from `https:
474 474
 
475 475
 Function that is invoked when the `WebView` content process is terminated.
476 476
 
477
-| Type     | Required | Platform      |
478
-| -------- | -------- | ------------- |
479
-| function | No       | iOS WKWebView |
477
+| Type     | Required | Platform                |
478
+| -------- | -------- | ----------------------- |
479
+| function | No       | iOS and macOS WKWebView |
480 480
 
481 481
 Example:
482 482
 
@@ -863,9 +863,9 @@ Possible values for `dataDetectorTypes` are:
863 863
 
864 864
 Boolean value that determines whether scrolling is enabled in the `WebView`. The default value is `true`. Setting this to `false` will prevent the webview from moving the document body when the keyboard appears over an input.
865 865
 
866
-| Type | Required | Platform |
867
-| ---- | -------- | -------- |
868
-| bool | No       | iOS      |
866
+| Type | Required | Platform      |
867
+| ---- | -------- | ------------- |
868
+| bool | No       | iOS and macOS |
869 869
 
870 870
 ---
871 871
 
@@ -934,9 +934,9 @@ Boolean that sets whether JavaScript running in the context of a file scheme URL
934 934
 
935 935
 A String value that indicates which URLs the WebView's file can then reference in scripts, AJAX requests, and CSS imports. This is only used in for WebViews that are loaded with a source.uri set to a `'file://'` URL. If not provided, the default is to only allow read access to the URL provided in source.uri itself.
936 936
 
937
-| Type   | Required | Platform |
938
-| ------ | -------- | -------- |
939
-| string | No       | iOS      |
937
+| Type   | Required | Platform      |
938
+| ------ | -------- | ------------- |
939
+| string | No       | iOS and macOS |
940 940
 
941 941
 ---
942 942
 
@@ -984,9 +984,9 @@ If true, this will hide the keyboard accessory view (< > and Done).
984 984
 
985 985
 If true, this will be able horizontal swipe gestures. The default value is `false`.
986 986
 
987
-| Type    | Required | Platform |
988
-| ------- | -------- | -------- |
989
-| boolean | No       | iOS      |
987
+| Type    | Required | Platform          |
988
+| ------- | -------- | ----------------- |
989
+| boolean | No       | iOS and macOS     |
990 990
 
991 991
 ---
992 992
 
@@ -1061,9 +1061,9 @@ If the value of this property is true, the scroll view stops on multiples of the
1061 1061
 
1062 1062
 A Boolean value that determines whether pressing on a link displays a preview of the destination for the link. In iOS this property is available on devices that support 3D Touch. In iOS 10 and later, the default value is true; before that, the default value is false.
1063 1063
 
1064
-| Type    | Required | Platform |
1065
-| ------- | -------- | -------- |
1066
-| boolean | No       | iOS      |
1064
+| Type    | Required | Platform          |
1065
+| ------- | -------- | ----------------- |
1066
+| boolean | No       | iOS and macOS     |
1067 1067
 
1068 1068
 ---
1069 1069
 
@@ -1071,9 +1071,9 @@ A Boolean value that determines whether pressing on a link displays a preview of
1071 1071
 
1072 1072
 Set `true` if shared cookies from `[NSHTTPCookieStorage sharedHTTPCookieStorage]` should used for every load request in the WebView. The default value is `false`. For more on cookies, read the [Guide](Guide.md#Managing-Cookies)
1073 1073
 
1074
-| Type    | Required | Platform |
1075
-| ------- | -------- | -------- |
1076
-| boolean | No       | iOS      |
1074
+| Type    | Required | Platform          |
1075
+| ------- | -------- | ----------------- |
1076
+| boolean | No       | iOS and macOS     |
1077 1077
 
1078 1078
 ---
1079 1079
 

+ 4
- 1
example/.gitignore View File

@@ -20,7 +20,10 @@ DerivedData
20 20
 *.hmap
21 21
 *.ipa
22 22
 *.xcuserstate
23
-project.xcworkspace
23
+# exclude project.xcworkspace except for xcshareddata/WorkspaceSettings.xcsettings
24
+project.xcworkspace/*
25
+**/project.xcworkspace/contents.xcworkspacedata
26
+**/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
24 27
 
25 28
 # Android/IntelliJ
26 29
 #

+ 155
- 13
example/App.tsx View File

@@ -1,17 +1,159 @@
1
-import React from 'react';
2
-import {SafeAreaView, StyleSheet} from 'react-native';
3
-import {WebView} from 'react-native-webview';
1
+import React, {Component} from 'react';
2
+import {
3
+  StyleSheet,
4
+  SafeAreaView,
5
+  Text,
6
+  TouchableOpacity,
7
+  View,
8
+  Keyboard,
9
+  Button,
10
+} from 'react-native';
4 11
 
5
-const styles = StyleSheet.create({
6
-  container: {flex: 1, backgroundColor: '#20232a'},
7
-});
12
+import Alerts from './examples/Alerts';
13
+import Scrolling from './examples/Scrolling';
14
+import Background from './examples/Background';
8 15
 
9
-const App = () => {
10
-  return (
11
-    <SafeAreaView style={styles.container}>
12
-      <WebView source={{uri: 'https://facebook.github.io/react-native/'}} />
13
-    </SafeAreaView>
14
-  );
16
+const TESTS = {
17
+  Alerts: {
18
+    title: 'Alerts',
19
+    testId: 'alerts',
20
+    description: 'Alerts tests',
21
+    render() {
22
+      return <Alerts />;
23
+    },
24
+  },
25
+  Scrolling: {
26
+    title: 'Scrolling',
27
+    testId: 'scrolling',
28
+    description: 'Scrolling event test',
29
+    render() {
30
+      return <Scrolling />;
31
+    },
32
+  },
33
+  Background: {
34
+    title: 'Background',
35
+    testId: 'background',
36
+    description: 'Background color test',
37
+    render() {
38
+      return <Background />;
39
+    },
40
+  },
15 41
 };
16 42
 
17
-export default App;
43
+type Props = {};
44
+type State = {restarting: boolean, currentTest: Object};
45
+
46
+export default class App extends Component<Props, State> {
47
+  state = {
48
+    restarting: false,
49
+    currentTest: TESTS.Alerts,
50
+  };
51
+
52
+  _simulateRestart = () => {
53
+    this.setState({restarting: true}, () => this.setState({restarting: false}));
54
+  };
55
+
56
+  _changeTest = testName => {
57
+    this.setState({currentTest: TESTS[testName]});
58
+  };
59
+
60
+  render() {
61
+    const {restarting, currentTest} = this.state;
62
+    return (
63
+      <SafeAreaView style={styles.container}>
64
+        <TouchableOpacity
65
+          style={styles.closeKeyboardView}
66
+          onPress={() => Keyboard.dismiss()}
67
+          testID="closeKeyboard"
68
+        />
69
+
70
+        <TouchableOpacity
71
+          testID="restart_button"
72
+          onPress={this._simulateRestart}
73
+          style={styles.restartButton}
74
+          activeOpacity={0.6}>
75
+          <Text>Simulate Restart</Text>
76
+        </TouchableOpacity>
77
+
78
+        <View style={styles.testPickerContainer}>
79
+          <Button
80
+            testID="testType_alerts"
81
+            title="Alerts"
82
+            onPress={() => this._changeTest('Alerts')}
83
+          />
84
+          <Button
85
+            testID="testType_scrolling"
86
+            title="Scrolling"
87
+            onPress={() => this._changeTest('Scrolling')}
88
+          />
89
+          <Button
90
+            testID="testType_background"
91
+            title="Background"
92
+            onPress={() => this._changeTest('Background')}
93
+          />
94
+        </View>
95
+
96
+        {restarting ? null : (
97
+          <View
98
+            testID={`example-${currentTest.testId}`}
99
+            key={currentTest.title}
100
+            style={styles.exampleContainer}>
101
+            <Text style={styles.exampleTitle}>{currentTest.title}</Text>
102
+            <Text style={styles.exampleDescription}>
103
+              {currentTest.description}
104
+            </Text>
105
+            <View style={styles.exampleInnerContainer}>
106
+              {currentTest.render()}
107
+            </View>
108
+          </View>
109
+        )}
110
+      </SafeAreaView>
111
+    );
112
+  }
113
+}
114
+
115
+const styles = StyleSheet.create({
116
+  container: {
117
+    flex: 1,
118
+    backgroundColor: '#F5FCFF',
119
+    padding: 8,
120
+  },
121
+  exampleContainer: {
122
+    padding: 16,
123
+    backgroundColor: '#FFF',
124
+    borderColor: '#EEE',
125
+    borderTopWidth: 1,
126
+    borderBottomWidth: 1,
127
+    flex: 1,
128
+  },
129
+  exampleTitle: {
130
+    fontSize: 18,
131
+  },
132
+  exampleDescription: {
133
+    color: '#333333',
134
+    marginBottom: 16,
135
+  },
136
+  exampleInnerContainer: {
137
+    borderColor: '#EEE',
138
+    borderTopWidth: 1,
139
+    paddingTop: 10,
140
+    flex: 1,
141
+  },
142
+  restartButton: {
143
+    padding: 6,
144
+    fontSize: 16,
145
+    borderRadius: 5,
146
+    backgroundColor: '#F3F3F3',
147
+    alignItems: 'center',
148
+    justifyContent: 'center',
149
+    alignSelf: 'flex-end',
150
+  },
151
+  closeKeyboardView: {
152
+    width: 5,
153
+    height: 5,
154
+  },
155
+  testPickerContainer: {
156
+    flexDirection: 'row',
157
+    flexWrap: 'wrap',
158
+  },
159
+});

+ 7
- 4
example/android/app/build.gradle View File

@@ -76,11 +76,13 @@ import com.android.build.OutputFile
76 76
  */
77 77
 
78 78
 project.ext.react = [
79
-    entryFile: "index.js",
79
+    cliPath: "../../../node_modules/react-native/local-cli/cli.js",
80
+    entryFile: "./example/index.js",
81
+    root: "../../../",
80 82
     enableHermes: false,  // clean and rebuild if changing
81 83
 ]
82 84
 
83
-apply from: "../../node_modules/react-native/react.gradle"
85
+apply from: "../../../node_modules/react-native/react.gradle"
84 86
 
85 87
 /**
86 88
  * Set this to true to create two separate APKs instead of one:
@@ -179,11 +181,12 @@ android {
179 181
 }
180 182
 
181 183
 dependencies {
184
+    implementation project(':rnWebView')
182 185
     implementation fileTree(dir: "libs", include: ["*.jar"])
183 186
     implementation "com.facebook.react:react-native:+"  // From node_modules
184 187
 
185 188
     if (enableHermes) {
186
-        def hermesPath = "../../node_modules/hermes-engine/android/";
189
+        def hermesPath = "../../../node_modules/hermes-engine/android/";
187 190
         debugImplementation files(hermesPath + "hermes-debug.aar")
188 191
         releaseImplementation files(hermesPath + "hermes-release.aar")
189 192
     } else {
@@ -198,4 +201,4 @@ task copyDownloadableDepsToLibs(type: Copy) {
198 201
     into 'libs'
199 202
 }
200 203
 
201
-apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
204
+apply from: file("../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

+ 3
- 1
example/android/app/src/main/java/com/example/MainApplication.java View File

@@ -7,6 +7,7 @@ import com.facebook.react.ReactApplication;
7 7
 import com.facebook.react.ReactNativeHost;
8 8
 import com.facebook.react.ReactPackage;
9 9
 import com.facebook.soloader.SoLoader;
10
+import com.reactnativecommunity.webview.RNCWebViewPackage;
10 11
 import java.lang.reflect.InvocationTargetException;
11 12
 import java.util.List;
12 13
 
@@ -25,12 +26,13 @@ public class MainApplication extends Application implements ReactApplication {
25 26
           List<ReactPackage> packages = new PackageList(this).getPackages();
26 27
           // Packages that cannot be autolinked yet can be added manually here, for example:
27 28
           // packages.add(new MyReactNativePackage());
29
+          packages.add(new RNCWebViewPackage());
28 30
           return packages;
29 31
         }
30 32
 
31 33
         @Override
32 34
         protected String getJSMainModuleName() {
33
-          return "index";
35
+          return "example/index";
34 36
         }
35 37
       };
36 38
 

+ 2
- 2
example/android/build.gradle View File

@@ -24,11 +24,11 @@ allprojects {
24 24
         mavenLocal()
25 25
         maven {
26 26
             // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
27
-            url("$rootDir/../node_modules/react-native/android")
27
+            url("$rootDir/../../node_modules/react-native/android")
28 28
         }
29 29
         maven {
30 30
             // Android JSC is installed from npm
31
-            url("$rootDir/../node_modules/jsc-android/dist")
31
+            url("$rootDir/../../node_modules/jsc-android/dist")
32 32
         }
33 33
 
34 34
         google()

+ 3
- 1
example/android/settings.gradle View File

@@ -1,3 +1,5 @@
1 1
 rootProject.name = 'example'
2
-apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
2
+apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
3 3
 include ':app'
4
+include ':rnWebView'
5
+project(':rnWebView').projectDir = new File(rootProject.projectDir, '../../android')

+ 72
- 0
example/examples/Alerts.tsx View File

@@ -0,0 +1,72 @@
1
+import React, {Component} from 'react';
2
+import {Text, View} from 'react-native';
3
+
4
+import WebView from 'react-native-webview';
5
+
6
+const HTML = `
7
+<!DOCTYPE html>\n
8
+<html>
9
+  <head>
10
+    <title>Alerts</title>
11
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
12
+    <meta name="viewport" content="width=320, user-scalable=no">
13
+    <style type="text/css">
14
+      body {
15
+        margin: 0;
16
+        padding: 0;
17
+        font: 62.5% arial, sans-serif;
18
+        background: #ccc;
19
+      }
20
+    </style>
21
+  </head>
22
+  <body>
23
+    <button onclick="showAlert()">Show alert</button>
24
+    <button onclick="showConfirm()">Show confirm</button>
25
+    <button onclick="showPrompt()">Show prompt</button>
26
+    <p id="demo"></p>    
27
+    <script>
28
+      function showAlert() {
29
+        alert("Hello! I am an alert box!");
30
+        document.getElementById("demo").innerHTML = "Alert dismissed!";
31
+      }
32
+      function showConfirm() {
33
+        var response;
34
+        if (confirm("Press a button!")) {
35
+          response = "You pressed OK on confirm!";
36
+        } else {
37
+          response = "You pressed Cancel on confirm!";
38
+        }
39
+        document.getElementById("demo").innerHTML = response;
40
+      }
41
+      function showPrompt() {
42
+        var message;
43
+        const name = prompt("Please enter your name", "Name");
44
+        if (name !== null) {
45
+          message = "Hello " + name;
46
+        } else {
47
+          message = "You pressed Cancel on prompt!";
48
+        }
49
+        document.getElementById("demo").innerHTML = message;
50
+      }
51
+    </script>
52
+  </body>
53
+</html>
54
+`;
55
+
56
+type Props = {};
57
+type State = {};
58
+
59
+export default class Alerts extends Component<Props, State> {
60
+  state = {};
61
+
62
+  render() {
63
+    return (
64
+      <View style={{ height: 120 }}>
65
+        <WebView
66
+          source={{html: HTML}}
67
+          automaticallyAdjustContentInsets={false}
68
+        />
69
+      </View>
70
+    );
71
+  }
72
+}

+ 54
- 0
example/examples/Background.tsx View File

@@ -0,0 +1,54 @@
1
+import React, {Component} from 'react';
2
+import {Text, View} from 'react-native';
3
+
4
+import WebView from 'react-native-webview';
5
+
6
+const HTML = `
7
+<!DOCTYPE html>\n
8
+<html>
9
+  <head>
10
+    <title>Hello World</title>
11
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
12
+    <meta name="viewport" content="width=320, user-scalable=no">
13
+    <style type="text/css">
14
+      body {
15
+        margin: 0;
16
+        padding: 0;
17
+        font: 62.5% arial, sans-serif;
18
+        background: transparent;
19
+      }
20
+    </style>
21
+  </head>
22
+  <body>
23
+    <p>HTML content in transparent body.</p>
24
+  </body>
25
+</html>
26
+`;
27
+
28
+type Props = {};
29
+type State = {
30
+  backgroundColor: string,
31
+};
32
+
33
+export default class Background extends Component<Props, State> {
34
+  state = {
35
+    backgroundColor: '#FF00FF00'
36
+  };
37
+
38
+  render() {
39
+    return (
40
+      <View>
41
+        <View style={{backgroundColor:'red'}}>
42
+          <View style={{ height: 120 }}>
43
+            <WebView
44
+              source={{html: HTML}}
45
+              automaticallyAdjustContentInsets={false}
46
+              style={{backgroundColor:'#00000000'}}
47
+            />
48
+          </View>
49
+        </View>
50
+        <Text>WebView is transparent contained in a View with a red backgroundColor</Text>
51
+      </View>
52
+    );
53
+  }
54
+}

+ 68
- 0
example/examples/Scrolling.tsx View File

@@ -0,0 +1,68 @@
1
+import React, {Component} from 'react';
2
+import {Button, Text, View} from 'react-native';
3
+
4
+import WebView from 'react-native-webview';
5
+
6
+const HTML = `
7
+<!DOCTYPE html>\n
8
+<html>
9
+  <head>
10
+    <title>Hello World</title>
11
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
12
+    <meta name="viewport" content="width=320, user-scalable=no">
13
+    <style type="text/css">
14
+      body {
15
+        margin: 0;
16
+        padding: 0;
17
+        font: 62.5% arial, sans-serif;
18
+        background: #ccc;
19
+      }
20
+    </style>
21
+  </head>
22
+  <body>
23
+    <p>Lorem ipsum dolor sit amet, virtute utroque voluptaria et duo, probo aeque partiendo pri at. Mea ut stet aliquip deterruisset. Inani erroribus principes ei mel, no dicit recteque delicatissimi usu. Ne has dolore nominavi, feugait hendrerit interesset vis ea, amet regione ne pri. Te cum amet etiam.</p>
24
+    <p>Ut adipiscing neglegentur mediocritatem sea, suas abhorreant ius cu, ne nostrud feugiat per. Nam paulo facete iudicabit an, an brute mundi suavitate has, ex utamur numquam duo. Sea platonem argumentum instructior in, quo no prima inani perfecto. Ex illum postea copiosae has, ei mea sonet ocurreret.</p>
25
+    <p>Has convenire erroribus cu, quo homero facilisis inciderint ea. Vix choro gloriatur definitionem an, te exerci debitis voluptaria pri, mea admodum antiopam neglegentur te. His ea iisque splendide, nam id malorum pertinacia. Iusto tempor in eos, vis debet erant an. An nostrum rationibus sit, et sed dicta delenit suscipiantur. Est dolore vituperatoribus in, ubique explicari est cu. Legere tractatos ut usu, probo atqui vituperata in usu, mazim nemore praesent pro no.</p>
26
+    <p>Ei pri facilisi accusamus. Ut partem quaestio sit, an usu audiam quaerendum, ei qui hinc soleat. Fabulas phaedrum erroribus ut est. Intellegebat delicatissimi vis cu. His ea vidit libris facilis. Usu ne scripta legimus intellegam. Hendrerit urbanitas accommodare mei in.</p>
27
+    <p>Brute appetere efficiendi has ne. Ei ornatus labores vis. Vel harum fierent no, ad erat partiendo vis, harum democritum duo at. Has no labitur vulputate. Has cu autem aperiam hendrerit, sed eu justo verear menandri.</p>
28
+  </body>
29
+</html>
30
+`;
31
+
32
+type Props = {};
33
+type State = {
34
+  scrollEnabled: boolean,
35
+  lastScrollEvent: string
36
+};
37
+
38
+export default class Scrolling extends Component<Props, State> {
39
+  state = {
40
+    scrollEnabled: true,
41
+    lastScrollEvent: ''
42
+  };
43
+
44
+  render() {
45
+    return (
46
+      <View>
47
+        <View style={{ height: 120 }}>
48
+          <WebView
49
+            source={{html: HTML}}
50
+            automaticallyAdjustContentInsets={false}
51
+            onScroll={this._onScroll}
52
+            scrollEnabled={this.state.scrollEnabled}
53
+          />
54
+        </View>
55
+        <Button
56
+          title={this.state.scrollEnabled ? 'Scroll enabled' : 'Scroll disabled'}
57
+          onPress={() => this.setState({scrollEnabled: !this.state.scrollEnabled})}
58
+        />
59
+        <Text>Last scroll event:</Text>
60
+        <Text>{this.state.lastScrollEvent}</Text>
61
+      </View>
62
+    );
63
+  }
64
+
65
+  _onScroll = event => {
66
+    this.setState({lastScrollEvent: JSON.stringify(event.nativeEvent)});
67
+  }
68
+}

+ 34
- 31
example/ios/Podfile View File

@@ -1,38 +1,41 @@
1 1
 platform :ios, '9.0'
2
-require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
2
+require_relative '../../node_modules/@react-native-community/cli-platform-ios/native_modules'
3
+
4
+project './example.xcodeproj'
3 5
 
4 6
 target 'example' do
5 7
   # Pods for example
6
-  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
7
-  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
8
-  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
9
-  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
10
-  pod 'React', :path => '../node_modules/react-native/'
11
-  pod 'React-Core', :path => '../node_modules/react-native/'
12
-  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
13
-  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
14
-  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
15
-  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
16
-  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
17
-  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
18
-  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
19
-  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
20
-  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
21
-  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
22
-  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
23
-  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
24
-
25
-  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
26
-  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
27
-  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
28
-  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
29
-  pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
30
-  pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
31
-  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
32
-
33
-  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
34
-  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
35
-  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
8
+  pod 'react-native-webview', :path => "../.."
9
+  pod 'FBLazyVector', :path => "../../node_modules/react-native/Libraries/FBLazyVector"
10
+  pod 'FBReactNativeSpec', :path => "../../node_modules/react-native/Libraries/FBReactNativeSpec"
11
+  pod 'RCTRequired', :path => "../../node_modules/react-native/Libraries/RCTRequired"
12
+  pod 'RCTTypeSafety', :path => "../../node_modules/react-native/Libraries/TypeSafety"
13
+  pod 'React', :path => '../../node_modules/react-native/'
14
+  pod 'React-Core', :path => '../../node_modules/react-native/'
15
+  pod 'React-CoreModules', :path => '../../node_modules/react-native/React/CoreModules'
16
+  pod 'React-Core/DevSupport', :path => '../../node_modules/react-native/'
17
+  pod 'React-RCTActionSheet', :path => '../../node_modules/react-native/Libraries/ActionSheetIOS'
18
+  pod 'React-RCTAnimation', :path => '../../node_modules/react-native/Libraries/NativeAnimation'
19
+  pod 'React-RCTBlob', :path => '../../node_modules/react-native/Libraries/Blob'
20
+  pod 'React-RCTImage', :path => '../../node_modules/react-native/Libraries/Image'
21
+  pod 'React-RCTLinking', :path => '../../node_modules/react-native/Libraries/LinkingIOS'
22
+  pod 'React-RCTNetwork', :path => '../../node_modules/react-native/Libraries/Network'
23
+  pod 'React-RCTSettings', :path => '../../node_modules/react-native/Libraries/Settings'
24
+  pod 'React-RCTText', :path => '../../node_modules/react-native/Libraries/Text'
25
+  pod 'React-RCTVibration', :path => '../../node_modules/react-native/Libraries/Vibration'
26
+  pod 'React-Core/RCTWebSocket', :path => '../../node_modules/react-native/'
27
+
28
+  pod 'React-cxxreact', :path => '../../node_modules/react-native/ReactCommon/cxxreact'
29
+  pod 'React-jsi', :path => '../../node_modules/react-native/ReactCommon/jsi'
30
+  pod 'React-jsiexecutor', :path => '../../node_modules/react-native/ReactCommon/jsiexecutor'
31
+  pod 'React-jsinspector', :path => '../../node_modules/react-native/ReactCommon/jsinspector'
32
+  pod 'ReactCommon/jscallinvoker', :path => "../../node_modules/react-native/ReactCommon"
33
+  pod 'ReactCommon/turbomodule/core', :path => "../../node_modules/react-native/ReactCommon"
34
+  pod 'Yoga', :path => '../../node_modules/react-native/ReactCommon/yoga'
35
+
36
+  pod 'DoubleConversion', :podspec => '../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
37
+  pod 'glog', :podspec => '../../node_modules/react-native/third-party-podspecs/glog.podspec'
38
+  pod 'Folly', :podspec => '../../node_modules/react-native/third-party-podspecs/Folly.podspec'
36 39
 
37 40
   target 'exampleTests' do
38 41
     inherit! :search_paths

+ 59
- 59
example/ios/Podfile.lock View File

@@ -182,7 +182,7 @@ PODS:
182 182
     - React-cxxreact (= 0.61.5)
183 183
     - React-jsi (= 0.61.5)
184 184
   - React-jsinspector (0.61.5)
185
-  - react-native-webview (8.0.2):
185
+  - react-native-webview (8.0.6):
186 186
     - React
187 187
   - React-RCTActionSheet (0.61.5):
188 188
     - React-Core/RCTActionSheetHeaders (= 0.61.5)
@@ -222,35 +222,35 @@ PODS:
222 222
   - Yoga (1.14.0)
223 223
 
224 224
 DEPENDENCIES:
225
-  - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
226
-  - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
227
-  - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
228
-  - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
229
-  - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
230
-  - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
231
-  - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
232
-  - React (from `../node_modules/react-native/`)
233
-  - React-Core (from `../node_modules/react-native/`)
234
-  - React-Core/DevSupport (from `../node_modules/react-native/`)
235
-  - React-Core/RCTWebSocket (from `../node_modules/react-native/`)
236
-  - React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
237
-  - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
238
-  - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
239
-  - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
240
-  - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
241
-  - react-native-webview (from `../node_modules/react-native-webview`)
242
-  - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
243
-  - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
244
-  - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
245
-  - React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
246
-  - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
247
-  - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
248
-  - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
249
-  - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
250
-  - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
251
-  - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`)
252
-  - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
253
-  - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
225
+  - DoubleConversion (from `../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
226
+  - FBLazyVector (from `../../node_modules/react-native/Libraries/FBLazyVector`)
227
+  - FBReactNativeSpec (from `../../node_modules/react-native/Libraries/FBReactNativeSpec`)
228
+  - Folly (from `../../node_modules/react-native/third-party-podspecs/Folly.podspec`)
229
+  - glog (from `../../node_modules/react-native/third-party-podspecs/glog.podspec`)
230
+  - RCTRequired (from `../../node_modules/react-native/Libraries/RCTRequired`)
231
+  - RCTTypeSafety (from `../../node_modules/react-native/Libraries/TypeSafety`)
232
+  - React (from `../../node_modules/react-native/`)
233
+  - React-Core (from `../../node_modules/react-native/`)
234
+  - React-Core/DevSupport (from `../../node_modules/react-native/`)
235
+  - React-Core/RCTWebSocket (from `../../node_modules/react-native/`)
236
+  - React-CoreModules (from `../../node_modules/react-native/React/CoreModules`)
237
+  - React-cxxreact (from `../../node_modules/react-native/ReactCommon/cxxreact`)
238
+  - React-jsi (from `../../node_modules/react-native/ReactCommon/jsi`)
239
+  - React-jsiexecutor (from `../../node_modules/react-native/ReactCommon/jsiexecutor`)
240
+  - React-jsinspector (from `../../node_modules/react-native/ReactCommon/jsinspector`)
241
+  - react-native-webview (from `../..`)
242
+  - React-RCTActionSheet (from `../../node_modules/react-native/Libraries/ActionSheetIOS`)
243
+  - React-RCTAnimation (from `../../node_modules/react-native/Libraries/NativeAnimation`)
244
+  - React-RCTBlob (from `../../node_modules/react-native/Libraries/Blob`)
245
+  - React-RCTImage (from `../../node_modules/react-native/Libraries/Image`)
246
+  - React-RCTLinking (from `../../node_modules/react-native/Libraries/LinkingIOS`)
247
+  - React-RCTNetwork (from `../../node_modules/react-native/Libraries/Network`)
248
+  - React-RCTSettings (from `../../node_modules/react-native/Libraries/Settings`)
249
+  - React-RCTText (from `../../node_modules/react-native/Libraries/Text`)
250
+  - React-RCTVibration (from `../../node_modules/react-native/Libraries/Vibration`)
251
+  - ReactCommon/jscallinvoker (from `../../node_modules/react-native/ReactCommon`)
252
+  - ReactCommon/turbomodule/core (from `../../node_modules/react-native/ReactCommon`)
253
+  - Yoga (from `../../node_modules/react-native/ReactCommon/yoga`)
254 254
 
255 255
 SPEC REPOS:
256 256
   trunk:
@@ -258,57 +258,57 @@ SPEC REPOS:
258 258
 
259 259
 EXTERNAL SOURCES:
260 260
   DoubleConversion:
261
-    :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
261
+    :podspec: "../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
262 262
   FBLazyVector:
263
-    :path: "../node_modules/react-native/Libraries/FBLazyVector"
263
+    :path: "../../node_modules/react-native/Libraries/FBLazyVector"
264 264
   FBReactNativeSpec:
265
-    :path: "../node_modules/react-native/Libraries/FBReactNativeSpec"
265
+    :path: "../../node_modules/react-native/Libraries/FBReactNativeSpec"
266 266
   Folly:
267
-    :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
267
+    :podspec: "../../node_modules/react-native/third-party-podspecs/Folly.podspec"
268 268
   glog:
269
-    :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
269
+    :podspec: "../../node_modules/react-native/third-party-podspecs/glog.podspec"
270 270
   RCTRequired:
271
-    :path: "../node_modules/react-native/Libraries/RCTRequired"
271
+    :path: "../../node_modules/react-native/Libraries/RCTRequired"
272 272
   RCTTypeSafety:
273
-    :path: "../node_modules/react-native/Libraries/TypeSafety"
273
+    :path: "../../node_modules/react-native/Libraries/TypeSafety"
274 274
   React:
275
-    :path: "../node_modules/react-native/"
275
+    :path: "../../node_modules/react-native/"
276 276
   React-Core:
277
-    :path: "../node_modules/react-native/"
277
+    :path: "../../node_modules/react-native/"
278 278
   React-CoreModules:
279
-    :path: "../node_modules/react-native/React/CoreModules"
279
+    :path: "../../node_modules/react-native/React/CoreModules"
280 280
   React-cxxreact:
281
-    :path: "../node_modules/react-native/ReactCommon/cxxreact"
281
+    :path: "../../node_modules/react-native/ReactCommon/cxxreact"
282 282
   React-jsi:
283
-    :path: "../node_modules/react-native/ReactCommon/jsi"
283
+    :path: "../../node_modules/react-native/ReactCommon/jsi"
284 284
   React-jsiexecutor:
285
-    :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
285
+    :path: "../../node_modules/react-native/ReactCommon/jsiexecutor"
286 286
   React-jsinspector:
287
-    :path: "../node_modules/react-native/ReactCommon/jsinspector"
287
+    :path: "../../node_modules/react-native/ReactCommon/jsinspector"
288 288
   react-native-webview:
289
-    :path: "../node_modules/react-native-webview"
289
+    :path: "../.."
290 290
   React-RCTActionSheet:
291
-    :path: "../node_modules/react-native/Libraries/ActionSheetIOS"
291
+    :path: "../../node_modules/react-native/Libraries/ActionSheetIOS"
292 292
   React-RCTAnimation:
293
-    :path: "../node_modules/react-native/Libraries/NativeAnimation"
293
+    :path: "../../node_modules/react-native/Libraries/NativeAnimation"
294 294
   React-RCTBlob:
295
-    :path: "../node_modules/react-native/Libraries/Blob"
295
+    :path: "../../node_modules/react-native/Libraries/Blob"
296 296
   React-RCTImage:
297
-    :path: "../node_modules/react-native/Libraries/Image"
297
+    :path: "../../node_modules/react-native/Libraries/Image"
298 298
   React-RCTLinking:
299
-    :path: "../node_modules/react-native/Libraries/LinkingIOS"
299
+    :path: "../../node_modules/react-native/Libraries/LinkingIOS"
300 300
   React-RCTNetwork:
301
-    :path: "../node_modules/react-native/Libraries/Network"
301
+    :path: "../../node_modules/react-native/Libraries/Network"
302 302
   React-RCTSettings:
303
-    :path: "../node_modules/react-native/Libraries/Settings"
303
+    :path: "../../node_modules/react-native/Libraries/Settings"
304 304
   React-RCTText:
305
-    :path: "../node_modules/react-native/Libraries/Text"
305
+    :path: "../../node_modules/react-native/Libraries/Text"
306 306
   React-RCTVibration:
307
-    :path: "../node_modules/react-native/Libraries/Vibration"
307
+    :path: "../../node_modules/react-native/Libraries/Vibration"
308 308
   ReactCommon:
309
-    :path: "../node_modules/react-native/ReactCommon"
309
+    :path: "../../node_modules/react-native/ReactCommon"
310 310
   Yoga:
311
-    :path: "../node_modules/react-native/ReactCommon/yoga"
311
+    :path: "../../node_modules/react-native/ReactCommon/yoga"
312 312
 
313 313
 SPEC CHECKSUMS:
314 314
   boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
@@ -326,7 +326,7 @@ SPEC CHECKSUMS:
326 326
   React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
327 327
   React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
328 328
   React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
329
-  react-native-webview: 99bdfd6c189772b0f15494f728430c23b18b93e4
329
+  react-native-webview: 222d83c9c489e09b5d3541519110a637490ad4fa
330 330
   React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
331 331
   React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
332 332
   React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
@@ -339,6 +339,6 @@ SPEC CHECKSUMS:
339 339
   ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd
340 340
   Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b
341 341
 
342
-PODFILE CHECKSUM: 79310af6b976c356911a8a833e9b99c3399fdda3
342
+PODFILE CHECKSUM: 2b0bdb79b803eefe541da6f9be6b06e99063bbfd
343 343
 
344
-COCOAPODS: 1.8.3
344
+COCOAPODS: 1.8.4

+ 4
- 4
example/ios/example.xcodeproj/project.pbxproj View File

@@ -371,7 +371,7 @@
371 371
 			);
372 372
 			runOnlyForDeploymentPostprocessing = 0;
373 373
 			shellPath = /bin/sh;
374
-			shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
374
+			shellScript = "export NODE_BINARY=node\n../../node_modules/react-native/scripts/react-native-xcode.sh\n";
375 375
 		};
376 376
 		2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {
377 377
 			isa = PBXShellScriptBuildPhase;
@@ -385,7 +385,7 @@
385 385
 			);
386 386
 			runOnlyForDeploymentPostprocessing = 0;
387 387
 			shellPath = /bin/sh;
388
-			shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
388
+			shellScript = "export NODE_BINARY=node\n../../node_modules/react-native/scripts/react-native-xcode.sh\n";
389 389
 		};
390 390
 		56202D3091BCA37A2C594528 /* [CP] Check Pods Manifest.lock */ = {
391 391
 			isa = PBXShellScriptBuildPhase;
@@ -491,7 +491,7 @@
491 491
 			);
492 492
 			runOnlyForDeploymentPostprocessing = 0;
493 493
 			shellPath = /bin/sh;
494
-			shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n  if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n    if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n      echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n      exit 2\n    fi\n  else\n    open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n  fi\nfi\n";
494
+			shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n  if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n    if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n      echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n      exit 2\n    fi\n  else\n    open \"$SRCROOT/../../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n  fi\nfi\n";
495 495
 			showEnvVarsInLog = 0;
496 496
 		};
497 497
 		FD10A7F122414F3F0027D42C /* Start Packager */ = {
@@ -510,7 +510,7 @@
510 510
 			);
511 511
 			runOnlyForDeploymentPostprocessing = 0;
512 512
 			shellPath = /bin/sh;
513
-			shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n  if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n    if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n      echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n      exit 2\n    fi\n  else\n    open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n  fi\nfi\n";
513
+			shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n  if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n    if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n      echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n      exit 2\n    fi\n  else\n    open \"$SRCROOT/../../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n  fi\nfi\n";
514 514
 			showEnvVarsInLog = 0;
515 515
 		};
516 516
 /* End PBXShellScriptBuildPhase section */

+ 1
- 1
example/ios/example/AppDelegate.m View File

@@ -33,7 +33,7 @@
33 33
 - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
34 34
 {
35 35
 #if DEBUG
36
-  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
36
+  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"example/index" fallbackResource:nil];
37 37
 #else
38 38
   return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
39 39
 #endif

+ 16
- 0
example/macos/example-macOS/AppDelegate.h View File

@@ -0,0 +1,16 @@
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
+
8
+#import <Cocoa/Cocoa.h>
9
+
10
+@class RCTBridge;
11
+
12
+@interface AppDelegate : NSObject <NSApplicationDelegate>
13
+
14
+@property (nonatomic, readonly) RCTBridge *bridge;
15
+
16
+@end

+ 39
- 0
example/macos/example-macOS/AppDelegate.m View File

@@ -0,0 +1,39 @@
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
+
8
+#import "AppDelegate.h"
9
+
10
+#import <React/RCTBridge.h>
11
+#import <React/RCTBundleURLProvider.h>
12
+
13
+@interface AppDelegate () <RCTBridgeDelegate>
14
+
15
+@end
16
+
17
+@implementation AppDelegate
18
+
19
+- (void)awakeFromNib {
20
+  [super awakeFromNib];
21
+
22
+  _bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:nil];
23
+}
24
+
25
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
26
+  // Insert code here to initialize your application
27
+}
28
+
29
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
30
+  // Insert code here to tear down your application
31
+}
32
+
33
+#pragma mark - RCTBridgeDelegate Methods
34
+
35
+- (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge {
36
+  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"example/index" fallbackResource:@"main"]; // .jsbundle;
37
+}
38
+
39
+@end

+ 45
- 0
example/macos/example-macOS/Info.plist View File

@@ -0,0 +1,45 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>CFBundleDevelopmentRegion</key>
6
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
7
+	<key>CFBundleExecutable</key>
8
+	<string>$(EXECUTABLE_NAME)</string>
9
+	<key>CFBundleIconFile</key>
10
+	<string></string>
11
+	<key>CFBundleIdentifier</key>
12
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+	<key>CFBundleInfoDictionaryVersion</key>
14
+	<string>6.0</string>
15
+	<key>CFBundleName</key>
16
+	<string>$(PRODUCT_NAME)</string>
17
+	<key>CFBundlePackageType</key>
18
+	<string>APPL</string>
19
+	<key>CFBundleShortVersionString</key>
20
+	<string>1.0</string>
21
+	<key>CFBundleVersion</key>
22
+	<string>1</string>
23
+	<key>LSMinimumSystemVersion</key>
24
+	<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
25
+	<key>NSAppTransportSecurity</key>
26
+	<dict>
27
+		<key>NSAllowsArbitraryLoads</key>
28
+		<true/>
29
+		<key>NSExceptionDomains</key>
30
+		<dict>
31
+			<key>localhost</key>
32
+			<dict>
33
+				<key>NSExceptionAllowsInsecureHTTPLoads</key>
34
+				<true/>
35
+			</dict>
36
+		</dict>
37
+	</dict>
38
+	<key>NSHumanReadableCopyright</key>
39
+	<string>Copyright © 2017 Facebook. All rights reserved.</string>
40
+	<key>NSMainStoryboardFile</key>
41
+	<string>Main</string>
42
+	<key>NSPrincipalClass</key>
43
+	<string>NSApplication</string>
44
+</dict>
45
+</plist>

+ 713
- 0
example/macos/example-macOS/Main.storyboard View File

@@ -0,0 +1,713 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
3
+    <dependencies>
4
+        <deployment identifier="macosx"/>
5
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15505"/>
6
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7
+    </dependencies>
8
+    <scenes>
9
+        <!--Application-->
10
+        <scene sceneID="JPo-4y-FX3">
11
+            <objects>
12
+                <application id="hnw-xV-0zn" sceneMemberID="viewController">
13
+                    <menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
14
+                        <items>
15
+                            <menuItem title="rncTesterApp-macOS" id="1Xt-HY-uBw">
16
+                                <modifierMask key="keyEquivalentModifierMask"/>
17
+                                <menu key="submenu" title="rncTesterApp-macOS" systemMenu="apple" id="uQy-DD-JDr">
18
+                                    <items>
19
+                                        <menuItem title="About rncTesterApp-macOS" id="5kV-Vb-QxS">
20
+                                            <modifierMask key="keyEquivalentModifierMask"/>
21
+                                            <connections>
22
+                                                <action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
23
+                                            </connections>
24
+                                        </menuItem>
25
+                                        <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
26
+                                        <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
27
+                                        <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
28
+                                        <menuItem title="Services" id="NMo-om-nkz">
29
+                                            <modifierMask key="keyEquivalentModifierMask"/>
30
+                                            <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
31
+                                        </menuItem>
32
+                                        <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
33
+                                        <menuItem title="Hide rncTesterApp-macOS" keyEquivalent="h" id="Olw-nP-bQN">
34
+                                            <connections>
35
+                                                <action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
36
+                                            </connections>
37
+                                        </menuItem>
38
+                                        <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
39
+                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
40
+                                            <connections>
41
+                                                <action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
42
+                                            </connections>
43
+                                        </menuItem>
44
+                                        <menuItem title="Show All" id="Kd2-mp-pUS">
45
+                                            <modifierMask key="keyEquivalentModifierMask"/>
46
+                                            <connections>
47
+                                                <action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
48
+                                            </connections>
49
+                                        </menuItem>
50
+                                        <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
51
+                                        <menuItem title="Quit rncTesterApp-macOS" keyEquivalent="q" id="4sb-4s-VLi">
52
+                                            <connections>
53
+                                                <action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
54
+                                            </connections>
55
+                                        </menuItem>
56
+                                    </items>
57
+                                </menu>
58
+                            </menuItem>
59
+                            <menuItem title="File" id="dMs-cI-mzQ">
60
+                                <modifierMask key="keyEquivalentModifierMask"/>
61
+                                <menu key="submenu" title="File" id="bib-Uj-vzu">
62
+                                    <items>
63
+                                        <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
64
+                                            <connections>
65
+                                                <action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
66
+                                            </connections>
67
+                                        </menuItem>
68
+                                        <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
69
+                                            <connections>
70
+                                                <action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
71
+                                            </connections>
72
+                                        </menuItem>
73
+                                        <menuItem title="Open Recent" id="tXI-mr-wws">
74
+                                            <modifierMask key="keyEquivalentModifierMask"/>
75
+                                            <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
76
+                                                <items>
77
+                                                    <menuItem title="Clear Menu" id="vNY-rz-j42">
78
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
79
+                                                        <connections>
80
+                                                            <action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
81
+                                                        </connections>
82
+                                                    </menuItem>
83
+                                                </items>
84
+                                            </menu>
85
+                                        </menuItem>
86
+                                        <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
87
+                                        <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
88
+                                            <connections>
89
+                                                <action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
90
+                                            </connections>
91
+                                        </menuItem>
92
+                                        <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
93
+                                            <connections>
94
+                                                <action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
95
+                                            </connections>
96
+                                        </menuItem>
97
+                                        <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
98
+                                            <connections>
99
+                                                <action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
100
+                                            </connections>
101
+                                        </menuItem>
102
+                                        <menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
103
+                                            <connections>
104
+                                                <action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
105
+                                            </connections>
106
+                                        </menuItem>
107
+                                        <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
108
+                                        <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
109
+                                            <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
110
+                                            <connections>
111
+                                                <action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
112
+                                            </connections>
113
+                                        </menuItem>
114
+                                        <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
115
+                                            <connections>
116
+                                                <action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
117
+                                            </connections>
118
+                                        </menuItem>
119
+                                    </items>
120
+                                </menu>
121
+                            </menuItem>
122
+                            <menuItem title="Edit" id="5QF-Oa-p0T">
123
+                                <modifierMask key="keyEquivalentModifierMask"/>
124
+                                <menu key="submenu" title="Edit" id="W48-6f-4Dl">
125
+                                    <items>
126
+                                        <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
127
+                                            <connections>
128
+                                                <action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
129
+                                            </connections>
130
+                                        </menuItem>
131
+                                        <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
132
+                                            <connections>
133
+                                                <action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
134
+                                            </connections>
135
+                                        </menuItem>
136
+                                        <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
137
+                                        <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
138
+                                            <connections>
139
+                                                <action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
140
+                                            </connections>
141
+                                        </menuItem>
142
+                                        <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
143
+                                            <connections>
144
+                                                <action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
145
+                                            </connections>
146
+                                        </menuItem>
147
+                                        <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
148
+                                            <connections>
149
+                                                <action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
150
+                                            </connections>
151
+                                        </menuItem>
152
+                                        <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
153
+                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
154
+                                            <connections>
155
+                                                <action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
156
+                                            </connections>
157
+                                        </menuItem>
158
+                                        <menuItem title="Delete" id="pa3-QI-u2k">
159
+                                            <modifierMask key="keyEquivalentModifierMask"/>
160
+                                            <connections>
161
+                                                <action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
162
+                                            </connections>
163
+                                        </menuItem>
164
+                                        <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
165
+                                            <connections>
166
+                                                <action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
167
+                                            </connections>
168
+                                        </menuItem>
169
+                                        <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
170
+                                        <menuItem title="Find" id="4EN-yA-p0u">
171
+                                            <modifierMask key="keyEquivalentModifierMask"/>
172
+                                            <menu key="submenu" title="Find" id="1b7-l0-nxx">
173
+                                                <items>
174
+                                                    <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
175
+                                                        <connections>
176
+                                                            <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
177
+                                                        </connections>
178
+                                                    </menuItem>
179
+                                                    <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
180
+                                                        <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
181
+                                                        <connections>
182
+                                                            <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
183
+                                                        </connections>
184
+                                                    </menuItem>
185
+                                                    <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
186
+                                                        <connections>
187
+                                                            <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
188
+                                                        </connections>
189
+                                                    </menuItem>
190
+                                                    <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
191
+                                                        <connections>
192
+                                                            <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
193
+                                                        </connections>
194
+                                                    </menuItem>
195
+                                                    <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
196
+                                                        <connections>
197
+                                                            <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
198
+                                                        </connections>
199
+                                                    </menuItem>
200
+                                                    <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
201
+                                                        <connections>
202
+                                                            <action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
203
+                                                        </connections>
204
+                                                    </menuItem>
205
+                                                </items>
206
+                                            </menu>
207
+                                        </menuItem>
208
+                                        <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
209
+                                            <modifierMask key="keyEquivalentModifierMask"/>
210
+                                            <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
211
+                                                <items>
212
+                                                    <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
213
+                                                        <connections>
214
+                                                            <action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
215
+                                                        </connections>
216
+                                                    </menuItem>
217
+                                                    <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
218
+                                                        <connections>
219
+                                                            <action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
220
+                                                        </connections>
221
+                                                    </menuItem>
222
+                                                    <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
223
+                                                    <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
224
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
225
+                                                        <connections>
226
+                                                            <action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
227
+                                                        </connections>
228
+                                                    </menuItem>
229
+                                                    <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
230
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
231
+                                                        <connections>
232
+                                                            <action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
233
+                                                        </connections>
234
+                                                    </menuItem>
235
+                                                    <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
236
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
237
+                                                        <connections>
238
+                                                            <action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
239
+                                                        </connections>
240
+                                                    </menuItem>
241
+                                                </items>
242
+                                            </menu>
243
+                                        </menuItem>
244
+                                        <menuItem title="Substitutions" id="9ic-FL-obx">
245
+                                            <modifierMask key="keyEquivalentModifierMask"/>
246
+                                            <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
247
+                                                <items>
248
+                                                    <menuItem title="Show Substitutions" id="z6F-FW-3nz">
249
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
250
+                                                        <connections>
251
+                                                            <action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
252
+                                                        </connections>
253
+                                                    </menuItem>
254
+                                                    <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
255
+                                                    <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
256
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
257
+                                                        <connections>
258
+                                                            <action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
259
+                                                        </connections>
260
+                                                    </menuItem>
261
+                                                    <menuItem title="Smart Quotes" id="hQb-2v-fYv">
262
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
263
+                                                        <connections>
264
+                                                            <action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
265
+                                                        </connections>
266
+                                                    </menuItem>
267
+                                                    <menuItem title="Smart Dashes" id="rgM-f4-ycn">
268
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
269
+                                                        <connections>
270
+                                                            <action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
271
+                                                        </connections>
272
+                                                    </menuItem>
273
+                                                    <menuItem title="Smart Links" id="cwL-P1-jid">
274
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
275
+                                                        <connections>
276
+                                                            <action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
277
+                                                        </connections>
278
+                                                    </menuItem>
279
+                                                    <menuItem title="Data Detectors" id="tRr-pd-1PS">
280
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
281
+                                                        <connections>
282
+                                                            <action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
283
+                                                        </connections>
284
+                                                    </menuItem>
285
+                                                    <menuItem title="Text Replacement" id="HFQ-gK-NFA">
286
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
287
+                                                        <connections>
288
+                                                            <action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
289
+                                                        </connections>
290
+                                                    </menuItem>
291
+                                                </items>
292
+                                            </menu>
293
+                                        </menuItem>
294
+                                        <menuItem title="Transformations" id="2oI-Rn-ZJC">
295
+                                            <modifierMask key="keyEquivalentModifierMask"/>
296
+                                            <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
297
+                                                <items>
298
+                                                    <menuItem title="Make Upper Case" id="vmV-6d-7jI">
299
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
300
+                                                        <connections>
301
+                                                            <action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
302
+                                                        </connections>
303
+                                                    </menuItem>
304
+                                                    <menuItem title="Make Lower Case" id="d9M-CD-aMd">
305
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
306
+                                                        <connections>
307
+                                                            <action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
308
+                                                        </connections>
309
+                                                    </menuItem>
310
+                                                    <menuItem title="Capitalize" id="UEZ-Bs-lqG">
311
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
312
+                                                        <connections>
313
+                                                            <action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
314
+                                                        </connections>
315
+                                                    </menuItem>
316
+                                                </items>
317
+                                            </menu>
318
+                                        </menuItem>
319
+                                        <menuItem title="Speech" id="xrE-MZ-jX0">
320
+                                            <modifierMask key="keyEquivalentModifierMask"/>
321
+                                            <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
322
+                                                <items>
323
+                                                    <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
324
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
325
+                                                        <connections>
326
+                                                            <action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
327
+                                                        </connections>
328
+                                                    </menuItem>
329
+                                                    <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
330
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
331
+                                                        <connections>
332
+                                                            <action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
333
+                                                        </connections>
334
+                                                    </menuItem>
335
+                                                </items>
336
+                                            </menu>
337
+                                        </menuItem>
338
+                                    </items>
339
+                                </menu>
340
+                            </menuItem>
341
+                            <menuItem title="Format" id="jxT-CU-nIS">
342
+                                <modifierMask key="keyEquivalentModifierMask"/>
343
+                                <menu key="submenu" title="Format" id="GEO-Iw-cKr">
344
+                                    <items>
345
+                                        <menuItem title="Font" id="Gi5-1S-RQB">
346
+                                            <modifierMask key="keyEquivalentModifierMask"/>
347
+                                            <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
348
+                                                <items>
349
+                                                    <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
350
+                                                        <connections>
351
+                                                            <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
352
+                                                        </connections>
353
+                                                    </menuItem>
354
+                                                    <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
355
+                                                        <connections>
356
+                                                            <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
357
+                                                        </connections>
358
+                                                    </menuItem>
359
+                                                    <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
360
+                                                        <connections>
361
+                                                            <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
362
+                                                        </connections>
363
+                                                    </menuItem>
364
+                                                    <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
365
+                                                        <connections>
366
+                                                            <action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
367
+                                                        </connections>
368
+                                                    </menuItem>
369
+                                                    <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
370
+                                                    <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
371
+                                                        <connections>
372
+                                                            <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
373
+                                                        </connections>
374
+                                                    </menuItem>
375
+                                                    <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
376
+                                                        <connections>
377
+                                                            <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
378
+                                                        </connections>
379
+                                                    </menuItem>
380
+                                                    <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
381
+                                                    <menuItem title="Kern" id="jBQ-r6-VK2">
382
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
383
+                                                        <menu key="submenu" title="Kern" id="tlD-Oa-oAM">
384
+                                                            <items>
385
+                                                                <menuItem title="Use Default" id="GUa-eO-cwY">
386
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
387
+                                                                    <connections>
388
+                                                                        <action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
389
+                                                                    </connections>
390
+                                                                </menuItem>
391
+                                                                <menuItem title="Use None" id="cDB-IK-hbR">
392
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
393
+                                                                    <connections>
394
+                                                                        <action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
395
+                                                                    </connections>
396
+                                                                </menuItem>
397
+                                                                <menuItem title="Tighten" id="46P-cB-AYj">
398
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
399
+                                                                    <connections>
400
+                                                                        <action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
401
+                                                                    </connections>
402
+                                                                </menuItem>
403
+                                                                <menuItem title="Loosen" id="ogc-rX-tC1">
404
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
405
+                                                                    <connections>
406
+                                                                        <action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
407
+                                                                    </connections>
408
+                                                                </menuItem>
409
+                                                            </items>
410
+                                                        </menu>
411
+                                                    </menuItem>
412
+                                                    <menuItem title="Ligatures" id="o6e-r0-MWq">
413
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
414
+                                                        <menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
415
+                                                            <items>
416
+                                                                <menuItem title="Use Default" id="agt-UL-0e3">
417
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
418
+                                                                    <connections>
419
+                                                                        <action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
420
+                                                                    </connections>
421
+                                                                </menuItem>
422
+                                                                <menuItem title="Use None" id="J7y-lM-qPV">
423
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
424
+                                                                    <connections>
425
+                                                                        <action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
426
+                                                                    </connections>
427
+                                                                </menuItem>
428
+                                                                <menuItem title="Use All" id="xQD-1f-W4t">
429
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
430
+                                                                    <connections>
431
+                                                                        <action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
432
+                                                                    </connections>
433
+                                                                </menuItem>
434
+                                                            </items>
435
+                                                        </menu>
436
+                                                    </menuItem>
437
+                                                    <menuItem title="Baseline" id="OaQ-X3-Vso">
438
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
439
+                                                        <menu key="submenu" title="Baseline" id="ijk-EB-dga">
440
+                                                            <items>
441
+                                                                <menuItem title="Use Default" id="3Om-Ey-2VK">
442
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
443
+                                                                    <connections>
444
+                                                                        <action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
445
+                                                                    </connections>
446
+                                                                </menuItem>
447
+                                                                <menuItem title="Superscript" id="Rqc-34-cIF">
448
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
449
+                                                                    <connections>
450
+                                                                        <action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
451
+                                                                    </connections>
452
+                                                                </menuItem>
453
+                                                                <menuItem title="Subscript" id="I0S-gh-46l">
454
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
455
+                                                                    <connections>
456
+                                                                        <action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
457
+                                                                    </connections>
458
+                                                                </menuItem>
459
+                                                                <menuItem title="Raise" id="2h7-ER-AoG">
460
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
461
+                                                                    <connections>
462
+                                                                        <action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
463
+                                                                    </connections>
464
+                                                                </menuItem>
465
+                                                                <menuItem title="Lower" id="1tx-W0-xDw">
466
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
467
+                                                                    <connections>
468
+                                                                        <action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
469
+                                                                    </connections>
470
+                                                                </menuItem>
471
+                                                            </items>
472
+                                                        </menu>
473
+                                                    </menuItem>
474
+                                                    <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
475
+                                                    <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
476
+                                                        <connections>
477
+                                                            <action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
478
+                                                        </connections>
479
+                                                    </menuItem>
480
+                                                    <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
481
+                                                    <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
482
+                                                        <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
483
+                                                        <connections>
484
+                                                            <action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
485
+                                                        </connections>
486
+                                                    </menuItem>
487
+                                                    <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
488
+                                                        <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
489
+                                                        <connections>
490
+                                                            <action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
491
+                                                        </connections>
492
+                                                    </menuItem>
493
+                                                </items>
494
+                                            </menu>
495
+                                        </menuItem>
496
+                                        <menuItem title="Text" id="Fal-I4-PZk">
497
+                                            <modifierMask key="keyEquivalentModifierMask"/>
498
+                                            <menu key="submenu" title="Text" id="d9c-me-L2H">
499
+                                                <items>
500
+                                                    <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
501
+                                                        <connections>
502
+                                                            <action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
503
+                                                        </connections>
504
+                                                    </menuItem>
505
+                                                    <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
506
+                                                        <connections>
507
+                                                            <action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
508
+                                                        </connections>
509
+                                                    </menuItem>
510
+                                                    <menuItem title="Justify" id="J5U-5w-g23">
511
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
512
+                                                        <connections>
513
+                                                            <action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
514
+                                                        </connections>
515
+                                                    </menuItem>
516
+                                                    <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
517
+                                                        <connections>
518
+                                                            <action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
519
+                                                        </connections>
520
+                                                    </menuItem>
521
+                                                    <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
522
+                                                    <menuItem title="Writing Direction" id="H1b-Si-o9J">
523
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
524
+                                                        <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
525
+                                                            <items>
526
+                                                                <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
527
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
528
+                                                                </menuItem>
529
+                                                                <menuItem title="  Default" id="YGs-j5-SAR">
530
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
531
+                                                                    <connections>
532
+                                                                        <action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
533
+                                                                    </connections>
534
+                                                                </menuItem>
535
+                                                                <menuItem title="  Left to Right" id="Lbh-J2-qVU">
536
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
537
+                                                                    <connections>
538
+                                                                        <action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
539
+                                                                    </connections>
540
+                                                                </menuItem>
541
+                                                                <menuItem title="  Right to Left" id="jFq-tB-4Kx">
542
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
543
+                                                                    <connections>
544
+                                                                        <action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
545
+                                                                    </connections>
546
+                                                                </menuItem>
547
+                                                                <menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
548
+                                                                <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
549
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
550
+                                                                </menuItem>
551
+                                                                <menuItem title="  Default" id="Nop-cj-93Q">
552
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
553
+                                                                    <connections>
554
+                                                                        <action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
555
+                                                                    </connections>
556
+                                                                </menuItem>
557
+                                                                <menuItem title="  Left to Right" id="BgM-ve-c93">
558
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
559
+                                                                    <connections>
560
+                                                                        <action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
561
+                                                                    </connections>
562
+                                                                </menuItem>
563
+                                                                <menuItem title="  Right to Left" id="RB4-Sm-HuC">
564
+                                                                    <modifierMask key="keyEquivalentModifierMask"/>
565
+                                                                    <connections>
566
+                                                                        <action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
567
+                                                                    </connections>
568
+                                                                </menuItem>
569
+                                                            </items>
570
+                                                        </menu>
571
+                                                    </menuItem>
572
+                                                    <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
573
+                                                    <menuItem title="Show Ruler" id="vLm-3I-IUL">
574
+                                                        <modifierMask key="keyEquivalentModifierMask"/>
575
+                                                        <connections>
576
+                                                            <action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
577
+                                                        </connections>
578
+                                                    </menuItem>
579
+                                                    <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
580
+                                                        <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
581
+                                                        <connections>
582
+                                                            <action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
583
+                                                        </connections>
584
+                                                    </menuItem>
585
+                                                    <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
586
+                                                        <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
587
+                                                        <connections>
588
+                                                            <action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
589
+                                                        </connections>
590
+                                                    </menuItem>
591
+                                                </items>
592
+                                            </menu>
593
+                                        </menuItem>
594
+                                    </items>
595
+                                </menu>
596
+                            </menuItem>
597
+                            <menuItem title="View" id="H8h-7b-M4v">
598
+                                <modifierMask key="keyEquivalentModifierMask"/>
599
+                                <menu key="submenu" title="View" id="HyV-fh-RgO">
600
+                                    <items>
601
+                                        <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
602
+                                            <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
603
+                                            <connections>
604
+                                                <action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
605
+                                            </connections>
606
+                                        </menuItem>
607
+                                        <menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
608
+                                            <modifierMask key="keyEquivalentModifierMask"/>
609
+                                            <connections>
610
+                                                <action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
611
+                                            </connections>
612
+                                        </menuItem>
613
+                                        <menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
614
+                                        <menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
615
+                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
616
+                                            <connections>
617
+                                                <action selector="toggleSidebar:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
618
+                                            </connections>
619
+                                        </menuItem>
620
+                                        <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
621
+                                            <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
622
+                                            <connections>
623
+                                                <action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
624
+                                            </connections>
625
+                                        </menuItem>
626
+                                    </items>
627
+                                </menu>
628
+                            </menuItem>
629
+                            <menuItem title="Window" id="aUF-d1-5bR">
630
+                                <modifierMask key="keyEquivalentModifierMask"/>
631
+                                <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
632
+                                    <items>
633
+                                        <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
634
+                                            <connections>
635
+                                                <action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
636
+                                            </connections>
637
+                                        </menuItem>
638
+                                        <menuItem title="Zoom" id="R4o-n2-Eq4">
639
+                                            <modifierMask key="keyEquivalentModifierMask"/>
640
+                                            <connections>
641
+                                                <action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
642
+                                            </connections>
643
+                                        </menuItem>
644
+                                        <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
645
+                                        <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
646
+                                            <modifierMask key="keyEquivalentModifierMask"/>
647
+                                            <connections>
648
+                                                <action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
649
+                                            </connections>
650
+                                        </menuItem>
651
+                                    </items>
652
+                                </menu>
653
+                            </menuItem>
654
+                            <menuItem title="Help" id="wpr-3q-Mcd">
655
+                                <modifierMask key="keyEquivalentModifierMask"/>
656
+                                <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
657
+                                    <items>
658
+                                        <menuItem title="rncTesterApp-macOS Help" keyEquivalent="?" id="FKE-Sm-Kum">
659
+                                            <connections>
660
+                                                <action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
661
+                                            </connections>
662
+                                        </menuItem>
663
+                                    </items>
664
+                                </menu>
665
+                            </menuItem>
666
+                        </items>
667
+                    </menu>
668
+                    <connections>
669
+                        <outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
670
+                    </connections>
671
+                </application>
672
+                <customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
673
+                <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
674
+                <customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
675
+            </objects>
676
+            <point key="canvasLocation" x="75" y="0.0"/>
677
+        </scene>
678
+        <!--Window Controller-->
679
+        <scene sceneID="R2V-B0-nI4">
680
+            <objects>
681
+                <windowController id="B8D-0N-5wS" sceneMemberID="viewController">
682
+                    <window key="window" title="example macOS" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
683
+                        <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
684
+                        <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
685
+                        <rect key="contentRect" x="196" y="240" width="480" height="270"/>
686
+                        <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
687
+                        <connections>
688
+                            <outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
689
+                        </connections>
690
+                    </window>
691
+                    <connections>
692
+                        <segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
693
+                    </connections>
694
+                </windowController>
695
+                <customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
696
+            </objects>
697
+            <point key="canvasLocation" x="75" y="250"/>
698
+        </scene>
699
+        <!--View Controller-->
700
+        <scene sceneID="hIz-AP-VOD">
701
+            <objects>
702
+                <viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController">
703
+                    <view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
704
+                        <rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
705
+                        <autoresizingMask key="autoresizingMask"/>
706
+                    </view>
707
+                </viewController>
708
+                <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
709
+            </objects>
710
+            <point key="canvasLocation" x="75" y="655"/>
711
+        </scene>
712
+    </scenes>
713
+</document>

+ 12
- 0
example/macos/example-macOS/ViewController.h View File

@@ -0,0 +1,12 @@
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
+
8
+#import <Cocoa/Cocoa.h>
9
+
10
+@interface ViewController : NSViewController
11
+
12
+@end

+ 29
- 0
example/macos/example-macOS/ViewController.m View File

@@ -0,0 +1,29 @@
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
+
8
+#import "ViewController.h"
9
+#import "AppDelegate.h"
10
+
11
+#import <React/RCTRootView.h>
12
+
13
+@implementation ViewController
14
+
15
+- (void)viewDidLoad {
16
+  [super viewDidLoad];
17
+
18
+  RCTBridge *bridge = [((AppDelegate *)[NSApp delegate])bridge];
19
+  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"example" initialProperties:nil];
20
+
21
+  NSView *view = [self view];
22
+
23
+  [view addSubview:rootView];
24
+  [rootView setBackgroundColor:[NSColor windowBackgroundColor]];
25
+  [rootView setFrame:[view bounds]];
26
+  [rootView setAutoresizingMask:(NSViewMinXMargin | NSViewMinXMargin | NSViewMinYMargin | NSViewMaxYMargin | NSViewWidthSizable | NSViewHeightSizable)];
27
+}
28
+
29
+@end

+ 12
- 0
example/macos/example-macOS/main.m View File

@@ -0,0 +1,12 @@
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
+
8
+#import <Cocoa/Cocoa.h>
9
+
10
+int main(int argc, const char *argv[]) {
11
+  return NSApplicationMain(argc, argv);
12
+}

+ 1569
- 0
example/macos/example.xcodeproj/project.pbxproj
File diff suppressed because it is too large
View File


+ 10
- 0
example/macos/example.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings View File

@@ -0,0 +1,10 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>BuildSystemType</key>
6
+	<string>Original</string>
7
+	<key>PreviewsEnabled</key>
8
+	<false/>
9
+</dict>
10
+</plist>

+ 92
- 0
example/macos/example.xcodeproj/xcshareddata/xcschemes/example-macOS.xcscheme View File

@@ -0,0 +1,92 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+   LastUpgradeVersion = "1120"
4
+   version = "1.3">
5
+   <BuildAction
6
+      parallelizeBuildables = "NO"
7
+      buildImplicitDependencies = "YES">
8
+      <BuildActionEntries>
9
+         <BuildActionEntry
10
+            buildForTesting = "YES"
11
+            buildForRunning = "YES"
12
+            buildForProfiling = "YES"
13
+            buildForArchiving = "YES"
14
+            buildForAnalyzing = "YES">
15
+            <BuildableReference
16
+               BuildableIdentifier = "primary"
17
+               BlueprintIdentifier = "6B857DA21EC51FC600A9D063"
18
+               BuildableName = "libReact.a"
19
+               BlueprintName = "React-macOS"
20
+               ReferencedContainer = "container:../../node_modules/react-native-macos/React/React.xcodeproj">
21
+            </BuildableReference>
22
+         </BuildActionEntry>
23
+         <BuildActionEntry
24
+            buildForTesting = "YES"
25
+            buildForRunning = "YES"
26
+            buildForProfiling = "YES"
27
+            buildForArchiving = "YES"
28
+            buildForAnalyzing = "YES">
29
+            <BuildableReference
30
+               BuildableIdentifier = "primary"
31
+               BlueprintIdentifier = "38C1415723BBE33000902604"
32
+               BuildableName = "example-macOS.app"
33
+               BlueprintName = "example-macOS"
34
+               ReferencedContainer = "container:example.xcodeproj">
35
+            </BuildableReference>
36
+         </BuildActionEntry>
37
+      </BuildActionEntries>
38
+   </BuildAction>
39
+   <TestAction
40
+      buildConfiguration = "Debug"
41
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
42
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
43
+      shouldUseLaunchSchemeArgsEnv = "YES">
44
+      <Testables>
45
+      </Testables>
46
+   </TestAction>
47
+   <LaunchAction
48
+      buildConfiguration = "Debug"
49
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
50
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
51
+      launchStyle = "0"
52
+      useCustomWorkingDirectory = "NO"
53
+      ignoresPersistentStateOnLaunch = "NO"
54
+      debugDocumentVersioning = "YES"
55
+      debugServiceExtension = "internal"
56
+      allowLocationSimulation = "YES">
57
+      <BuildableProductRunnable
58
+         runnableDebuggingMode = "0">
59
+         <BuildableReference
60
+            BuildableIdentifier = "primary"
61
+            BlueprintIdentifier = "38C1415723BBE33000902604"
62
+            BuildableName = "example-macOS.app"
63
+            BlueprintName = "example-macOS"
64
+            ReferencedContainer = "container:example.xcodeproj">
65
+         </BuildableReference>
66
+      </BuildableProductRunnable>
67
+   </LaunchAction>
68
+   <ProfileAction
69
+      buildConfiguration = "Release"
70
+      shouldUseLaunchSchemeArgsEnv = "YES"
71
+      savedToolIdentifier = ""
72
+      useCustomWorkingDirectory = "NO"
73
+      debugDocumentVersioning = "YES">
74
+      <BuildableProductRunnable
75
+         runnableDebuggingMode = "0">
76
+         <BuildableReference
77
+            BuildableIdentifier = "primary"
78
+            BlueprintIdentifier = "38C1415723BBE33000902604"
79
+            BuildableName = "example-macOS.app"
80
+            BlueprintName = "example-macOS"
81
+            ReferencedContainer = "container:example.xcodeproj">
82
+         </BuildableReference>
83
+      </BuildableProductRunnable>
84
+   </ProfileAction>
85
+   <AnalyzeAction
86
+      buildConfiguration = "Debug">
87
+   </AnalyzeAction>
88
+   <ArchiveAction
89
+      buildConfiguration = "Release"
90
+      revealArchiveInOrganizer = "YES">
91
+   </ArchiveAction>
92
+</Scheme>

+ 92
- 0
example/macos/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme View File

@@ -0,0 +1,92 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+   LastUpgradeVersion = "1120"
4
+   version = "1.3">
5
+   <BuildAction
6
+      parallelizeBuildables = "NO"
7
+      buildImplicitDependencies = "YES">
8
+      <BuildActionEntries>
9
+         <BuildActionEntry
10
+            buildForTesting = "YES"
11
+            buildForRunning = "YES"
12
+            buildForProfiling = "YES"
13
+            buildForArchiving = "YES"
14
+            buildForAnalyzing = "YES">
15
+            <BuildableReference
16
+               BuildableIdentifier = "primary"
17
+               BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
18
+               BuildableName = "libReact.a"
19
+               BlueprintName = "React"
20
+               ReferencedContainer = "container:../../node_modules/react-native-macos/React/React.xcodeproj">
21
+            </BuildableReference>
22
+         </BuildActionEntry>
23
+         <BuildActionEntry
24
+            buildForTesting = "YES"
25
+            buildForRunning = "YES"
26
+            buildForProfiling = "YES"
27
+            buildForArchiving = "YES"
28
+            buildForAnalyzing = "YES">
29
+            <BuildableReference
30
+               BuildableIdentifier = "primary"
31
+               BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
32
+               BuildableName = "example.app"
33
+               BlueprintName = "example"
34
+               ReferencedContainer = "container:example.xcodeproj">
35
+            </BuildableReference>
36
+         </BuildActionEntry>
37
+      </BuildActionEntries>
38
+   </BuildAction>
39
+   <TestAction
40
+      buildConfiguration = "Debug"
41
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
42
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
43
+      shouldUseLaunchSchemeArgsEnv = "YES">
44
+      <Testables>
45
+      </Testables>
46
+   </TestAction>
47
+   <LaunchAction
48
+      buildConfiguration = "Debug"
49
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
50
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
51
+      launchStyle = "0"
52
+      useCustomWorkingDirectory = "NO"
53
+      ignoresPersistentStateOnLaunch = "NO"
54
+      debugDocumentVersioning = "YES"
55
+      debugServiceExtension = "internal"
56
+      allowLocationSimulation = "YES">
57
+      <BuildableProductRunnable
58
+         runnableDebuggingMode = "0">
59
+         <BuildableReference
60
+            BuildableIdentifier = "primary"
61
+            BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
62
+            BuildableName = "example.app"
63
+            BlueprintName = "example"
64
+            ReferencedContainer = "container:example.xcodeproj">
65
+         </BuildableReference>
66
+      </BuildableProductRunnable>
67
+   </LaunchAction>
68
+   <ProfileAction
69
+      buildConfiguration = "Release"
70
+      shouldUseLaunchSchemeArgsEnv = "YES"
71
+      savedToolIdentifier = ""
72
+      useCustomWorkingDirectory = "NO"
73
+      debugDocumentVersioning = "YES">
74
+      <BuildableProductRunnable
75
+         runnableDebuggingMode = "0">
76
+         <BuildableReference
77
+            BuildableIdentifier = "primary"
78
+            BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
79
+            BuildableName = "example.app"
80
+            BlueprintName = "example"
81
+            ReferencedContainer = "container:example.xcodeproj">
82
+         </BuildableReference>
83
+      </BuildableProductRunnable>
84
+   </ProfileAction>
85
+   <AnalyzeAction
86
+      buildConfiguration = "Debug">
87
+   </AnalyzeAction>
88
+   <ArchiveAction
89
+      buildConfiguration = "Release"
90
+      revealArchiveInOrganizer = "YES">
91
+   </ArchiveAction>
92
+</Scheme>

+ 15
- 0
example/macos/example/AppDelegate.h View File

@@ -0,0 +1,15 @@
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
+
8
+#import <React/RCTBridgeDelegate.h>
9
+#import <UIKit/UIKit.h>
10
+
11
+@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
12
+
13
+@property (nonatomic, strong) UIWindow *window;
14
+
15
+@end

+ 42
- 0
example/macos/example/AppDelegate.m View File

@@ -0,0 +1,42 @@
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
+
8
+#import "AppDelegate.h"
9
+
10
+#import <React/RCTBridge.h>
11
+#import <React/RCTBundleURLProvider.h>
12
+#import <React/RCTRootView.h>
13
+
14
+@implementation AppDelegate
15
+
16
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
17
+{
18
+  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
19
+  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
20
+                                                   moduleName:@"example"
21
+                                            initialProperties:nil];
22
+
23
+  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
24
+
25
+  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
26
+  UIViewController *rootViewController = [UIViewController new];
27
+  rootViewController.view = rootView;
28
+  self.window.rootViewController = rootViewController;
29
+  [self.window makeKeyAndVisible];
30
+  return YES;
31
+}
32
+
33
+- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
34
+{
35
+#if DEBUG
36
+  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"example/index" fallbackResource:nil];
37
+#else
38
+  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
39
+#endif
40
+}
41
+
42
+@end

+ 42
- 0
example/macos/example/Base.lproj/LaunchScreen.xib View File

@@ -0,0 +1,42 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
3
+    <dependencies>
4
+        <deployment identifier="iOS"/>
5
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
6
+        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
7
+    </dependencies>
8
+    <objects>
9
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
10
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
11
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
12
+            <rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
13
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
14
+            <subviews>
15
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
16
+                    <rect key="frame" x="20" y="439" width="441" height="21"/>
17
+                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
18
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
19
+                    <nil key="highlightedColor"/>
20
+                </label>
21
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="example" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
22
+                    <rect key="frame" x="20" y="140" width="441" height="43"/>
23
+                    <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
24
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
25
+                    <nil key="highlightedColor"/>
26
+                </label>
27
+            </subviews>
28
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
29
+            <constraints>
30
+                <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
31
+                <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
32
+                <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
33
+                <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
34
+                <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
35
+                <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
36
+            </constraints>
37
+            <nil key="simulatedStatusBarMetrics"/>
38
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
39
+            <point key="canvasLocation" x="548" y="455"/>
40
+        </view>
41
+    </objects>
42
+</document>

+ 53
- 0
example/macos/example/Images.xcassets/AppIcon.appiconset/Contents.json View File

@@ -0,0 +1,53 @@
1
+{
2
+  "images" : [
3
+    {
4
+      "idiom" : "iphone",
5
+      "size" : "20x20",
6
+      "scale" : "2x"
7
+    },
8
+    {
9
+      "idiom" : "iphone",
10
+      "size" : "20x20",
11
+      "scale" : "3x"
12
+    },
13
+    {
14
+      "idiom" : "iphone",
15
+      "size" : "29x29",
16
+      "scale" : "2x"
17
+    },
18
+    {
19
+      "idiom" : "iphone",
20
+      "size" : "29x29",
21
+      "scale" : "3x"
22
+    },
23
+    {
24
+      "idiom" : "iphone",
25
+      "size" : "40x40",
26
+      "scale" : "2x"
27
+    },
28
+    {
29
+      "idiom" : "iphone",
30
+      "size" : "40x40",
31
+      "scale" : "3x"
32
+    },
33
+    {
34
+      "idiom" : "iphone",
35
+      "size" : "60x60",
36
+      "scale" : "2x"
37
+    },
38
+    {
39
+      "idiom" : "iphone",
40
+      "size" : "60x60",
41
+      "scale" : "3x"
42
+    },
43
+    {
44
+      "idiom" : "ios-marketing",
45
+      "size" : "1024x1024",
46
+      "scale" : "1x"
47
+    }
48
+  ],
49
+  "info" : {
50
+    "version" : 1,
51
+    "author" : "xcode"
52
+  }
53
+}

+ 6
- 0
example/macos/example/Images.xcassets/Contents.json View File

@@ -0,0 +1,6 @@
1
+{
2
+  "info" : {
3
+    "version" : 1,
4
+    "author" : "xcode"
5
+  }
6
+}

+ 57
- 0
example/macos/example/Info.plist View File

@@ -0,0 +1,57 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+	<key>CFBundleDevelopmentRegion</key>
6
+	<string>en</string>
7
+	<key>CFBundleDisplayName</key>
8
+	<string>example</string>
9
+	<key>CFBundleExecutable</key>
10
+	<string>$(EXECUTABLE_NAME)</string>
11
+	<key>CFBundleIdentifier</key>
12
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13
+	<key>CFBundleInfoDictionaryVersion</key>
14
+	<string>6.0</string>
15
+	<key>CFBundleName</key>
16
+	<string>$(PRODUCT_NAME)</string>
17
+	<key>CFBundlePackageType</key>
18
+	<string>APPL</string>
19
+	<key>CFBundleShortVersionString</key>
20
+	<string>1.0</string>
21
+	<key>CFBundleSignature</key>
22
+	<string>????</string>
23
+	<key>CFBundleVersion</key>
24
+	<string>1</string>
25
+	<key>LSRequiresIPhoneOS</key>
26
+	<true/>
27
+	<key>NSAppTransportSecurity</key>
28
+	<dict>
29
+		<key>NSAllowsArbitraryLoads</key>
30
+		<true/>
31
+		<key>NSExceptionDomains</key>
32
+		<dict>
33
+			<key>localhost</key>
34
+			<dict>
35
+				<key>NSExceptionAllowsInsecureHTTPLoads</key>
36
+				<true/>
37
+			</dict>
38
+		</dict>
39
+	</dict>
40
+	<key>NSLocationWhenInUseUsageDescription</key>
41
+	<string></string>
42
+	<key>UILaunchStoryboardName</key>
43
+	<string>LaunchScreen</string>
44
+	<key>UIRequiredDeviceCapabilities</key>
45
+	<array>
46
+		<string>armv7</string>
47
+	</array>
48
+	<key>UISupportedInterfaceOrientations</key>
49
+	<array>
50
+		<string>UIInterfaceOrientationPortrait</string>
51
+		<string>UIInterfaceOrientationLandscapeLeft</string>
52
+		<string>UIInterfaceOrientationLandscapeRight</string>
53
+	</array>
54
+	<key>UIViewControllerBasedStatusBarAppearance</key>
55
+	<false/>
56
+</dict>
57
+</plist>

+ 16
- 0
example/macos/example/main.m View File

@@ -0,0 +1,16 @@
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
+
8
+#import <UIKit/UIKit.h>
9
+
10
+#import "AppDelegate.h"
11
+
12
+int main(int argc, char * argv[]) {
13
+  @autoreleasepool {
14
+    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15
+  }
16
+}

+ 0
- 39
example/package.json View File

@@ -1,39 +0,0 @@
1
-{
2
-  "name": "example",
3
-  "version": "0.0.1",
4
-  "private": true,
5
-  "scripts": {
6
-    "android": "react-native run-android",
7
-    "ios": "react-native run-ios",
8
-    "start": "react-native start",
9
-    "test": "jest",
10
-    "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
11
-  },
12
-  "dependencies": {
13
-    "react": "16.9.0",
14
-    "react-native": "0.61.5",
15
-    "react-native-webview": "file:../"
16
-  },
17
-  "devDependencies": {
18
-    "@babel/core": "^7.6.2",
19
-    "@babel/runtime": "^7.6.2",
20
-    "@types/react-native": "^0.60.25",
21
-    "@types/react-test-renderer": "16.9.1",
22
-    "@typescript-eslint/eslint-plugin": "^2.12.0",
23
-    "@typescript-eslint/parser": "^2.12.0",
24
-    "babel-jest": "^24.9.0",
25
-    "metro-react-native-babel-preset": "^0.56.0",
26
-    "typescript": "^3.7.3"
27
-  },
28
-  "jest": {
29
-    "preset": "react-native",
30
-    "moduleFileExtensions": [
31
-      "ts",
32
-      "tsx",
33
-      "js",
34
-      "jsx",
35
-      "json",
36
-      "node"
37
-    ]
38
-  }
39
-}

+ 0
- 6591
example/yarn.lock
File diff suppressed because it is too large
View File


+ 168
- 38
ios/RNCWebView.m View File

@@ -9,7 +9,11 @@
9 9
 #import <React/RCTConvert.h>
10 10
 #import <React/RCTAutoInsetsProtocol.h>
11 11
 #import "RNCWKProcessPoolManager.h"
12
+#if !TARGET_OS_OSX
12 13
 #import <UIKit/UIKit.h>
14
+#else
15
+#import <React/RCTUIKit.h>
16
+#endif // !TARGET_OS_OSX
13 17
 
14 18
 #import "objc/runtime.h"
15 19
 
@@ -19,6 +23,7 @@ static NSString *const MessageHandlerName = @"ReactNativeWebView";
19 23
 static NSURLCredential* clientAuthenticationCredential;
20 24
 static NSDictionary* customCertificatesForHost;
21 25
 
26
+#if !TARGET_OS_OSX
22 27
 // runtime trick to remove WKWebView keyboard default toolbar
23 28
 // see: http://stackoverflow.com/questions/19033292/ios-7-uiwebview-keyboard-issue/19042279#19042279
24 29
 @interface _SwizzleHelperWK : UIView
@@ -39,8 +44,29 @@ static NSDictionary* customCertificatesForHost;
39 44
     return nil;
40 45
 }
41 46
 @end
47
+#endif // !TARGET_OS_OSX
42 48
 
43
-@interface RNCWebView () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, UIScrollViewDelegate, RCTAutoInsetsProtocol>
49
+#if TARGET_OS_OSX
50
+@interface RNCWKWebView : WKWebView
51
+@end
52
+@implementation RNCWKWebView
53
+- (void)scrollWheel:(NSEvent *)theEvent {
54
+  RNCWebView *rncWebView = (RNCWebView *)[self superview];
55
+  RCTAssert([rncWebView isKindOfClass:[rncWebView class]], @"superview must be an RNCWebView");
56
+  if (![rncWebView scrollEnabled]) {
57
+    [[self nextResponder] scrollWheel:theEvent];
58
+    return;
59
+  }
60
+  [super scrollWheel:theEvent];
61
+}
62
+@end
63
+#endif // TARGET_OS_OSX
64
+
65
+@interface RNCWebView () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler,
66
+#if !TARGET_OS_OSX
67
+    UIScrollViewDelegate,
68
+#endif // !TARGET_OS_OSX
69
+    RCTAutoInsetsProtocol>
44 70
 @property (nonatomic, copy) RCTDirectEventBlock onLoadingStart;
45 71
 @property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish;
46 72
 @property (nonatomic, copy) RCTDirectEventBlock onLoadingError;
@@ -50,19 +76,29 @@ static NSDictionary* customCertificatesForHost;
50 76
 @property (nonatomic, copy) RCTDirectEventBlock onMessage;
51 77
 @property (nonatomic, copy) RCTDirectEventBlock onScroll;
52 78
 @property (nonatomic, copy) RCTDirectEventBlock onContentProcessDidTerminate;
79
+#if !TARGET_OS_OSX
53 80
 @property (nonatomic, copy) WKWebView *webView;
81
+#else
82
+@property (nonatomic, copy) RNCWKWebView *webView;
83
+#endif // !TARGET_OS_OSX
54 84
 @end
55 85
 
56 86
 @implementation RNCWebView
57 87
 {
88
+#if !TARGET_OS_OSX
58 89
   UIColor * _savedBackgroundColor;
90
+#else
91
+  RCTUIColor * _savedBackgroundColor;
92
+#endif // !TARGET_OS_OSX
59 93
   BOOL _savedHideKeyboardAccessoryView;
60 94
   BOOL _savedKeyboardDisplayRequiresUserAction;
61 95
 
62 96
   // Workaround for StatusBar appearance bug for iOS 12
63 97
   // https://github.com/react-native-community/react-native-webview/issues/62
64 98
   BOOL _isFullScreenVideoOpen;
99
+#if !TARGET_OS_OSX
65 100
   UIStatusBarStyle _savedStatusBarStyle;
101
+#endif // !TARGET_OS_OSX
66 102
   BOOL _savedStatusBarHidden;
67 103
 
68 104
 #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
@@ -73,7 +109,11 @@ static NSDictionary* customCertificatesForHost;
73 109
 - (instancetype)initWithFrame:(CGRect)frame
74 110
 {
75 111
   if ((self = [super initWithFrame:frame])) {
112
+    #if !TARGET_OS_OSX
76 113
     super.backgroundColor = [UIColor clearColor];
114
+    #else
115
+    super.backgroundColor = [RCTUIColor clearColor];
116
+    #endif // !TARGET_OS_OSX
77 117
     _bounces = YES;
78 118
     _scrollEnabled = YES;
79 119
     _showsHorizontalScrollIndicator = YES;
@@ -82,14 +122,17 @@ static NSDictionary* customCertificatesForHost;
82 122
     _automaticallyAdjustContentInsets = YES;
83 123
     _contentInset = UIEdgeInsetsZero;
84 124
     _savedKeyboardDisplayRequiresUserAction = YES;
125
+#if !TARGET_OS_OSX
85 126
     _savedStatusBarStyle = RCTSharedApplication().statusBarStyle;
86 127
     _savedStatusBarHidden = RCTSharedApplication().statusBarHidden;
128
+#endif // !TARGET_OS_OSX
87 129
 
88 130
 #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
89 131
     _savedContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
90 132
 #endif
91 133
   }
92 134
 
135
+#if !TARGET_OS_OSX
93 136
   if (@available(iOS 12.0, *)) {
94 137
     // Workaround for a keyboard dismissal bug present in iOS 12
95 138
     // https://openradar.appspot.com/radar?id=5018321736957952
@@ -114,7 +157,7 @@ static NSDictionary* customCertificatesForHost;
114 157
                                                    name:UIWindowDidBecomeHiddenNotification
115 158
                                                  object:nil];
116 159
   }
117
-
160
+#endif // !TARGET_OS_OSX
118 161
   return self;
119 162
 }
120 163
 
@@ -208,6 +251,7 @@ static NSDictionary* customCertificatesForHost;
208 251
     }
209 252
   }
210 253
 
254
+#if !TARGET_OS_OSX
211 255
   wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback;
212 256
 #if WEBKIT_IOS_10_APIS_AVAILABLE
213 257
   wkWebViewConfig.mediaTypesRequiringUserActionForPlayback = _mediaPlaybackRequiresUserAction
@@ -217,6 +261,7 @@ static NSDictionary* customCertificatesForHost;
217 261
 #else
218 262
   wkWebViewConfig.mediaPlaybackRequiresUserAction = _mediaPlaybackRequiresUserAction;
219 263
 #endif
264
+#endif // !TARGET_OS_OSX
220 265
 
221 266
   if (_applicationNameForUserAgent) {
222 267
       wkWebViewConfig.applicationNameForUserAgent = [NSString stringWithFormat:@"%@ %@", wkWebViewConfig.applicationNameForUserAgent, _applicationNameForUserAgent];
@@ -291,17 +336,26 @@ static NSDictionary* customCertificatesForHost;
291 336
 {
292 337
   if (self.window != nil && _webView == nil) {
293 338
     WKWebViewConfiguration *wkWebViewConfig = [self setUpWkWebViewConfig];
339
+#if !TARGET_OS_OSX
294 340
     _webView = [[WKWebView alloc] initWithFrame:self.bounds configuration: wkWebViewConfig];
341
+#else
342
+    _webView = [[RNCWKWebView alloc] initWithFrame:self.bounds configuration: wkWebViewConfig];
343
+#endif // !TARGET_OS_OSX
344
+
295 345
     [self setBackgroundColor: _savedBackgroundColor];
346
+#if !TARGET_OS_OSX
296 347
     _webView.scrollView.delegate = self;
348
+#endif // !TARGET_OS_OSX
297 349
     _webView.UIDelegate = self;
298 350
     _webView.navigationDelegate = self;
351
+#if !TARGET_OS_OSX
299 352
     _webView.scrollView.scrollEnabled = _scrollEnabled;
300 353
     _webView.scrollView.pagingEnabled = _pagingEnabled;
301 354
     _webView.scrollView.bounces = _bounces;
302 355
     _webView.scrollView.showsHorizontalScrollIndicator = _showsHorizontalScrollIndicator;
303 356
     _webView.scrollView.showsVerticalScrollIndicator = _showsVerticalScrollIndicator;
304 357
     _webView.scrollView.directionalLockEnabled = _directionalLockEnabled;
358
+#endif // !TARGET_OS_OSX
305 359
     _webView.allowsLinkPreview = _allowsLinkPreview;
306 360
     [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
307 361
     _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures;
@@ -335,13 +389,16 @@ static NSDictionary* customCertificatesForHost;
335 389
         [_webView.configuration.userContentController removeScriptMessageHandlerForName:MessageHandlerName];
336 390
         [_webView removeObserver:self forKeyPath:@"estimatedProgress"];
337 391
         [_webView removeFromSuperview];
392
+#if !TARGET_OS_OSX
338 393
         _webView.scrollView.delegate = nil;
394
+#endif // !TARGET_OS_OSX
339 395
         _webView = nil;
340 396
     }
341 397
 
342 398
     [super removeFromSuperview];
343 399
 }
344 400
 
401
+#if !TARGET_OS_OSX
345 402
 -(void)showFullScreenVideoStatusBars
346 403
 {
347 404
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
@@ -389,6 +446,7 @@ static NSDictionary* customCertificatesForHost;
389 446
       }];
390 447
     }
391 448
 }
449
+#endif // !TARGET_OS_OSX
392 450
 
393 451
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
394 452
     if ([keyPath isEqual:@"estimatedProgress"] && object == self.webView) {
@@ -402,7 +460,11 @@ static NSDictionary* customCertificatesForHost;
402 460
     }
403 461
 }
404 462
 
463
+#if !TARGET_OS_OSX
405 464
 - (void)setBackgroundColor:(UIColor *)backgroundColor
465
+#else
466
+- (void)setBackgroundColor:(RCTUIColor *)backgroundColor
467
+#endif // !TARGET_OS_OSX
406 468
 {
407 469
   _savedBackgroundColor = backgroundColor;
408 470
   if (_webView == nil) {
@@ -410,9 +472,20 @@ static NSDictionary* customCertificatesForHost;
410 472
   }
411 473
 
412 474
   CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor);
413
-  self.opaque = _webView.opaque = (alpha == 1.0);
475
+  BOOL opaque = (alpha == 1.0);
476
+#if !TARGET_OS_OSX
477
+  self.opaque = _webView.opaque = opaque;
414 478
   _webView.scrollView.backgroundColor = backgroundColor;
415 479
   _webView.backgroundColor = backgroundColor;
480
+#else
481
+  // https://stackoverflow.com/questions/40007753/macos-wkwebview-background-transparency
482
+  NSOperatingSystemVersion version = { 10, 12, 0 };
483
+  if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]) {
484
+    [_webView setValue:@(opaque) forKey: @"drawsBackground"];
485
+  } else {
486
+    [_webView setValue:@(!opaque) forKey: @"drawsTransparentBackground"];
487
+  }
488
+#endif // !TARGET_OS_OSX
416 489
 }
417 490
 
418 491
 #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
@@ -475,6 +548,7 @@ static NSDictionary* customCertificatesForHost;
475 548
   }
476 549
 }
477 550
 
551
+#if !TARGET_OS_OSX
478 552
 - (void)setContentInset:(UIEdgeInsets)contentInset
479 553
 {
480 554
   _contentInset = contentInset;
@@ -489,6 +563,7 @@ static NSDictionary* customCertificatesForHost;
489 563
                     withScrollView:_webView.scrollView
490 564
                       updateOffset:YES];
491 565
 }
566
+#endif // !TARGET_OS_OSX
492 567
 
493 568
 - (void)visitSource
494 569
 {
@@ -525,6 +600,7 @@ static NSDictionary* customCertificatesForHost;
525 600
     }
526 601
 }
527 602
 
603
+#if !TARGET_OS_OSX
528 604
 -(void)setKeyboardDisplayRequiresUserAction:(BOOL)keyboardDisplayRequiresUserAction
529 605
 {
530 606
     if (_webView == nil) {
@@ -630,17 +706,23 @@ static NSDictionary* customCertificatesForHost;
630 706
     object_setClass(subview, newClass);
631 707
 }
632 708
 
709
+// UIScrollViewDelegate method
633 710
 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
634 711
 {
635 712
   scrollView.decelerationRate = _decelerationRate;
636 713
 }
714
+#endif // !TARGET_OS_OSX
637 715
 
638 716
 - (void)setScrollEnabled:(BOOL)scrollEnabled
639 717
 {
640 718
   _scrollEnabled = scrollEnabled;
719
+#if !TARGET_OS_OSX
641 720
   _webView.scrollView.scrollEnabled = scrollEnabled;
721
+#endif // !TARGET_OS_OSX
642 722
 }
643 723
 
724
+#if !TARGET_OS_OSX
725
+// UIScrollViewDelegate method
644 726
 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
645 727
 {
646 728
   // Don't allow scrolling the scrollView.
@@ -690,6 +772,7 @@ static NSDictionary* customCertificatesForHost;
690 772
     _showsVerticalScrollIndicator = showsVerticalScrollIndicator;
691 773
     _webView.scrollView.showsVerticalScrollIndicator = showsVerticalScrollIndicator;
692 774
 }
775
+#endif // !TARGET_OS_OSX
693 776
 
694 777
 - (void)postMessage:(NSString *)message
695 778
 {
@@ -707,7 +790,9 @@ static NSDictionary* customCertificatesForHost;
707 790
 
708 791
   // Ensure webview takes the position and dimensions of RNCWebView
709 792
   _webView.frame = self.bounds;
793
+#if !TARGET_OS_OSX
710 794
   _webView.scrollView.contentInset = _contentInset;
795
+#endif // !TARGET_OS_OSX
711 796
 }
712 797
 
713 798
 - (NSMutableDictionary<NSString *, id> *)baseEvent
@@ -769,52 +854,95 @@ static NSDictionary* customCertificatesForHost;
769 854
 #pragma mark - WKNavigationDelegate methods
770 855
 
771 856
 /**
772
-* alert
773
-*/
857
+ * alert
858
+ */
774 859
 - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
775 860
 {
776
-    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
777
-    [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
778
-        completionHandler();
779
-    }]];
780
-    [[self topViewController] presentViewController:alert animated:YES completion:NULL];
781
-
861
+#if !TARGET_OS_OSX
862
+  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
863
+  [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
864
+    completionHandler();
865
+  }]];
866
+  [[self topViewController] presentViewController:alert animated:YES completion:NULL];
867
+#else
868
+  NSAlert *alert = [[NSAlert alloc] init];
869
+  [alert setMessageText:message];
870
+  [alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:^(__unused NSModalResponse response){
871
+    completionHandler();
872
+  }];
873
+#endif // !TARGET_OS_OSX
782 874
 }
783 875
 
784 876
 /**
785
-* confirm
786
-*/
877
+ * confirm
878
+ */
787 879
 - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
788
-    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
789
-    [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
790
-        completionHandler(YES);
791
-    }]];
792
-    [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
793
-        completionHandler(NO);
794
-    }]];
795
-    [[self topViewController] presentViewController:alert animated:YES completion:NULL];
880
+#if !TARGET_OS_OSX
881
+  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
882
+  [alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
883
+    completionHandler(YES);
884
+  }]];
885
+  [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
886
+    completionHandler(NO);
887
+  }]];
888
+  [[self topViewController] presentViewController:alert animated:YES completion:NULL];
889
+#else
890
+  NSAlert *alert = [[NSAlert alloc] init];
891
+  [alert setMessageText:message];
892
+  [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button")];
893
+  [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel button")];
894
+  void (^callbacksHandlers)(NSModalResponse response) = ^void(NSModalResponse response) {
895
+    completionHandler(response == NSAlertFirstButtonReturn);
896
+  };
897
+  [alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:callbacksHandlers];
898
+#endif // !TARGET_OS_OSX
796 899
 }
797 900
 
798 901
 /**
799
-* prompt
800
-*/
902
+ * prompt
903
+ */
801 904
 - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler{
802
-    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:prompt preferredStyle:UIAlertControllerStyleAlert];
803
-    [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
804
-        textField.text = defaultText;
805
-    }];
806
-    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
807
-        completionHandler([[alert.textFields lastObject] text]);
808
-    }];
809
-    [alert addAction:okAction];
810
-    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
811
-        completionHandler(nil);
812
-    }];
813
-    [alert addAction:cancelAction];
814
-    alert.preferredAction = okAction;
815
-    [[self topViewController] presentViewController:alert animated:YES completion:NULL];
905
+#if !TARGET_OS_OSX
906
+  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:prompt preferredStyle:UIAlertControllerStyleAlert];
907
+  [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
908
+    textField.text = defaultText;
909
+  }];
910
+  UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
911
+    completionHandler([[alert.textFields lastObject] text]);
912
+  }];
913
+  [alert addAction:okAction];
914
+  UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
915
+    completionHandler(nil);
916
+  }];
917
+  [alert addAction:cancelAction];
918
+  alert.preferredAction = okAction;
919
+  [[self topViewController] presentViewController:alert animated:YES completion:NULL];
920
+#else
921
+  NSAlert *alert = [[NSAlert alloc] init];
922
+  [alert setMessageText:prompt];
923
+
924
+  const NSRect RCTSingleTextFieldFrame = NSMakeRect(0.0, 0.0, 275.0, 22.0);
925
+  NSTextField *textField = [[NSTextField alloc] initWithFrame:RCTSingleTextFieldFrame];
926
+  textField.cell.scrollable = YES;
927
+  if (@available(macOS 10.11, *)) {
928
+    textField.maximumNumberOfLines = 1;
929
+  }
930
+  textField.stringValue = defaultText;
931
+  [alert setAccessoryView:textField];
932
+
933
+  [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button")];
934
+  [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel button")];
935
+  [alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:^(NSModalResponse response) {
936
+    if (response == NSAlertFirstButtonReturn) {
937
+      completionHandler([textField stringValue]);
938
+    } else {
939
+      completionHandler(nil);
940
+    }
941
+  }];
942
+#endif // !TARGET_OS_OSX
816 943
 }
817 944
 
945
+#if !TARGET_OS_OSX
818 946
 /**
819 947
  * topViewController
820 948
  */
@@ -853,7 +981,7 @@ static NSDictionary* customCertificatesForHost;
853 981
   }
854 982
   return window;
855 983
 }
856
-
984
+#endif // !TARGET_OS_OSX
857 985
 
858 986
 /**
859 987
  * Decides whether to allow or cancel a navigation.
@@ -1058,11 +1186,13 @@ static NSDictionary* customCertificatesForHost;
1058 1186
   [_webView stopLoading];
1059 1187
 }
1060 1188
 
1189
+#if !TARGET_OS_OSX
1061 1190
 - (void)setBounces:(BOOL)bounces
1062 1191
 {
1063 1192
   _bounces = bounces;
1064 1193
   _webView.scrollView.bounces = bounces;
1065 1194
 }
1195
+#endif // !TARGET_OS_OSX
1066 1196
 
1067 1197
 - (NSURLRequest *)requestForSource:(id)json {
1068 1198
   NSURLRequest *request = [RCTConvert NSURLRequest:self.source];

+ 6
- 13
ios/RNCWebViewManager.m View File

@@ -14,19 +14,6 @@
14 14
 @interface RNCWebViewManager () <RNCWebViewDelegate>
15 15
 @end
16 16
 
17
-@implementation RCTConvert (UIScrollView)
18
-
19
-#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
20
-RCT_ENUM_CONVERTER(UIScrollViewContentInsetAdjustmentBehavior, (@{
21
-                                                                  @"automatic": @(UIScrollViewContentInsetAdjustmentAutomatic),
22
-                                                                  @"scrollableAxes": @(UIScrollViewContentInsetAdjustmentScrollableAxes),
23
-                                                                  @"never": @(UIScrollViewContentInsetAdjustmentNever),
24
-                                                                  @"always": @(UIScrollViewContentInsetAdjustmentAlways),
25
-                                                                  }), UIScrollViewContentInsetAdjustmentNever, integerValue)
26
-#endif
27
-
28
-@end
29
-
30 17
 @implementation RNCWebViewManager
31 18
 {
32 19
   NSConditionLock *_shouldStartLoadLock;
@@ -35,7 +22,11 @@ RCT_ENUM_CONVERTER(UIScrollViewContentInsetAdjustmentBehavior, (@{
35 22
 
36 23
 RCT_EXPORT_MODULE()
37 24
 
25
+#if !TARGET_OS_OSX
38 26
 - (UIView *)view
27
+#else
28
+- (RCTUIView *)view
29
+#endif // !TARGET_OS_OSX
39 30
 {
40 31
   RNCWebView *webView = [RNCWebView new];
41 32
   webView.delegate = self;
@@ -110,9 +101,11 @@ RCT_CUSTOM_VIEW_PROPERTY(sharedCookiesEnabled, BOOL, RNCWebView) {
110 101
     view.sharedCookiesEnabled = json == nil ? false : [RCTConvert BOOL: json];
111 102
 }
112 103
 
104
+#if !TARGET_OS_OSX
113 105
 RCT_CUSTOM_VIEW_PROPERTY(decelerationRate, CGFloat, RNCWebView) {
114 106
   view.decelerationRate = json == nil ? UIScrollViewDecelerationRateNormal : [RCTConvert CGFloat: json];
115 107
 }
108
+#endif // !TARGET_OS_OSX
116 109
 
117 110
 RCT_CUSTOM_VIEW_PROPERTY(directionalLockEnabled, BOOL, RNCWebView) {
118 111
     view.directionalLockEnabled = json == nil ? true : [RCTConvert BOOL: json];

+ 363
- 0
macos/RNCWebView.xcodeproj/project.pbxproj View File

@@ -0,0 +1,363 @@
1
+// !$*UTF8*$!
2
+{
3
+	archiveVersion = 1;
4
+	classes = {
5
+	};
6
+	objectVersion = 46;
7
+	objects = {
8
+
9
+/* Begin PBXBuildFile section */
10
+		3515965E21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3515965D21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m */; };
11
+		38116A2B23BBECB700ACE311 /* ../ios/RNCWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351B21446E6C00F9801F /* ../ios/RNCWebViewManager.m */; };
12
+		38116A2C23BBECB700ACE311 /* ../ios/RNCWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351C21446E6C00F9801F /* ../ios/RNCWebView.m */; };
13
+		38116A2D23BBECB700ACE311 /* ../ios/RNCWKProcessPoolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3515965D21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m */; };
14
+		E91B351D21446E6C00F9801F /* ../ios/RNCWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351B21446E6C00F9801F /* ../ios/RNCWebViewManager.m */; };
15
+		E91B351E21446E6C00F9801F /* ../ios/RNCWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351C21446E6C00F9801F /* ../ios/RNCWebView.m */; };
16
+/* End PBXBuildFile section */
17
+
18
+/* Begin PBXCopyFilesBuildPhase section */
19
+		38116A2F23BBECB700ACE311 /* CopyFiles */ = {
20
+			isa = PBXCopyFilesBuildPhase;
21
+			buildActionMask = 2147483647;
22
+			dstPath = "include/$(PRODUCT_NAME)";
23
+			dstSubfolderSpec = 16;
24
+			files = (
25
+			);
26
+			runOnlyForDeploymentPostprocessing = 0;
27
+		};
28
+		58B511D91A9E6C8500147676 /* CopyFiles */ = {
29
+			isa = PBXCopyFilesBuildPhase;
30
+			buildActionMask = 2147483647;
31
+			dstPath = "include/$(PRODUCT_NAME)";
32
+			dstSubfolderSpec = 16;
33
+			files = (
34
+			);
35
+			runOnlyForDeploymentPostprocessing = 0;
36
+		};
37
+/* End PBXCopyFilesBuildPhase section */
38
+
39
+/* Begin PBXFileReference section */
40
+		134814201AA4EA6300B7C361 /* libRNCWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCWebView.a; sourceTree = BUILT_PRODUCTS_DIR; };
41
+		3515965D21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ../ios/RNCWKProcessPoolManager.m; sourceTree = "<group>"; };
42
+		3515965F21A3C87E00623BFA /* ../ios/RNCWKProcessPoolManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ../ios/RNCWKProcessPoolManager.h; sourceTree = "<group>"; };
43
+		38116A3323BBECB700ACE311 /* libRNCWebView-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRNCWebView-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
44
+		E91B351921446E6C00F9801F /* ../ios/RNCWebViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ../ios/RNCWebViewManager.h; sourceTree = "<group>"; };
45
+		E91B351A21446E6C00F9801F /* ../ios/RNCWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ../ios/RNCWebView.h; sourceTree = "<group>"; };
46
+		E91B351B21446E6C00F9801F /* ../ios/RNCWebViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ../ios/RNCWebViewManager.m; sourceTree = "<group>"; };
47
+		E91B351C21446E6C00F9801F /* ../ios/RNCWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ../ios/RNCWebView.m; sourceTree = "<group>"; };
48
+/* End PBXFileReference section */
49
+
50
+/* Begin PBXFrameworksBuildPhase section */
51
+		38116A2E23BBECB700ACE311 /* Frameworks */ = {
52
+			isa = PBXFrameworksBuildPhase;
53
+			buildActionMask = 2147483647;
54
+			files = (
55
+			);
56
+			runOnlyForDeploymentPostprocessing = 0;
57
+		};
58
+		58B511D81A9E6C8500147676 /* Frameworks */ = {
59
+			isa = PBXFrameworksBuildPhase;
60
+			buildActionMask = 2147483647;
61
+			files = (
62
+			);
63
+			runOnlyForDeploymentPostprocessing = 0;
64
+		};
65
+/* End PBXFrameworksBuildPhase section */
66
+
67
+/* Begin PBXGroup section */
68
+		134814211AA4EA7D00B7C361 /* Products */ = {
69
+			isa = PBXGroup;
70
+			children = (
71
+				134814201AA4EA6300B7C361 /* libRNCWebView.a */,
72
+			);
73
+			name = Products;
74
+			sourceTree = "<group>";
75
+		};
76
+		58B511D21A9E6C8500147676 = {
77
+			isa = PBXGroup;
78
+			children = (
79
+				E91B351A21446E6C00F9801F /* ../ios/RNCWebView.h */,
80
+				E91B351C21446E6C00F9801F /* ../ios/RNCWebView.m */,
81
+				E91B351921446E6C00F9801F /* ../ios/RNCWebViewManager.h */,
82
+				E91B351B21446E6C00F9801F /* ../ios/RNCWebViewManager.m */,
83
+				3515965D21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m */,
84
+				3515965F21A3C87E00623BFA /* ../ios/RNCWKProcessPoolManager.h */,
85
+				134814211AA4EA7D00B7C361 /* Products */,
86
+				38116A3323BBECB700ACE311 /* libRNCWebView-macOS.a */,
87
+			);
88
+			sourceTree = "<group>";
89
+		};
90
+/* End PBXGroup section */
91
+
92
+/* Begin PBXNativeTarget section */
93
+		38116A2923BBECB700ACE311 /* RNCWebView-macOS */ = {
94
+			isa = PBXNativeTarget;
95
+			buildConfigurationList = 38116A3023BBECB700ACE311 /* Build configuration list for PBXNativeTarget "RNCWebView-macOS" */;
96
+			buildPhases = (
97
+				38116A2A23BBECB700ACE311 /* Sources */,
98
+				38116A2E23BBECB700ACE311 /* Frameworks */,
99
+				38116A2F23BBECB700ACE311 /* CopyFiles */,
100
+			);
101
+			buildRules = (
102
+			);
103
+			dependencies = (
104
+			);
105
+			name = "RNCWebView-macOS";
106
+			productName = RCTDataManager;
107
+			productReference = 38116A3323BBECB700ACE311 /* libRNCWebView-macOS.a */;
108
+			productType = "com.apple.product-type.library.static";
109
+		};
110
+		58B511DA1A9E6C8500147676 /* RNCWebView */ = {
111
+			isa = PBXNativeTarget;
112
+			buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCWebView" */;
113
+			buildPhases = (
114
+				58B511D71A9E6C8500147676 /* Sources */,
115
+				58B511D81A9E6C8500147676 /* Frameworks */,
116
+				58B511D91A9E6C8500147676 /* CopyFiles */,
117
+			);
118
+			buildRules = (
119
+			);
120
+			dependencies = (
121
+			);
122
+			name = RNCWebView;
123
+			productName = RCTDataManager;
124
+			productReference = 134814201AA4EA6300B7C361 /* libRNCWebView.a */;
125
+			productType = "com.apple.product-type.library.static";
126
+		};
127
+/* End PBXNativeTarget section */
128
+
129
+/* Begin PBXProject section */
130
+		58B511D31A9E6C8500147676 /* Project object */ = {
131
+			isa = PBXProject;
132
+			attributes = {
133
+				LastUpgradeCheck = 0830;
134
+				ORGANIZATIONNAME = Facebook;
135
+				TargetAttributes = {
136
+					58B511DA1A9E6C8500147676 = {
137
+						CreatedOnToolsVersion = 6.1.1;
138
+					};
139
+				};
140
+			};
141
+			buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCWebView" */;
142
+			compatibilityVersion = "Xcode 3.2";
143
+			developmentRegion = en;
144
+			hasScannedForEncodings = 0;
145
+			knownRegions = (
146
+				en,
147
+			);
148
+			mainGroup = 58B511D21A9E6C8500147676;
149
+			productRefGroup = 58B511D21A9E6C8500147676;
150
+			projectDirPath = "";
151
+			projectRoot = "";
152
+			targets = (
153
+				58B511DA1A9E6C8500147676 /* RNCWebView */,
154
+				38116A2923BBECB700ACE311 /* RNCWebView-macOS */,
155
+			);
156
+		};
157
+/* End PBXProject section */
158
+
159
+/* Begin PBXSourcesBuildPhase section */
160
+		38116A2A23BBECB700ACE311 /* Sources */ = {
161
+			isa = PBXSourcesBuildPhase;
162
+			buildActionMask = 2147483647;
163
+			files = (
164
+				38116A2B23BBECB700ACE311 /* ../ios/RNCWebViewManager.m in Sources */,
165
+				38116A2C23BBECB700ACE311 /* ../ios/RNCWebView.m in Sources */,
166
+				38116A2D23BBECB700ACE311 /* ../ios/RNCWKProcessPoolManager.m in Sources */,
167
+			);
168
+			runOnlyForDeploymentPostprocessing = 0;
169
+		};
170
+		58B511D71A9E6C8500147676 /* Sources */ = {
171
+			isa = PBXSourcesBuildPhase;
172
+			buildActionMask = 2147483647;
173
+			files = (
174
+				E91B351D21446E6C00F9801F /* ../ios/RNCWebViewManager.m in Sources */,
175
+				E91B351E21446E6C00F9801F /* ../ios/RNCWebView.m in Sources */,
176
+				3515965E21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m in Sources */,
177
+			);
178
+			runOnlyForDeploymentPostprocessing = 0;
179
+		};
180
+/* End PBXSourcesBuildPhase section */
181
+
182
+/* Begin XCBuildConfiguration section */
183
+		38116A3123BBECB700ACE311 /* Debug */ = {
184
+			isa = XCBuildConfiguration;
185
+			buildSettings = {
186
+				FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native-macos/React/**";
187
+				HEADER_SEARCH_PATHS = (
188
+					"$(inherited)",
189
+					"$(SRCROOT)/../node_modules/react-native-macos/React/**",
190
+				);
191
+				LIBRARY_SEARCH_PATHS = "$(inherited)";
192
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
193
+				OTHER_LDFLAGS = "-ObjC";
194
+				PRODUCT_NAME = "$(TARGET_NAME)";
195
+				SDKROOT = macosx;
196
+				SKIP_INSTALL = YES;
197
+			};
198
+			name = Debug;
199
+		};
200
+		38116A3223BBECB700ACE311 /* Release */ = {
201
+			isa = XCBuildConfiguration;
202
+			buildSettings = {
203
+				FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native-macos/React/**";
204
+				HEADER_SEARCH_PATHS = (
205
+					"$(inherited)",
206
+					"$(SRCROOT)/../node_modules/react-native-macos/React/**",
207
+				);
208
+				LIBRARY_SEARCH_PATHS = "$(inherited)";
209
+				MACOSX_DEPLOYMENT_TARGET = 10.14;
210
+				OTHER_LDFLAGS = "-ObjC";
211
+				PRODUCT_NAME = "$(TARGET_NAME)";
212
+				SDKROOT = macosx;
213
+				SKIP_INSTALL = YES;
214
+			};
215
+			name = Release;
216
+		};
217
+		58B511ED1A9E6C8500147676 /* Debug */ = {
218
+			isa = XCBuildConfiguration;
219
+			buildSettings = {
220
+				ALWAYS_SEARCH_USER_PATHS = NO;
221
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
222
+				CLANG_CXX_LIBRARY = "libc++";
223
+				CLANG_ENABLE_MODULES = YES;
224
+				CLANG_ENABLE_OBJC_ARC = YES;
225
+				CLANG_WARN_BOOL_CONVERSION = YES;
226
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
227
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
228
+				CLANG_WARN_EMPTY_BODY = YES;
229
+				CLANG_WARN_ENUM_CONVERSION = YES;
230
+				CLANG_WARN_INFINITE_RECURSION = YES;
231
+				CLANG_WARN_INT_CONVERSION = YES;
232
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
233
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
234
+				CLANG_WARN_UNREACHABLE_CODE = YES;
235
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
236
+				COPY_PHASE_STRIP = NO;
237
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
238
+				ENABLE_TESTABILITY = YES;
239
+				GCC_C_LANGUAGE_STANDARD = gnu99;
240
+				GCC_DYNAMIC_NO_PIC = NO;
241
+				GCC_NO_COMMON_BLOCKS = YES;
242
+				GCC_OPTIMIZATION_LEVEL = 0;
243
+				GCC_PREPROCESSOR_DEFINITIONS = (
244
+					"DEBUG=1",
245
+					"$(inherited)",
246
+				);
247
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
248
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
249
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
250
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
251
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
252
+				GCC_WARN_UNUSED_FUNCTION = YES;
253
+				GCC_WARN_UNUSED_VARIABLE = YES;
254
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
255
+				MTL_ENABLE_DEBUG_INFO = YES;
256
+				ONLY_ACTIVE_ARCH = YES;
257
+				SDKROOT = iphoneos;
258
+			};
259
+			name = Debug;
260
+		};
261
+		58B511EE1A9E6C8500147676 /* Release */ = {
262
+			isa = XCBuildConfiguration;
263
+			buildSettings = {
264
+				ALWAYS_SEARCH_USER_PATHS = NO;
265
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
266
+				CLANG_CXX_LIBRARY = "libc++";
267
+				CLANG_ENABLE_MODULES = YES;
268
+				CLANG_ENABLE_OBJC_ARC = YES;
269
+				CLANG_WARN_BOOL_CONVERSION = YES;
270
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
271
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
272
+				CLANG_WARN_EMPTY_BODY = YES;
273
+				CLANG_WARN_ENUM_CONVERSION = YES;
274
+				CLANG_WARN_INFINITE_RECURSION = YES;
275
+				CLANG_WARN_INT_CONVERSION = YES;
276
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
277
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
278
+				CLANG_WARN_UNREACHABLE_CODE = YES;
279
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
280
+				COPY_PHASE_STRIP = YES;
281
+				ENABLE_NS_ASSERTIONS = NO;
282
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
283
+				GCC_C_LANGUAGE_STANDARD = gnu99;
284
+				GCC_NO_COMMON_BLOCKS = YES;
285
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
286
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
287
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
288
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
289
+				GCC_WARN_UNUSED_FUNCTION = YES;
290
+				GCC_WARN_UNUSED_VARIABLE = YES;
291
+				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
292
+				MTL_ENABLE_DEBUG_INFO = NO;
293
+				SDKROOT = iphoneos;
294
+				VALIDATE_PRODUCT = YES;
295
+			};
296
+			name = Release;
297
+		};
298
+		58B511F01A9E6C8500147676 /* Debug */ = {
299
+			isa = XCBuildConfiguration;
300
+			buildSettings = {
301
+				FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native-macos/React/**";
302
+				HEADER_SEARCH_PATHS = (
303
+					"$(inherited)",
304
+					"$(SRCROOT)/../node_modules/react-native-macos/React/**",
305
+					"$(SRCROOT)/../../react-native-macos/React/**",
306
+				);
307
+				LIBRARY_SEARCH_PATHS = "$(inherited)";
308
+				OTHER_LDFLAGS = "-ObjC";
309
+				PRODUCT_NAME = RNCWebView;
310
+				SKIP_INSTALL = YES;
311
+			};
312
+			name = Debug;
313
+		};
314
+		58B511F11A9E6C8500147676 /* Release */ = {
315
+			isa = XCBuildConfiguration;
316
+			buildSettings = {
317
+				FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native-macos/React/**";
318
+				HEADER_SEARCH_PATHS = (
319
+					"$(inherited)",
320
+					"$(SRCROOT)/../node_modules/react-native-macos/React/**",
321
+					"$(SRCROOT)/../../react-native-macos/React/**",
322
+				);
323
+				LIBRARY_SEARCH_PATHS = "$(inherited)";
324
+				OTHER_LDFLAGS = "-ObjC";
325
+				PRODUCT_NAME = RNCWebView;
326
+				SKIP_INSTALL = YES;
327
+			};
328
+			name = Release;
329
+		};
330
+/* End XCBuildConfiguration section */
331
+
332
+/* Begin XCConfigurationList section */
333
+		38116A3023BBECB700ACE311 /* Build configuration list for PBXNativeTarget "RNCWebView-macOS" */ = {
334
+			isa = XCConfigurationList;
335
+			buildConfigurations = (
336
+				38116A3123BBECB700ACE311 /* Debug */,
337
+				38116A3223BBECB700ACE311 /* Release */,
338
+			);
339
+			defaultConfigurationIsVisible = 0;
340
+			defaultConfigurationName = Release;
341
+		};
342
+		58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCWebView" */ = {
343
+			isa = XCConfigurationList;
344
+			buildConfigurations = (
345
+				58B511ED1A9E6C8500147676 /* Debug */,
346
+				58B511EE1A9E6C8500147676 /* Release */,
347
+			);
348
+			defaultConfigurationIsVisible = 0;
349
+			defaultConfigurationName = Release;
350
+		};
351
+		58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCWebView" */ = {
352
+			isa = XCConfigurationList;
353
+			buildConfigurations = (
354
+				58B511F01A9E6C8500147676 /* Debug */,
355
+				58B511F11A9E6C8500147676 /* Release */,
356
+			);
357
+			defaultConfigurationIsVisible = 0;
358
+			defaultConfigurationName = Release;
359
+		};
360
+/* End XCConfigurationList section */
361
+	};
362
+	rootObject = 58B511D31A9E6C8500147676 /* Project object */;
363
+}

+ 12
- 0
metro.config.js View File

@@ -0,0 +1,12 @@
1
+/**
2
+ * This cli config is needed for development purposes, e.g. for running
3
+ * integration tests during local development or on CI services.
4
+ */
5
+
6
+const blacklist = require('metro-config/src/defaults/blacklist');
7
+
8
+module.exports = {
9
+  resolver: {
10
+    blacklistRE: blacklist([/node_modules\/react-native-macos\/.*/])
11
+  },
12
+};

+ 19
- 0
metro.config.macos.js View File

@@ -0,0 +1,19 @@
1
+/**
2
+ * This cli config is needed for development purposes, e.g. for running
3
+ * integration tests during local development or on CI services.
4
+ */
5
+
6
+const path = require('path');
7
+const blacklist = require('metro-config/src/defaults/blacklist');
8
+
9
+const rnmPath = path.resolve(__dirname, 'node_modules/react-native-macos');
10
+
11
+module.exports = {
12
+  resolver: {
13
+    extraNodeModules: {
14
+      'react-native': rnmPath,
15
+    },
16
+    platforms: ['macos', 'ios', 'android'],
17
+    blacklistRE: blacklist([/node_modules\/react-native\/.*/])
18
+  },
19
+};

+ 18
- 8
package.json View File

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "react-native-webview",
3
-  "description": "React Native WebView component for iOS, Android, and Windows 10 (coming soon)",
3
+  "description": "React Native WebView component for iOS, Android, and macOS",
4 4
   "main": "index.js",
5 5
   "typings": "index.d.ts",
6 6
   "author": "Jamon Holmgren <jamon@infinite.red>",
@@ -8,9 +8,13 @@
8 8
     "Thibault Malbranche <malbranche.thibault@gmail.com>"
9 9
   ],
10 10
   "license": "MIT",
11
-  "version": "8.0.3",
11
+  "version": "8.1.0",
12 12
   "homepage": "https://github.com/react-native-community/react-native-webview#readme",
13 13
   "scripts": {
14
+    "start": "node node_modules/react-native/local-cli/cli.js start",
15
+    "start:android": "react-native run-android --root example/",
16
+    "start:ios": "react-native run-ios --project-path example/ios --scheme example",
17
+    "start:macos": "node node_modules/react-native-macos/local-cli/cli.js start --use-react-native-macos",
14 18
     "ci": "CI=true && yarn lint && yarn test",
15 19
     "ci:publish": "yarn semantic-release",
16 20
     "lint": "yarn tsc --noEmit && yarn eslint ./src --ext .ts,.tsx",
@@ -23,7 +27,7 @@
23 27
     "type": "Component"
24 28
   },
25 29
   "peerDependencies": {
26
-    "react": "^16.0",
30
+    "react": "^16.9",
27 31
     "react-native": ">=0.60 <0.62"
28 32
   },
29 33
   "dependencies": {
@@ -31,7 +35,10 @@
31 35
     "invariant": "2.2.4"
32 36
   },
33 37
   "devDependencies": {
34
-    "@babel/core": "7.5.5",
38
+    "@babel/core": "7.4.5",
39
+    "@babel/runtime": "7.4.5",
40
+    "@react-native-community/cli-platform-ios": "^3.0.0",
41
+    "@react-native-community/cli-platform-android": "^3.0.0",
35 42
     "@semantic-release/git": "7.0.16",
36 43
     "@types/invariant": "^2.2.30",
37 44
     "@types/jest": "24.0.18",
@@ -40,7 +47,8 @@
40 47
     "@typescript-eslint/eslint-plugin": "2.1.0",
41 48
     "@typescript-eslint/parser": "2.1.0",
42 49
     "babel-eslint": "10.0.3",
43
-    "babel-jest": "^24.9.0",
50
+    "babel-jest": "24.8.0",
51
+    "babel-plugin-module-resolver": "3.1.3",
44 52
     "eslint": "6.3.0",
45 53
     "eslint-config-airbnb": "18.0.1",
46 54
     "eslint-config-prettier": "6.2.0",
@@ -49,9 +57,10 @@
49 57
     "eslint-plugin-react": "7.14.3",
50 58
     "eslint-plugin-react-native": "3.7.0",
51 59
     "jest": "24.9.0",
52
-    "metro-react-native-babel-preset": "0.53.1",
53
-    "react": "16.8.3",
54
-    "react-native": "0.60.5",
60
+    "metro-react-native-babel-preset": "0.54.1",
61
+    "react": "16.9.0",
62
+    "react-native": "0.61.5",
63
+    "react-native-macos": "0.60.0-microsoft.49",
55 64
     "semantic-release": "15.13.24",
56 65
     "typescript": "3.6.2"
57 66
   },
@@ -62,6 +71,7 @@
62 71
   "files": [
63 72
     "android",
64 73
     "ios",
74
+    "macos",
65 75
     "lib",
66 76
     "index.js",
67 77
     "index.d.ts",

+ 26
- 0
react-native.config.js View File

@@ -0,0 +1,26 @@
1
+/**
2
+ * This cli config is needed for the coexistance of react-native and other
3
+ * out-of-tree implementations such react-native-macos.
4
+ * The following issue is tracked by
5
+ * https://github.com/react-native-community/discussions-and-proposals/issues/182
6
+ *
7
+ * The work-around involves having a metro.config.js for each out-of-tree
8
+ * platform, i.e. metro.config.js for react-native and 
9
+ * metro.config.macos.js for react-native-macos.
10
+ * This react-native.config.js looks for a --use-react-native-macos
11
+ * switch and when present pushes --config=metro.config.macos.js 
12
+ * and specifies reactNativePath: 'node_modules/react-native-macos'.
13
+ * The metro.config.js has to blacklist 'node_modules/react-native-macos', 
14
+ * and conversely metro.config.macos.js has to blacklist 'node_modules/react-native'.
15
+ */
16
+'use strict';
17
+
18
+const macSwitch = '--use-react-native-macos';
19
+
20
+if (process.argv.includes(macSwitch)) {
21
+  process.argv = process.argv.filter(arg => arg !== macSwitch);
22
+  process.argv.push('--config=metro.config.macos.js');
23
+  module.exports = {
24
+    reactNativePath: 'node_modules/react-native-macos',
25
+  };
26
+}

+ 347
- 0
src/WebView.macos.tsx View File

@@ -0,0 +1,347 @@
1
+import React from 'react';
2
+import {
3
+  UIManager as NotTypedUIManager,
4
+  View,
5
+  requireNativeComponent,
6
+  NativeModules,
7
+  Image,
8
+  findNodeHandle,
9
+  ImageSourcePropType,
10
+} from 'react-native';
11
+import invariant from 'invariant';
12
+
13
+import {
14
+  defaultOriginWhitelist,
15
+  createOnShouldStartLoadWithRequest,
16
+  defaultRenderError,
17
+  defaultRenderLoading,
18
+} from './WebViewShared';
19
+import {
20
+  WebViewErrorEvent,
21
+  WebViewHttpErrorEvent,
22
+  WebViewMessageEvent,
23
+  WebViewNavigationEvent,
24
+  WebViewProgressEvent,
25
+  WebViewTerminatedEvent,
26
+  MacOSWebViewProps,
27
+  NativeWebViewMacOS,
28
+  ViewManager,
29
+  State,
30
+  RNCWebViewUIManagerMacOS,
31
+} from './WebViewTypes';
32
+
33
+import styles from './WebView.styles';
34
+
35
+const UIManager = NotTypedUIManager as RNCWebViewUIManagerMacOS;
36
+
37
+const { resolveAssetSource } = Image;
38
+
39
+const RNCWebViewManager = NativeModules.RNCWebViewManager as ViewManager;
40
+
41
+const RNCWebView: typeof NativeWebViewMacOS = requireNativeComponent(
42
+  'RNCWebView',
43
+);
44
+
45
+class WebView extends React.Component<MacOSWebViewProps, State> {
46
+  static defaultProps = {
47
+    javaScriptEnabled: true,
48
+    cacheEnabled: true,
49
+    originWhitelist: defaultOriginWhitelist,
50
+    useSharedProcessPool: true,
51
+  };
52
+
53
+  static isFileUploadSupported = async () => {
54
+    // no native implementation for macOS, depends only on permissions
55
+    return true;
56
+  };
57
+
58
+  state: State = {
59
+    viewState: this.props.startInLoadingState ? 'LOADING' : 'IDLE',
60
+    lastErrorEvent: null,
61
+  };
62
+
63
+  webViewRef = React.createRef<NativeWebViewMacOS>();
64
+
65
+  // eslint-disable-next-line react/sort-comp
66
+  getCommands = () => UIManager.getViewManagerConfig('RNCWebView').Commands;
67
+
68
+  /**
69
+   * Go forward one page in the web view's history.
70
+   */
71
+  goForward = () => {
72
+    UIManager.dispatchViewManagerCommand(
73
+      this.getWebViewHandle(),
74
+      this.getCommands().goForward,
75
+      undefined,
76
+    );
77
+  };
78
+
79
+  /**
80
+   * Go back one page in the web view's history.
81
+   */
82
+  goBack = () => {
83
+    UIManager.dispatchViewManagerCommand(
84
+      this.getWebViewHandle(),
85
+      this.getCommands().goBack,
86
+      undefined,
87
+    );
88
+  };
89
+
90
+  /**
91
+   * Reloads the current page.
92
+   */
93
+  reload = () => {
94
+    this.setState({ viewState: 'LOADING' });
95
+    UIManager.dispatchViewManagerCommand(
96
+      this.getWebViewHandle(),
97
+      this.getCommands().reload,
98
+      undefined,
99
+    );
100
+  };
101
+
102
+  /**
103
+   * Stop loading the current page.
104
+   */
105
+  stopLoading = () => {
106
+    UIManager.dispatchViewManagerCommand(
107
+      this.getWebViewHandle(),
108
+      this.getCommands().stopLoading,
109
+      undefined,
110
+    );
111
+  };
112
+
113
+  /**
114
+   * Request focus on WebView rendered page.
115
+   */
116
+  requestFocus = () => {
117
+    UIManager.dispatchViewManagerCommand(
118
+      this.getWebViewHandle(),
119
+      this.getCommands().requestFocus,
120
+      undefined,
121
+    );
122
+  };
123
+
124
+  /**
125
+   * Posts a message to the web view, which will emit a `message` event.
126
+   * Accepts one argument, `data`, which must be a string.
127
+   *
128
+   * In your webview, you'll need to something like the following.
129
+   *
130
+   * ```js
131
+   * document.addEventListener('message', e => { document.title = e.data; });
132
+   * ```
133
+   */
134
+  postMessage = (data: string) => {
135
+    UIManager.dispatchViewManagerCommand(
136
+      this.getWebViewHandle(),
137
+      this.getCommands().postMessage,
138
+      [String(data)],
139
+    );
140
+  };
141
+
142
+  /**
143
+   * Injects a javascript string into the referenced WebView. Deliberately does not
144
+   * return a response because using eval() to return a response breaks this method
145
+   * on pages with a Content Security Policy that disallows eval(). If you need that
146
+   * functionality, look into postMessage/onMessage.
147
+   */
148
+  injectJavaScript = (data: string) => {
149
+    UIManager.dispatchViewManagerCommand(
150
+      this.getWebViewHandle(),
151
+      this.getCommands().injectJavaScript,
152
+      [data],
153
+    );
154
+  };
155
+
156
+  /**
157
+   * We return an event with a bunch of fields including:
158
+   *  url, title, loading, canGoBack, canGoForward
159
+   */
160
+  updateNavigationState = (event: WebViewNavigationEvent) => {
161
+    if (this.props.onNavigationStateChange) {
162
+      this.props.onNavigationStateChange(event.nativeEvent);
163
+    }
164
+  };
165
+
166
+  /**
167
+   * Returns the native `WebView` node.
168
+   */
169
+  getWebViewHandle = () => {
170
+    const nodeHandle = findNodeHandle(this.webViewRef.current);
171
+    invariant(nodeHandle != null, 'nodeHandle expected to be non-null');
172
+    return nodeHandle as number;
173
+  };
174
+
175
+  onLoadingStart = (event: WebViewNavigationEvent) => {
176
+    const { onLoadStart } = this.props;
177
+    if (onLoadStart) {
178
+      onLoadStart(event);
179
+    }
180
+    this.updateNavigationState(event);
181
+  };
182
+
183
+  onLoadingError = (event: WebViewErrorEvent) => {
184
+    event.persist(); // persist this event because we need to store it
185
+    const { onError, onLoadEnd } = this.props;
186
+    if (onLoadEnd) {
187
+      onLoadEnd(event);
188
+    }
189
+    if (onError) {
190
+      onError(event);
191
+    }
192
+    console.warn('Encountered an error loading page', event.nativeEvent);
193
+
194
+    this.setState({
195
+      lastErrorEvent: event.nativeEvent,
196
+      viewState: 'ERROR',
197
+    });
198
+  };
199
+
200
+  onHttpError = (event: WebViewHttpErrorEvent) => {
201
+    const { onHttpError } = this.props;
202
+    if (onHttpError) {
203
+      onHttpError(event);
204
+    }
205
+  }
206
+
207
+  onLoadingFinish = (event: WebViewNavigationEvent) => {
208
+    const { onLoad, onLoadEnd } = this.props;
209
+    if (onLoad) {
210
+      onLoad(event);
211
+    }
212
+    if (onLoadEnd) {
213
+      onLoadEnd(event);
214
+    }
215
+    this.setState({
216
+      viewState: 'IDLE',
217
+    });
218
+    this.updateNavigationState(event);
219
+  };
220
+
221
+  onMessage = (event: WebViewMessageEvent) => {
222
+    const { onMessage } = this.props;
223
+    if (onMessage) {
224
+      onMessage(event);
225
+    }
226
+  };
227
+
228
+  onLoadingProgress = (event: WebViewProgressEvent) => {
229
+    const { onLoadProgress } = this.props;
230
+    if (onLoadProgress) {
231
+      onLoadProgress(event);
232
+    }
233
+  };
234
+
235
+  onShouldStartLoadWithRequestCallback = (
236
+    shouldStart: boolean,
237
+    _url: string,
238
+    lockIdentifier: number,
239
+  ) => {
240
+    const viewManager
241
+      = (this.props.nativeConfig && this.props.nativeConfig.viewManager)
242
+      || RNCWebViewManager;
243
+
244
+    viewManager.startLoadWithResult(!!shouldStart, lockIdentifier);
245
+  };
246
+
247
+  onContentProcessDidTerminate = (event: WebViewTerminatedEvent) => {
248
+    const { onContentProcessDidTerminate } = this.props;
249
+    if (onContentProcessDidTerminate) {
250
+      onContentProcessDidTerminate(event);
251
+    }
252
+  };
253
+
254
+  componentDidUpdate(prevProps: MacOSWebViewProps) {
255
+    this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback');
256
+    this.showRedboxOnPropChanges(prevProps, 'incognito');
257
+    this.showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction');
258
+  }
259
+
260
+  showRedboxOnPropChanges(
261
+    prevProps: MacOSWebViewProps,
262
+    propName: keyof MacOSWebViewProps,
263
+  ) {
264
+    if (this.props[propName] !== prevProps[propName]) {
265
+      console.error(
266
+        `Changes to property ${propName} do nothing after the initial render.`,
267
+      );
268
+    }
269
+  }
270
+
271
+  render() {
272
+    const {
273
+      nativeConfig = {},
274
+      onMessage,
275
+      onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
276
+      originWhitelist,
277
+      renderError,
278
+      renderLoading,
279
+      style,
280
+      containerStyle,
281
+      ...otherProps
282
+    } = this.props;
283
+
284
+    let otherView = null;
285
+
286
+    if (this.state.viewState === 'LOADING') {
287
+      otherView = (renderLoading || defaultRenderLoading)();
288
+    } else if (this.state.viewState === 'ERROR') {
289
+      const errorEvent = this.state.lastErrorEvent;
290
+      invariant(errorEvent != null, 'lastErrorEvent expected to be non-null');
291
+      otherView = (renderError || defaultRenderError)(
292
+        errorEvent.domain,
293
+        errorEvent.code,
294
+        errorEvent.description,
295
+      );
296
+    } else if (this.state.viewState !== 'IDLE') {
297
+      console.error(
298
+        `RNCWebView invalid state encountered: ${this.state.viewState}`,
299
+      );
300
+    }
301
+
302
+    const webViewStyles = [styles.container, styles.webView, style];
303
+    const webViewContainerStyle = [styles.container, containerStyle];
304
+
305
+    const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
306
+      this.onShouldStartLoadWithRequestCallback,
307
+      // casting cause it's in the default props
308
+      originWhitelist as readonly string[],
309
+      onShouldStartLoadWithRequestProp,
310
+    );
311
+
312
+    const NativeWebView
313
+      = (nativeConfig.component as typeof NativeWebViewMacOS | undefined)
314
+      || RNCWebView;
315
+
316
+    const webView = (
317
+      <NativeWebView
318
+        key="webViewKey"
319
+        {...otherProps}
320
+        messagingEnabled={typeof onMessage === 'function'}
321
+        onLoadingError={this.onLoadingError}
322
+        onLoadingFinish={this.onLoadingFinish}
323
+        onLoadingProgress={this.onLoadingProgress}
324
+        onLoadingStart={this.onLoadingStart}
325
+        onHttpError={this.onHttpError}
326
+        onMessage={this.onMessage}
327
+        onScroll={this.props.onScroll}
328
+        onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
329
+        onContentProcessDidTerminate={this.onContentProcessDidTerminate}
330
+        ref={this.webViewRef}
331
+        // TODO: find a better way to type this.
332
+        source={resolveAssetSource(this.props.source as ImageSourcePropType)}
333
+        style={webViewStyles}
334
+        {...nativeConfig.props}
335
+      />
336
+    );
337
+
338
+    return (
339
+      <View style={webViewContainerStyle}>
340
+        {webView}
341
+        {otherView}
342
+      </View>
343
+    );
344
+  }
345
+}
346
+
347
+export default WebView;

+ 175
- 14
src/WebViewTypes.ts View File

@@ -28,7 +28,7 @@ interface RNCWebViewUIManager<Commands extends string> extends UIManagerStatic {
28 28
 
29 29
 export type RNCWebViewUIManagerAndroid = RNCWebViewUIManager<WebViewCommands | AndroidWebViewCommands>
30 30
 export type RNCWebViewUIManagerIOS = RNCWebViewUIManager<WebViewCommands>
31
-
31
+export type RNCWebViewUIManagerMacOS = RNCWebViewUIManager<WebViewCommands>
32 32
 
33 33
 
34 34
 type WebViewState = 'IDLE' | 'LOADING' | 'ERROR';
@@ -57,6 +57,14 @@ declare const NativeWebViewIOSBase: Constructor<NativeMethodsMixin> &
57 57
   typeof NativeWebViewIOSComponent;
58 58
 export class NativeWebViewIOS extends NativeWebViewIOSBase {}
59 59
 
60
+// eslint-disable-next-line react/prefer-stateless-function
61
+declare class NativeWebViewMacOSComponent extends Component<
62
+  MacOSNativeWebViewProps
63
+> {}
64
+declare const NativeWebViewMacOSBase: Constructor<NativeMethodsMixin> &
65
+  typeof NativeWebViewMacOSComponent;
66
+export class NativeWebViewMacOS extends NativeWebViewMacOSBase {}
67
+
60 68
 // eslint-disable-next-line react/prefer-stateless-function
61 69
 declare class NativeWebViewAndroidComponent extends Component<
62 70
   AndroidNativeWebViewProps
@@ -104,7 +112,7 @@ export interface WebViewMessage extends WebViewNativeEvent {
104 112
 
105 113
 export interface WebViewError extends WebViewNativeEvent {
106 114
   /**
107
-   * `domain` is only used on iOS
115
+   * `domain` is only used on iOS and macOS
108 116
    */
109 117
   domain?: string;
110 118
   code: number;
@@ -195,7 +203,7 @@ export interface WebViewNativeConfig {
195 203
   /**
196 204
    * The native component used to render the WebView.
197 205
    */
198
-  component?: typeof NativeWebViewIOS | typeof NativeWebViewAndroid;
206
+  component?: typeof NativeWebViewIOS | typeof NativeWebViewMacOS | typeof NativeWebViewAndroid;
199 207
   /**
200 208
    * Set props directly on the native component WebView. Enables custom props which the
201 209
    * original WebView doesn't pass through.
@@ -203,7 +211,7 @@ export interface WebViewNativeConfig {
203 211
   props?: Object;
204 212
   /**
205 213
    * Set the ViewManager to use for communication with the native side.
206
-   * @platform ios
214
+   * @platform ios, macos
207 215
    */
208 216
   viewManager?: ViewManager;
209 217
 }
@@ -258,6 +266,13 @@ export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps {
258 266
   urlPrefixesForDefaultIntent?: readonly string[];
259 267
 }
260 268
 
269
+export enum ContentInsetAdjustmentBehavior {
270
+  automatic = 'automatic',
271
+  scrollableAxes = 'scrollableAxes',
272
+  never = 'never',
273
+  always = 'always'
274
+};
275
+
261 276
 export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
262 277
   allowingReadAccessToURL?: string;
263 278
   allowsBackForwardNavigationGestures?: boolean;
@@ -266,11 +281,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
266 281
   automaticallyAdjustContentInsets?: boolean;
267 282
   bounces?: boolean;
268 283
   contentInset?: ContentInsetProp;
269
-  contentInsetAdjustmentBehavior?:
270
-    | 'automatic'
271
-    | 'scrollableAxes'
272
-    | 'never'
273
-    | 'always';
284
+  contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
274 285
   dataDetectorTypes?: DataDetectorTypes | readonly DataDetectorTypes[];
275 286
   decelerationRate?: number;
276 287
   directionalLockEnabled?: boolean;
@@ -281,6 +292,23 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
281 292
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
282 293
 }
283 294
 
295
+export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps {
296
+  allowingReadAccessToURL?: string;
297
+  allowsBackForwardNavigationGestures?: boolean;
298
+  allowsInlineMediaPlayback?: boolean;
299
+  allowsLinkPreview?: boolean;
300
+  automaticallyAdjustContentInsets?: boolean;
301
+  bounces?: boolean;
302
+  contentInset?: ContentInsetProp;
303
+  contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
304
+  directionalLockEnabled?: boolean;
305
+  hideKeyboardAccessoryView?: boolean;
306
+  pagingEnabled?: boolean;
307
+  scrollEnabled?: boolean;
308
+  useSharedProcessPool?: boolean;
309
+  onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
310
+}
311
+
284 312
 export interface IOSWebViewProps extends WebViewSharedProps {
285 313
   /**
286 314
    * Does not store any data within the lifetime of the WebView.
@@ -335,11 +363,7 @@ export interface IOSWebViewProps extends WebViewSharedProps {
335 363
    * content area of the scroll view. The default value of this property is
336 364
    * "never". Available on iOS 11 and later.
337 365
    */
338
-  contentInsetAdjustmentBehavior?:
339
-    | 'automatic'
340
-    | 'scrollableAxes'
341
-    | 'never'
342
-    | 'always';
366
+  contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
343 367
 
344 368
   /**
345 369
    * The amount by which the web view content is inset from the edges of
@@ -460,6 +484,143 @@ export interface IOSWebViewProps extends WebViewSharedProps {
460 484
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
461 485
 }
462 486
 
487
+export interface MacOSWebViewProps extends WebViewSharedProps {
488
+  /**
489
+   * Does not store any data within the lifetime of the WebView.
490
+   */
491
+  incognito?: boolean;
492
+
493
+  /**
494
+   * Boolean value that determines whether the web view bounces
495
+   * when it reaches the edge of the content. The default value is `true`.
496
+   * @platform macos
497
+   */
498
+  bounces?: boolean;
499
+
500
+  /**
501
+   * Boolean value that determines whether scrolling is enabled in the
502
+   * `WebView`. The default value is `true`.
503
+   * @platform macos
504
+   */
505
+  scrollEnabled?: boolean;
506
+
507
+  /**
508
+   * If the value of this property is true, the scroll view stops on multiples
509
+   * of the scroll view’s bounds when the user scrolls.
510
+   * The default value is false.
511
+   * @platform macos
512
+   */
513
+  pagingEnabled?: boolean;
514
+
515
+  /**
516
+   * Controls whether to adjust the content inset for web views that are
517
+   * placed behind a navigation bar, tab bar, or toolbar. The default value
518
+   * is `true`.
519
+   * @platform macos
520
+   */
521
+  automaticallyAdjustContentInsets?: boolean;
522
+
523
+  /**
524
+   * This property specifies how the safe area insets are used to modify the
525
+   * content area of the scroll view. The default value of this property is
526
+   * "never". Available on iOS 11 and later.
527
+   */
528
+  contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
529
+
530
+  /**
531
+   * The amount by which the web view content is inset from the edges of
532
+   * the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.
533
+   * @platform macos
534
+   */
535
+  contentInset?: ContentInsetProp;
536
+
537
+  /**
538
+   * Boolean that determines whether HTML5 videos play inline or use the
539
+   * native full-screen controller. The default value is `false`.
540
+   *
541
+   * **NOTE** : In order for video to play inline, not only does this
542
+   * property need to be set to `true`, but the video element in the HTML
543
+   * document must also include the `webkit-playsinline` attribute.
544
+   * @platform macos
545
+   */
546
+  allowsInlineMediaPlayback?: boolean;
547
+  /**
548
+   * Hide the accessory view when the keyboard is open. Default is false to be
549
+   * backward compatible.
550
+   */
551
+  hideKeyboardAccessoryView?: boolean;
552
+  /**
553
+   * A Boolean value indicating whether horizontal swipe gestures will trigger
554
+   * back-forward list navigations.
555
+   */
556
+  allowsBackForwardNavigationGestures?: boolean;
557
+  /**
558
+   * A Boolean value indicating whether WebKit WebView should be created using a shared
559
+   * process pool, enabling WebViews to share cookies and localStorage between each other.
560
+   * Default is true but can be set to false for backwards compatibility.
561
+   * @platform macos
562
+   */
563
+  useSharedProcessPool?: boolean;
564
+
565
+  /**
566
+   * The custom user agent string.
567
+   */
568
+  userAgent?: string;
569
+
570
+  /**
571
+   * A Boolean value that determines whether pressing on a link
572
+   * displays a preview of the destination for the link.
573
+   *
574
+   * This property is available on devices that support Force Touch trackpad.
575
+   * @platform macos
576
+   */
577
+  allowsLinkPreview?: boolean;
578
+
579
+  /**
580
+   * Set true if shared cookies from HTTPCookieStorage should used for every load request.
581
+   * The default value is `false`.
582
+   * @platform macos
583
+   */
584
+  sharedCookiesEnabled?: boolean;
585
+
586
+  /**
587
+   * A Boolean value that determines whether scrolling is disabled in a particular direction.
588
+   * The default value is `true`.
589
+   * @platform macos
590
+   */
591
+  directionalLockEnabled?: boolean;
592
+
593
+  /**
594
+   * A Boolean value indicating whether web content can programmatically display the keyboard.
595
+   *
596
+   * When this property is set to true, the user must explicitly tap the elements in the
597
+   * web view to display the keyboard (or other relevant input view) for that element.
598
+   * When set to false, a focus event on an element causes the input view to be displayed
599
+   * and associated with that element automatically.
600
+   *
601
+   * The default value is `true`.
602
+   * @platform macos
603
+   */
604
+  keyboardDisplayRequiresUserAction?: boolean;
605
+
606
+  /**
607
+   * A String value that indicates which URLs the WebView's file can then
608
+   * reference in scripts, AJAX requests, and CSS imports. This is only used
609
+   * for WebViews that are loaded with a source.uri set to a `'file://'` URL.
610
+   *
611
+   * If not provided, the default is to only allow read access to the URL
612
+   * provided in source.uri itself.
613
+   * @platform macos
614
+   */
615
+  allowingReadAccessToURL?: string;
616
+
617
+  /**
618
+   * Function that is invoked when the WebKit WebView content process gets terminated.
619
+   * @platform macos
620
+   */
621
+  onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
622
+}
623
+
463 624
 export interface AndroidWebViewProps extends WebViewSharedProps {
464 625
   onNavigationStateChange?: (event: WebViewNavigation) => void;
465 626
   onContentSizeChange?: (event: WebViewEvent) => void;

+ 551
- 88
yarn.lock
File diff suppressed because it is too large
View File