feat(macOS): macOS Support (#1164)

This commit is contained in:
Tom Underhill 2020-02-12 15:39:11 -08:00 committed by GitHub
parent 31d015badf
commit 1e572318ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 4376 additions and 84 deletions

View File

@ -20,6 +20,7 @@ _This project is maintained for free by these people using both their free time
- [x] iOS
- [x] Android
- [x] macOS
_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)._

View File

@ -8,6 +8,44 @@ Secondly, we'd like the contribution experience to be as good as possible. While
After you fork the repo, clone it to your machine, and make your changes, you'll want to test them in an app.
There are two methods of testing:
1) Testing within a clone of react-native-webview
2) Testing in a new `react-native init` project
### Testing within react-native-webview
#### For all platforms:
```
$ yarn install
```
#### For Android:
```
$ yarn start:android
```
The Android example app will built, the Metro Bundler will launch, and the example app will be installed and started in the Android emulator.
#### For iOS:
```
$ cd example/ios
$ pod install
$ cd ../..
$ yarn start:ios
```
The iOS example app will be built, the Metro bundler will launch, and the example app will be install and started in the Simulator.
#### for macOS:
```
$ open example/macos/example.xcodeproj
$ yarn start:macos
```
The Metro Bundler will now be running in the Terminal for react-native-macos. In XCode select the `example-macos` target and Run.
### Testing in a new `react-native init` project
In a new `react-native init` project, do this:
```

View File

@ -2,7 +2,7 @@
Here's how to get started quickly with the React Native WebView.
#### 1. Add react-native-webview to your dependencies
## 1. Add react-native-webview to your dependencies
```
$ yarn add react-native-webview
@ -14,7 +14,7 @@ $ yarn add react-native-webview
$ npm install --save react-native-webview
```
#### 2. Link native dependencies
## 2. Link native dependencies
From react-native 0.60 autolinking will take care of the link step but don't forget to run `pod install`
@ -24,13 +24,20 @@ React Native modules that include native Objective-C, Swift, Java, or Kotlin cod
$ react-native link react-native-webview
```
iOS:
_NOTE: If you ever need to uninstall React Native WebView, run `react-native unlink react-native-webview` to unlink it._
### iOS:
If using cocoapods in the `ios/` directory run
```
$ pod install
```
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.
If you wish to use cocoapods and haven't set it up yet, please instead refer to [that article](https://engineering.brigad.co/demystifying-react-native-modules-linking-ae6c017a6b4a).
### Android:
Android - react-native-webview version <6:
This module does not require any extra step after running the link command 🎉
@ -44,12 +51,13 @@ android.enableJetifier=true
For Android manual installation, please refer to [this article](https://engineering.brigad.co/demystifying-react-native-modules-linking-964399ec731b) where you can find detailed step on how to link any react-native project.
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.
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).
### macOS:
_NOTE: If you ever need to uninstall React Native WebView, run `react-native unlink react-native-webview` to unlink it._
Cocoapod and autolinking is not yet support for react-native macOS but is coming soon. In the meantime you must manually link.
#### 3. Import the webview into your component
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.
## 3. Import the webview into your component
```js
import React, { Component } from 'react';

View File

@ -474,9 +474,9 @@ Note that this method will not be invoked on hash URL changes (e.g. from `https:
Function that is invoked when the `WebView` content process is terminated.
| Type | Required | Platform |
| -------- | -------- | ------------- |
| function | No | iOS WKWebView |
| Type | Required | Platform |
| -------- | -------- | ----------------------- |
| function | No | iOS and macOS WKWebView |
Example:
@ -863,9 +863,9 @@ Possible values for `dataDetectorTypes` are:
Boolean value that determines whether scrolling is enabled in the `WebView`. The default value is `true`. Setting this to `false` will prevent the webview from moving the document body when the keyboard appears over an input.
| Type | Required | Platform |
| ---- | -------- | -------- |
| bool | No | iOS |
| Type | Required | Platform |
| ---- | -------- | ------------- |
| bool | No | iOS and macOS |
---
@ -934,9 +934,9 @@ Boolean that sets whether JavaScript running in the context of a file scheme URL
A String value that indicates which URLs the WebView's file can then reference in scripts, AJAX requests, and CSS imports. This is only used in for WebViews that are loaded with a source.uri set to a `'file://'` URL. If not provided, the default is to only allow read access to the URL provided in source.uri itself.
| Type | Required | Platform |
| ------ | -------- | -------- |
| string | No | iOS |
| Type | Required | Platform |
| ------ | -------- | ------------- |
| string | No | iOS and macOS |
---
@ -984,9 +984,9 @@ If true, this will hide the keyboard accessory view (< > and Done).
If true, this will be able horizontal swipe gestures. The default value is `false`.
| Type | Required | Platform |
| ------- | -------- | -------- |
| boolean | No | iOS |
| Type | Required | Platform |
| ------- | -------- | ----------------- |
| boolean | No | iOS and macOS |
---
@ -1061,9 +1061,9 @@ If the value of this property is true, the scroll view stops on multiples of the
A Boolean value that determines whether pressing on a link displays a preview of the destination for the link. In iOS this property is available on devices that support 3D Touch. In iOS 10 and later, the default value is true; before that, the default value is false.
| Type | Required | Platform |
| ------- | -------- | -------- |
| boolean | No | iOS |
| Type | Required | Platform |
| ------- | -------- | ----------------- |
| boolean | No | iOS and macOS |
---
@ -1071,9 +1071,9 @@ A Boolean value that determines whether pressing on a link displays a preview of
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)
| Type | Required | Platform |
| ------- | -------- | -------- |
| boolean | No | iOS |
| Type | Required | Platform |
| ------- | -------- | ----------------- |
| boolean | No | iOS and macOS |
---

5
example/.gitignore vendored
View File

@ -20,7 +20,10 @@ DerivedData
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
# exclude project.xcworkspace except for xcshareddata/WorkspaceSettings.xcsettings
project.xcworkspace/*
**/project.xcworkspace/contents.xcworkspacedata
**/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
# Android/IntelliJ
#

View File

@ -182,7 +182,7 @@ PODS:
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsinspector (0.61.5)
- react-native-webview (8.0.4):
- react-native-webview (8.0.6):
- React
- React-RCTActionSheet (0.61.5):
- React-Core/RCTActionSheetHeaders (= 0.61.5)
@ -326,7 +326,7 @@ SPEC CHECKSUMS:
React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
react-native-webview: 3f5aa91c3cb083ea4762e006b9653291a96a777a
react-native-webview: 222d83c9c489e09b5d3541519110a637490ad4fa
React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72

View File

@ -0,0 +1,16 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Cocoa/Cocoa.h>
@class RCTBridge;
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (nonatomic, readonly) RCTBridge *bridge;
@end

View File

@ -0,0 +1,39 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
@interface AppDelegate () <RCTBridgeDelegate>
@end
@implementation AppDelegate
- (void)awakeFromNib {
[super awakeFromNib];
_bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:nil];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
#pragma mark - RCTBridgeDelegate Methods
- (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge {
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"example/index" fallbackResource:@"main"]; // .jsbundle;
}
@end

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 Facebook. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

View File

@ -0,0 +1,713 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="15505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15505"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="rncTesterApp-macOS" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="rncTesterApp-macOS" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About rncTesterApp-macOS" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide rncTesterApp-macOS" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit rncTesterApp-macOS" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
<connections>
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="tXI-mr-wws">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
<items>
<menuItem title="Clear Menu" id="vNY-rz-j42">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
<connections>
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
</connections>
</menuItem>
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
<connections>
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
</connections>
</menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
<connections>
<action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
</connections>
</menuItem>
<menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
<connections>
<action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
</connections>
</menuItem>
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
<connections>
<action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Format" id="jxT-CU-nIS">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
<items>
<menuItem title="Font" id="Gi5-1S-RQB">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
<items>
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
<connections>
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
</connections>
</menuItem>
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
</connections>
</menuItem>
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
</connections>
</menuItem>
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
<connections>
<action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
</connections>
</menuItem>
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
<menuItem title="Kern" id="jBQ-r6-VK2">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
<items>
<menuItem title="Use Default" id="GUa-eO-cwY">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
</connections>
</menuItem>
<menuItem title="Use None" id="cDB-IK-hbR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
</connections>
</menuItem>
<menuItem title="Tighten" id="46P-cB-AYj">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
</connections>
</menuItem>
<menuItem title="Loosen" id="ogc-rX-tC1">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Ligatures" id="o6e-r0-MWq">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
<items>
<menuItem title="Use Default" id="agt-UL-0e3">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
</connections>
</menuItem>
<menuItem title="Use None" id="J7y-lM-qPV">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
</connections>
</menuItem>
<menuItem title="Use All" id="xQD-1f-W4t">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Baseline" id="OaQ-X3-Vso">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
<items>
<menuItem title="Use Default" id="3Om-Ey-2VK">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
</connections>
</menuItem>
<menuItem title="Superscript" id="Rqc-34-cIF">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
</connections>
</menuItem>
<menuItem title="Subscript" id="I0S-gh-46l">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
</connections>
</menuItem>
<menuItem title="Raise" id="2h7-ER-AoG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
</connections>
</menuItem>
<menuItem title="Lower" id="1tx-W0-xDw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
<connections>
<action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
</connections>
</menuItem>
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Text" id="Fal-I4-PZk">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Text" id="d9c-me-L2H">
<items>
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
<connections>
<action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
</connections>
</menuItem>
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
<connections>
<action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
</connections>
</menuItem>
<menuItem title="Justify" id="J5U-5w-g23">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
</connections>
</menuItem>
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
<connections>
<action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
<menuItem title="Writing Direction" id="H1b-Si-o9J">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
<items>
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title=" Default" id="YGs-j5-SAR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
</connections>
</menuItem>
<menuItem title=" Left to Right" id="Lbh-J2-qVU">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
</connections>
</menuItem>
<menuItem title=" Right to Left" id="jFq-tB-4Kx">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title=" Default" id="Nop-cj-93Q">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
</connections>
</menuItem>
<menuItem title=" Left to Right" id="BgM-ve-c93">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
</connections>
</menuItem>
<menuItem title=" Right to Left" id="RB4-Sm-HuC">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
<menuItem title="Show Ruler" id="vLm-3I-IUL">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
</connections>
</menuItem>
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
</connections>
</menuItem>
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
</connections>
</menuItem>
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleSidebar:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
</connections>
</menuItem>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="rncTesterApp-macOS Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="0.0"/>
</scene>
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
<objects>
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
<window key="window" title="example macOS" allowsToolTipsWhenApplicationIsInactive="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<connections>
<outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
</connections>
</window>
<connections>
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
</connections>
</windowController>
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="250"/>
</scene>
<!--View Controller-->
<scene sceneID="hIz-AP-VOD">
<objects>
<viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController">
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
</view>
</viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="655"/>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,12 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Cocoa/Cocoa.h>
@interface ViewController : NSViewController
@end

View File

@ -0,0 +1,29 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "ViewController.h"
#import "AppDelegate.h"
#import <React/RCTRootView.h>
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
RCTBridge *bridge = [((AppDelegate *)[NSApp delegate])bridge];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"example" initialProperties:nil];
NSView *view = [self view];
[view addSubview:rootView];
[rootView setBackgroundColor:[NSColor windowBackgroundColor]];
[rootView setFrame:[view bounds]];
[rootView setAutoresizingMask:(NSViewMinXMargin | NSViewMinXMargin | NSViewMinYMargin | NSViewMaxYMargin | NSViewWidthSizable | NSViewHeightSizable)];
}
@end

View File

@ -0,0 +1,12 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Cocoa/Cocoa.h>
int main(int argc, const char *argv[]) {
return NSApplicationMain(argc, argv);
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1120"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6B857DA21EC51FC600A9D063"
BuildableName = "libReact.a"
BlueprintName = "React-macOS"
ReferencedContainer = "container:../../node_modules/react-native-macos/React/React.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "38C1415723BBE33000902604"
BuildableName = "example-macOS.app"
BlueprintName = "example-macOS"
ReferencedContainer = "container:example.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "38C1415723BBE33000902604"
BuildableName = "example-macOS.app"
BlueprintName = "example-macOS"
ReferencedContainer = "container:example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "38C1415723BBE33000902604"
BuildableName = "example-macOS.app"
BlueprintName = "example-macOS"
ReferencedContainer = "container:example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1120"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
BuildableName = "libReact.a"
BlueprintName = "React"
ReferencedContainer = "container:../../node_modules/react-native-macos/React/React.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "example.app"
BlueprintName = "example"
ReferencedContainer = "container:example.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "example.app"
BlueprintName = "example"
ReferencedContainer = "container:example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "example.app"
BlueprintName = "example"
ReferencedContainer = "container:example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,15 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
@property (nonatomic, strong) UIWindow *window;
@end

View File

@ -0,0 +1,42 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"example"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"example/index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
@end

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<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">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="140" width="441" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>

View File

@ -0,0 +1,53 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>example</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View File

@ -0,0 +1,16 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

View File

@ -9,7 +9,11 @@
#import <React/RCTConvert.h>
#import <React/RCTAutoInsetsProtocol.h>
#import "RNCWKProcessPoolManager.h"
#if !TARGET_OS_OSX
#import <UIKit/UIKit.h>
#else
#import <React/RCTUIKit.h>
#endif // !TARGET_OS_OSX
#import "objc/runtime.h"
@ -19,6 +23,7 @@ static NSString *const MessageHandlerName = @"ReactNativeWebView";
static NSURLCredential* clientAuthenticationCredential;
static NSDictionary* customCertificatesForHost;
#if !TARGET_OS_OSX
// runtime trick to remove WKWebView keyboard default toolbar
// see: http://stackoverflow.com/questions/19033292/ios-7-uiwebview-keyboard-issue/19042279#19042279
@interface _SwizzleHelperWK : UIView
@ -39,8 +44,29 @@ static NSDictionary* customCertificatesForHost;
return nil;
}
@end
#endif // !TARGET_OS_OSX
@interface RNCWebView () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, UIScrollViewDelegate, RCTAutoInsetsProtocol>
#if TARGET_OS_OSX
@interface RNCWKWebView : WKWebView
@end
@implementation RNCWKWebView
- (void)scrollWheel:(NSEvent *)theEvent {
RNCWebView *rncWebView = (RNCWebView *)[self superview];
RCTAssert([rncWebView isKindOfClass:[rncWebView class]], @"superview must be an RNCWebView");
if (![rncWebView scrollEnabled]) {
[[self nextResponder] scrollWheel:theEvent];
return;
}
[super scrollWheel:theEvent];
}
@end
#endif // TARGET_OS_OSX
@interface RNCWebView () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler,
#if !TARGET_OS_OSX
UIScrollViewDelegate,
#endif // !TARGET_OS_OSX
RCTAutoInsetsProtocol>
@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart;
@property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish;
@property (nonatomic, copy) RCTDirectEventBlock onLoadingError;
@ -50,19 +76,29 @@ static NSDictionary* customCertificatesForHost;
@property (nonatomic, copy) RCTDirectEventBlock onMessage;
@property (nonatomic, copy) RCTDirectEventBlock onScroll;
@property (nonatomic, copy) RCTDirectEventBlock onContentProcessDidTerminate;
#if !TARGET_OS_OSX
@property (nonatomic, copy) WKWebView *webView;
#else
@property (nonatomic, copy) RNCWKWebView *webView;
#endif // !TARGET_OS_OSX
@end
@implementation RNCWebView
{
#if !TARGET_OS_OSX
UIColor * _savedBackgroundColor;
#else
RCTUIColor * _savedBackgroundColor;
#endif // !TARGET_OS_OSX
BOOL _savedHideKeyboardAccessoryView;
BOOL _savedKeyboardDisplayRequiresUserAction;
// Workaround for StatusBar appearance bug for iOS 12
// https://github.com/react-native-community/react-native-webview/issues/62
BOOL _isFullScreenVideoOpen;
#if !TARGET_OS_OSX
UIStatusBarStyle _savedStatusBarStyle;
#endif // !TARGET_OS_OSX
BOOL _savedStatusBarHidden;
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
@ -73,7 +109,11 @@ static NSDictionary* customCertificatesForHost;
- (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
#if !TARGET_OS_OSX
super.backgroundColor = [UIColor clearColor];
#else
super.backgroundColor = [RCTUIColor clearColor];
#endif // !TARGET_OS_OSX
_bounces = YES;
_scrollEnabled = YES;
_showsHorizontalScrollIndicator = YES;
@ -82,14 +122,17 @@ static NSDictionary* customCertificatesForHost;
_automaticallyAdjustContentInsets = YES;
_contentInset = UIEdgeInsetsZero;
_savedKeyboardDisplayRequiresUserAction = YES;
#if !TARGET_OS_OSX
_savedStatusBarStyle = RCTSharedApplication().statusBarStyle;
_savedStatusBarHidden = RCTSharedApplication().statusBarHidden;
#endif // !TARGET_OS_OSX
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
_savedContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
#endif
}
#if !TARGET_OS_OSX
if (@available(iOS 12.0, *)) {
// Workaround for a keyboard dismissal bug present in iOS 12
// https://openradar.appspot.com/radar?id=5018321736957952
@ -114,7 +157,7 @@ static NSDictionary* customCertificatesForHost;
name:UIWindowDidBecomeHiddenNotification
object:nil];
}
#endif // !TARGET_OS_OSX
return self;
}
@ -208,6 +251,7 @@ static NSDictionary* customCertificatesForHost;
}
}
#if !TARGET_OS_OSX
wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback;
#if WEBKIT_IOS_10_APIS_AVAILABLE
wkWebViewConfig.mediaTypesRequiringUserActionForPlayback = _mediaPlaybackRequiresUserAction
@ -217,6 +261,7 @@ static NSDictionary* customCertificatesForHost;
#else
wkWebViewConfig.mediaPlaybackRequiresUserAction = _mediaPlaybackRequiresUserAction;
#endif
#endif // !TARGET_OS_OSX
if (_applicationNameForUserAgent) {
wkWebViewConfig.applicationNameForUserAgent = [NSString stringWithFormat:@"%@ %@", wkWebViewConfig.applicationNameForUserAgent, _applicationNameForUserAgent];
@ -291,17 +336,26 @@ static NSDictionary* customCertificatesForHost;
{
if (self.window != nil && _webView == nil) {
WKWebViewConfiguration *wkWebViewConfig = [self setUpWkWebViewConfig];
#if !TARGET_OS_OSX
_webView = [[WKWebView alloc] initWithFrame:self.bounds configuration: wkWebViewConfig];
#else
_webView = [[RNCWKWebView alloc] initWithFrame:self.bounds configuration: wkWebViewConfig];
#endif // !TARGET_OS_OSX
[self setBackgroundColor: _savedBackgroundColor];
#if !TARGET_OS_OSX
_webView.scrollView.delegate = self;
#endif // !TARGET_OS_OSX
_webView.UIDelegate = self;
_webView.navigationDelegate = self;
#if !TARGET_OS_OSX
_webView.scrollView.scrollEnabled = _scrollEnabled;
_webView.scrollView.pagingEnabled = _pagingEnabled;
_webView.scrollView.bounces = _bounces;
_webView.scrollView.showsHorizontalScrollIndicator = _showsHorizontalScrollIndicator;
_webView.scrollView.showsVerticalScrollIndicator = _showsVerticalScrollIndicator;
_webView.scrollView.directionalLockEnabled = _directionalLockEnabled;
#endif // !TARGET_OS_OSX
_webView.allowsLinkPreview = _allowsLinkPreview;
[_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
_webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures;
@ -335,13 +389,16 @@ static NSDictionary* customCertificatesForHost;
[_webView.configuration.userContentController removeScriptMessageHandlerForName:MessageHandlerName];
[_webView removeObserver:self forKeyPath:@"estimatedProgress"];
[_webView removeFromSuperview];
#if !TARGET_OS_OSX
_webView.scrollView.delegate = nil;
#endif // !TARGET_OS_OSX
_webView = nil;
}
[super removeFromSuperview];
}
#if !TARGET_OS_OSX
-(void)showFullScreenVideoStatusBars
{
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@ -389,6 +446,7 @@ static NSDictionary* customCertificatesForHost;
}];
}
}
#endif // !TARGET_OS_OSX
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if ([keyPath isEqual:@"estimatedProgress"] && object == self.webView) {
@ -402,7 +460,11 @@ static NSDictionary* customCertificatesForHost;
}
}
#if !TARGET_OS_OSX
- (void)setBackgroundColor:(UIColor *)backgroundColor
#else
- (void)setBackgroundColor:(RCTUIColor *)backgroundColor
#endif // !TARGET_OS_OSX
{
_savedBackgroundColor = backgroundColor;
if (_webView == nil) {
@ -410,9 +472,20 @@ static NSDictionary* customCertificatesForHost;
}
CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor);
self.opaque = _webView.opaque = (alpha == 1.0);
BOOL opaque = (alpha == 1.0);
#if !TARGET_OS_OSX
self.opaque = _webView.opaque = opaque;
_webView.scrollView.backgroundColor = backgroundColor;
_webView.backgroundColor = backgroundColor;
#else
// https://stackoverflow.com/questions/40007753/macos-wkwebview-background-transparency
NSOperatingSystemVersion version = { 10, 12, 0 };
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version]) {
[_webView setValue:@(opaque) forKey: @"drawsBackground"];
} else {
[_webView setValue:@(!opaque) forKey: @"drawsTransparentBackground"];
}
#endif // !TARGET_OS_OSX
}
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
@ -475,6 +548,7 @@ static NSDictionary* customCertificatesForHost;
}
}
#if !TARGET_OS_OSX
- (void)setContentInset:(UIEdgeInsets)contentInset
{
_contentInset = contentInset;
@ -489,6 +563,7 @@ static NSDictionary* customCertificatesForHost;
withScrollView:_webView.scrollView
updateOffset:YES];
}
#endif // !TARGET_OS_OSX
- (void)visitSource
{
@ -525,6 +600,7 @@ static NSDictionary* customCertificatesForHost;
}
}
#if !TARGET_OS_OSX
-(void)setKeyboardDisplayRequiresUserAction:(BOOL)keyboardDisplayRequiresUserAction
{
if (_webView == nil) {
@ -630,17 +706,23 @@ static NSDictionary* customCertificatesForHost;
object_setClass(subview, newClass);
}
// UIScrollViewDelegate method
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
scrollView.decelerationRate = _decelerationRate;
}
#endif // !TARGET_OS_OSX
- (void)setScrollEnabled:(BOOL)scrollEnabled
{
_scrollEnabled = scrollEnabled;
#if !TARGET_OS_OSX
_webView.scrollView.scrollEnabled = scrollEnabled;
#endif // !TARGET_OS_OSX
}
#if !TARGET_OS_OSX
// UIScrollViewDelegate method
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Don't allow scrolling the scrollView.
@ -690,6 +772,7 @@ static NSDictionary* customCertificatesForHost;
_showsVerticalScrollIndicator = showsVerticalScrollIndicator;
_webView.scrollView.showsVerticalScrollIndicator = showsVerticalScrollIndicator;
}
#endif // !TARGET_OS_OSX
- (void)postMessage:(NSString *)message
{
@ -707,7 +790,9 @@ static NSDictionary* customCertificatesForHost;
// Ensure webview takes the position and dimensions of RNCWebView
_webView.frame = self.bounds;
#if !TARGET_OS_OSX
_webView.scrollView.contentInset = _contentInset;
#endif // !TARGET_OS_OSX
}
- (NSMutableDictionary<NSString *, id> *)baseEvent
@ -769,52 +854,95 @@ static NSDictionary* customCertificatesForHost;
#pragma mark - WKNavigationDelegate methods
/**
* alert
*/
* alert
*/
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler();
}]];
[[self topViewController] presentViewController:alert animated:YES completion:NULL];
#if !TARGET_OS_OSX
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler();
}]];
[[self topViewController] presentViewController:alert animated:YES completion:NULL];
#else
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:message];
[alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:^(__unused NSModalResponse response){
completionHandler();
}];
#endif // !TARGET_OS_OSX
}
/**
* confirm
*/
* confirm
*/
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler(YES);
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler(NO);
}]];
[[self topViewController] presentViewController:alert animated:YES completion:NULL];
#if !TARGET_OS_OSX
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler(YES);
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler(NO);
}]];
[[self topViewController] presentViewController:alert animated:YES completion:NULL];
#else
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:message];
[alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button")];
[alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel button")];
void (^callbacksHandlers)(NSModalResponse response) = ^void(NSModalResponse response) {
completionHandler(response == NSAlertFirstButtonReturn);
};
[alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:callbacksHandlers];
#endif // !TARGET_OS_OSX
}
/**
* prompt
*/
* prompt
*/
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:prompt preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.text = defaultText;
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler([[alert.textFields lastObject] text]);
}];
[alert addAction:okAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler(nil);
}];
[alert addAction:cancelAction];
alert.preferredAction = okAction;
[[self topViewController] presentViewController:alert animated:YES completion:NULL];
#if !TARGET_OS_OSX
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:prompt preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.text = defaultText;
}];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler([[alert.textFields lastObject] text]);
}];
[alert addAction:okAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler(nil);
}];
[alert addAction:cancelAction];
alert.preferredAction = okAction;
[[self topViewController] presentViewController:alert animated:YES completion:NULL];
#else
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:prompt];
const NSRect RCTSingleTextFieldFrame = NSMakeRect(0.0, 0.0, 275.0, 22.0);
NSTextField *textField = [[NSTextField alloc] initWithFrame:RCTSingleTextFieldFrame];
textField.cell.scrollable = YES;
if (@available(macOS 10.11, *)) {
textField.maximumNumberOfLines = 1;
}
textField.stringValue = defaultText;
[alert setAccessoryView:textField];
[alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button")];
[alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel button")];
[alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:^(NSModalResponse response) {
if (response == NSAlertFirstButtonReturn) {
completionHandler([textField stringValue]);
} else {
completionHandler(nil);
}
}];
#endif // !TARGET_OS_OSX
}
#if !TARGET_OS_OSX
/**
* topViewController
*/
@ -853,7 +981,7 @@ static NSDictionary* customCertificatesForHost;
}
return window;
}
#endif // !TARGET_OS_OSX
/**
* Decides whether to allow or cancel a navigation.
@ -1058,11 +1186,13 @@ static NSDictionary* customCertificatesForHost;
[_webView stopLoading];
}
#if !TARGET_OS_OSX
- (void)setBounces:(BOOL)bounces
{
_bounces = bounces;
_webView.scrollView.bounces = bounces;
}
#endif // !TARGET_OS_OSX
- (NSURLRequest *)requestForSource:(id)json {
NSURLRequest *request = [RCTConvert NSURLRequest:self.source];

View File

@ -22,7 +22,11 @@
RCT_EXPORT_MODULE()
#if !TARGET_OS_OSX
- (UIView *)view
#else
- (RCTUIView *)view
#endif // !TARGET_OS_OSX
{
RNCWebView *webView = [RNCWebView new];
webView.delegate = self;
@ -97,9 +101,11 @@ RCT_CUSTOM_VIEW_PROPERTY(sharedCookiesEnabled, BOOL, RNCWebView) {
view.sharedCookiesEnabled = json == nil ? false : [RCTConvert BOOL: json];
}
#if !TARGET_OS_OSX
RCT_CUSTOM_VIEW_PROPERTY(decelerationRate, CGFloat, RNCWebView) {
view.decelerationRate = json == nil ? UIScrollViewDecelerationRateNormal : [RCTConvert CGFloat: json];
}
#endif // !TARGET_OS_OSX
RCT_CUSTOM_VIEW_PROPERTY(directionalLockEnabled, BOOL, RNCWebView) {
view.directionalLockEnabled = json == nil ? true : [RCTConvert BOOL: json];

View File

@ -0,0 +1,363 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
3515965E21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3515965D21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m */; };
38116A2B23BBECB700ACE311 /* ../ios/RNCWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351B21446E6C00F9801F /* ../ios/RNCWebViewManager.m */; };
38116A2C23BBECB700ACE311 /* ../ios/RNCWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351C21446E6C00F9801F /* ../ios/RNCWebView.m */; };
38116A2D23BBECB700ACE311 /* ../ios/RNCWKProcessPoolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3515965D21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m */; };
E91B351D21446E6C00F9801F /* ../ios/RNCWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351B21446E6C00F9801F /* ../ios/RNCWebViewManager.m */; };
E91B351E21446E6C00F9801F /* ../ios/RNCWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351C21446E6C00F9801F /* ../ios/RNCWebView.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
38116A2F23BBECB700ACE311 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
58B511D91A9E6C8500147676 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libRNCWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCWebView.a; sourceTree = BUILT_PRODUCTS_DIR; };
3515965D21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ../ios/RNCWKProcessPoolManager.m; sourceTree = "<group>"; };
3515965F21A3C87E00623BFA /* ../ios/RNCWKProcessPoolManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ../ios/RNCWKProcessPoolManager.h; sourceTree = "<group>"; };
38116A3323BBECB700ACE311 /* libRNCWebView-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRNCWebView-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
E91B351921446E6C00F9801F /* ../ios/RNCWebViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ../ios/RNCWebViewManager.h; sourceTree = "<group>"; };
E91B351A21446E6C00F9801F /* ../ios/RNCWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ../ios/RNCWebView.h; sourceTree = "<group>"; };
E91B351B21446E6C00F9801F /* ../ios/RNCWebViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ../ios/RNCWebViewManager.m; sourceTree = "<group>"; };
E91B351C21446E6C00F9801F /* ../ios/RNCWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ../ios/RNCWebView.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
38116A2E23BBECB700ACE311 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
58B511D81A9E6C8500147676 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
134814211AA4EA7D00B7C361 /* Products */ = {
isa = PBXGroup;
children = (
134814201AA4EA6300B7C361 /* libRNCWebView.a */,
);
name = Products;
sourceTree = "<group>";
};
58B511D21A9E6C8500147676 = {
isa = PBXGroup;
children = (
E91B351A21446E6C00F9801F /* ../ios/RNCWebView.h */,
E91B351C21446E6C00F9801F /* ../ios/RNCWebView.m */,
E91B351921446E6C00F9801F /* ../ios/RNCWebViewManager.h */,
E91B351B21446E6C00F9801F /* ../ios/RNCWebViewManager.m */,
3515965D21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m */,
3515965F21A3C87E00623BFA /* ../ios/RNCWKProcessPoolManager.h */,
134814211AA4EA7D00B7C361 /* Products */,
38116A3323BBECB700ACE311 /* libRNCWebView-macOS.a */,
);
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
38116A2923BBECB700ACE311 /* RNCWebView-macOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 38116A3023BBECB700ACE311 /* Build configuration list for PBXNativeTarget "RNCWebView-macOS" */;
buildPhases = (
38116A2A23BBECB700ACE311 /* Sources */,
38116A2E23BBECB700ACE311 /* Frameworks */,
38116A2F23BBECB700ACE311 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = "RNCWebView-macOS";
productName = RCTDataManager;
productReference = 38116A3323BBECB700ACE311 /* libRNCWebView-macOS.a */;
productType = "com.apple.product-type.library.static";
};
58B511DA1A9E6C8500147676 /* RNCWebView */ = {
isa = PBXNativeTarget;
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCWebView" */;
buildPhases = (
58B511D71A9E6C8500147676 /* Sources */,
58B511D81A9E6C8500147676 /* Frameworks */,
58B511D91A9E6C8500147676 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = RNCWebView;
productName = RCTDataManager;
productReference = 134814201AA4EA6300B7C361 /* libRNCWebView.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
58B511D31A9E6C8500147676 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0830;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
58B511DA1A9E6C8500147676 = {
CreatedOnToolsVersion = 6.1.1;
};
};
};
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCWebView" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 58B511D21A9E6C8500147676;
productRefGroup = 58B511D21A9E6C8500147676;
projectDirPath = "";
projectRoot = "";
targets = (
58B511DA1A9E6C8500147676 /* RNCWebView */,
38116A2923BBECB700ACE311 /* RNCWebView-macOS */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
38116A2A23BBECB700ACE311 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
38116A2B23BBECB700ACE311 /* ../ios/RNCWebViewManager.m in Sources */,
38116A2C23BBECB700ACE311 /* ../ios/RNCWebView.m in Sources */,
38116A2D23BBECB700ACE311 /* ../ios/RNCWKProcessPoolManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
58B511D71A9E6C8500147676 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E91B351D21446E6C00F9801F /* ../ios/RNCWebViewManager.m in Sources */,
E91B351E21446E6C00F9801F /* ../ios/RNCWebView.m in Sources */,
3515965E21A3C86000623BFA /* ../ios/RNCWKProcessPoolManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
38116A3123BBECB700ACE311 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native-macos/React/**";
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../node_modules/react-native-macos/React/**",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
MACOSX_DEPLOYMENT_TARGET = 10.14;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
};
name = Debug;
};
38116A3223BBECB700ACE311 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native-macos/React/**";
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../node_modules/react-native-macos/React/**",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
MACOSX_DEPLOYMENT_TARGET = 10.14;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
};
name = Release;
};
58B511ED1A9E6C8500147676 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
58B511EE1A9E6C8500147676 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
58B511F01A9E6C8500147676 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native-macos/React/**";
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../node_modules/react-native-macos/React/**",
"$(SRCROOT)/../../react-native-macos/React/**",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RNCWebView;
SKIP_INSTALL = YES;
};
name = Debug;
};
58B511F11A9E6C8500147676 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native-macos/React/**";
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../node_modules/react-native-macos/React/**",
"$(SRCROOT)/../../react-native-macos/React/**",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RNCWebView;
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
38116A3023BBECB700ACE311 /* Build configuration list for PBXNativeTarget "RNCWebView-macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
38116A3123BBECB700ACE311 /* Debug */,
38116A3223BBECB700ACE311 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCWebView" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511ED1A9E6C8500147676 /* Debug */,
58B511EE1A9E6C8500147676 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCWebView" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511F01A9E6C8500147676 /* Debug */,
58B511F11A9E6C8500147676 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 58B511D31A9E6C8500147676 /* Project object */;
}

12
metro.config.js Normal file
View File

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

19
metro.config.macos.js Normal file
View File

@ -0,0 +1,19 @@
/**
* This cli config is needed for development purposes, e.g. for running
* integration tests during local development or on CI services.
*/
const path = require('path');
const blacklist = require('metro-config/src/defaults/blacklist');
const rnmPath = path.resolve(__dirname, 'node_modules/react-native-macos');
module.exports = {
resolver: {
extraNodeModules: {
'react-native': rnmPath,
},
platforms: ['macos', 'ios', 'android'],
blacklistRE: blacklist([/node_modules\/react-native\/.*/])
},
};

View File

@ -1,6 +1,6 @@
{
"name": "react-native-webview",
"description": "React Native WebView component for iOS, Android, and Windows 10 (coming soon)",
"description": "React Native WebView component for iOS, Android, and macOS",
"main": "index.js",
"typings": "index.d.ts",
"author": "Jamon Holmgren <jamon@infinite.red>",
@ -14,6 +14,7 @@
"start": "node node_modules/react-native/local-cli/cli.js start",
"start:android": "react-native run-android --root example/",
"start:ios": "react-native run-ios --project-path example/ios --scheme example",
"start:macos": "node node_modules/react-native-macos/local-cli/cli.js start --use-react-native-macos",
"ci": "CI=true && yarn lint && yarn test",
"ci:publish": "yarn semantic-release",
"lint": "yarn tsc --noEmit && yarn eslint ./src --ext .ts,.tsx",
@ -36,6 +37,8 @@
"devDependencies": {
"@babel/core": "7.4.5",
"@babel/runtime": "7.4.5",
"@react-native-community/cli-platform-ios": "^3.0.0",
"@react-native-community/cli-platform-android": "^3.0.0",
"@semantic-release/git": "7.0.16",
"@types/invariant": "^2.2.30",
"@types/jest": "24.0.18",
@ -57,6 +60,7 @@
"metro-react-native-babel-preset": "0.54.1",
"react": "16.9.0",
"react-native": "0.61.5",
"react-native-macos": "0.60.0-microsoft.49",
"semantic-release": "15.13.24",
"typescript": "3.6.2"
},
@ -67,6 +71,7 @@
"files": [
"android",
"ios",
"macos",
"lib",
"index.js",
"index.d.ts",

26
react-native.config.js Normal file
View File

@ -0,0 +1,26 @@
/**
* This cli config is needed for the coexistance of react-native and other
* out-of-tree implementations such react-native-macos.
* The following issue is tracked by
* https://github.com/react-native-community/discussions-and-proposals/issues/182
*
* The work-around involves having a metro.config.js for each out-of-tree
* platform, i.e. metro.config.js for react-native and
* metro.config.macos.js for react-native-macos.
* This react-native.config.js looks for a --use-react-native-macos
* switch and when present pushes --config=metro.config.macos.js
* and specifies reactNativePath: 'node_modules/react-native-macos'.
* The metro.config.js has to blacklist 'node_modules/react-native-macos',
* and conversely metro.config.macos.js has to blacklist 'node_modules/react-native'.
*/
'use strict';
const macSwitch = '--use-react-native-macos';
if (process.argv.includes(macSwitch)) {
process.argv = process.argv.filter(arg => arg !== macSwitch);
process.argv.push('--config=metro.config.macos.js');
module.exports = {
reactNativePath: 'node_modules/react-native-macos',
};
}

347
src/WebView.macos.tsx Normal file
View File

@ -0,0 +1,347 @@
import React from 'react';
import {
UIManager as NotTypedUIManager,
View,
requireNativeComponent,
NativeModules,
Image,
findNodeHandle,
ImageSourcePropType,
} from 'react-native';
import invariant from 'invariant';
import {
defaultOriginWhitelist,
createOnShouldStartLoadWithRequest,
defaultRenderError,
defaultRenderLoading,
} from './WebViewShared';
import {
WebViewErrorEvent,
WebViewHttpErrorEvent,
WebViewMessageEvent,
WebViewNavigationEvent,
WebViewProgressEvent,
WebViewTerminatedEvent,
MacOSWebViewProps,
NativeWebViewMacOS,
ViewManager,
State,
RNCWebViewUIManagerMacOS,
} from './WebViewTypes';
import styles from './WebView.styles';
const UIManager = NotTypedUIManager as RNCWebViewUIManagerMacOS;
const { resolveAssetSource } = Image;
const RNCWebViewManager = NativeModules.RNCWebViewManager as ViewManager;
const RNCWebView: typeof NativeWebViewMacOS = requireNativeComponent(
'RNCWebView',
);
class WebView extends React.Component<MacOSWebViewProps, State> {
static defaultProps = {
javaScriptEnabled: true,
cacheEnabled: true,
originWhitelist: defaultOriginWhitelist,
useSharedProcessPool: true,
};
static isFileUploadSupported = async () => {
// no native implementation for macOS, depends only on permissions
return true;
};
state: State = {
viewState: this.props.startInLoadingState ? 'LOADING' : 'IDLE',
lastErrorEvent: null,
};
webViewRef = React.createRef<NativeWebViewMacOS>();
// eslint-disable-next-line react/sort-comp
getCommands = () => UIManager.getViewManagerConfig('RNCWebView').Commands;
/**
* Go forward one page in the web view's history.
*/
goForward = () => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
this.getCommands().goForward,
undefined,
);
};
/**
* Go back one page in the web view's history.
*/
goBack = () => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
this.getCommands().goBack,
undefined,
);
};
/**
* Reloads the current page.
*/
reload = () => {
this.setState({ viewState: 'LOADING' });
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
this.getCommands().reload,
undefined,
);
};
/**
* Stop loading the current page.
*/
stopLoading = () => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
this.getCommands().stopLoading,
undefined,
);
};
/**
* Request focus on WebView rendered page.
*/
requestFocus = () => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
this.getCommands().requestFocus,
undefined,
);
};
/**
* Posts a message to the web view, which will emit a `message` event.
* Accepts one argument, `data`, which must be a string.
*
* In your webview, you'll need to something like the following.
*
* ```js
* document.addEventListener('message', e => { document.title = e.data; });
* ```
*/
postMessage = (data: string) => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
this.getCommands().postMessage,
[String(data)],
);
};
/**
* Injects a javascript string into the referenced WebView. Deliberately does not
* return a response because using eval() to return a response breaks this method
* on pages with a Content Security Policy that disallows eval(). If you need that
* functionality, look into postMessage/onMessage.
*/
injectJavaScript = (data: string) => {
UIManager.dispatchViewManagerCommand(
this.getWebViewHandle(),
this.getCommands().injectJavaScript,
[data],
);
};
/**
* We return an event with a bunch of fields including:
* url, title, loading, canGoBack, canGoForward
*/
updateNavigationState = (event: WebViewNavigationEvent) => {
if (this.props.onNavigationStateChange) {
this.props.onNavigationStateChange(event.nativeEvent);
}
};
/**
* Returns the native `WebView` node.
*/
getWebViewHandle = () => {
const nodeHandle = findNodeHandle(this.webViewRef.current);
invariant(nodeHandle != null, 'nodeHandle expected to be non-null');
return nodeHandle as number;
};
onLoadingStart = (event: WebViewNavigationEvent) => {
const { onLoadStart } = this.props;
if (onLoadStart) {
onLoadStart(event);
}
this.updateNavigationState(event);
};
onLoadingError = (event: WebViewErrorEvent) => {
event.persist(); // persist this event because we need to store it
const { onError, onLoadEnd } = this.props;
if (onLoadEnd) {
onLoadEnd(event);
}
if (onError) {
onError(event);
}
console.warn('Encountered an error loading page', event.nativeEvent);
this.setState({
lastErrorEvent: event.nativeEvent,
viewState: 'ERROR',
});
};
onHttpError = (event: WebViewHttpErrorEvent) => {
const { onHttpError } = this.props;
if (onHttpError) {
onHttpError(event);
}
}
onLoadingFinish = (event: WebViewNavigationEvent) => {
const { onLoad, onLoadEnd } = this.props;
if (onLoad) {
onLoad(event);
}
if (onLoadEnd) {
onLoadEnd(event);
}
this.setState({
viewState: 'IDLE',
});
this.updateNavigationState(event);
};
onMessage = (event: WebViewMessageEvent) => {
const { onMessage } = this.props;
if (onMessage) {
onMessage(event);
}
};
onLoadingProgress = (event: WebViewProgressEvent) => {
const { onLoadProgress } = this.props;
if (onLoadProgress) {
onLoadProgress(event);
}
};
onShouldStartLoadWithRequestCallback = (
shouldStart: boolean,
_url: string,
lockIdentifier: number,
) => {
const viewManager
= (this.props.nativeConfig && this.props.nativeConfig.viewManager)
|| RNCWebViewManager;
viewManager.startLoadWithResult(!!shouldStart, lockIdentifier);
};
onContentProcessDidTerminate = (event: WebViewTerminatedEvent) => {
const { onContentProcessDidTerminate } = this.props;
if (onContentProcessDidTerminate) {
onContentProcessDidTerminate(event);
}
};
componentDidUpdate(prevProps: MacOSWebViewProps) {
this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback');
this.showRedboxOnPropChanges(prevProps, 'incognito');
this.showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction');
}
showRedboxOnPropChanges(
prevProps: MacOSWebViewProps,
propName: keyof MacOSWebViewProps,
) {
if (this.props[propName] !== prevProps[propName]) {
console.error(
`Changes to property ${propName} do nothing after the initial render.`,
);
}
}
render() {
const {
nativeConfig = {},
onMessage,
onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
originWhitelist,
renderError,
renderLoading,
style,
containerStyle,
...otherProps
} = this.props;
let otherView = null;
if (this.state.viewState === 'LOADING') {
otherView = (renderLoading || defaultRenderLoading)();
} else if (this.state.viewState === 'ERROR') {
const errorEvent = this.state.lastErrorEvent;
invariant(errorEvent != null, 'lastErrorEvent expected to be non-null');
otherView = (renderError || defaultRenderError)(
errorEvent.domain,
errorEvent.code,
errorEvent.description,
);
} else if (this.state.viewState !== 'IDLE') {
console.error(
`RNCWebView invalid state encountered: ${this.state.viewState}`,
);
}
const webViewStyles = [styles.container, styles.webView, style];
const webViewContainerStyle = [styles.container, containerStyle];
const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
this.onShouldStartLoadWithRequestCallback,
// casting cause it's in the default props
originWhitelist as readonly string[],
onShouldStartLoadWithRequestProp,
);
const NativeWebView
= (nativeConfig.component as typeof NativeWebViewMacOS | undefined)
|| RNCWebView;
const webView = (
<NativeWebView
key="webViewKey"
{...otherProps}
messagingEnabled={typeof onMessage === 'function'}
onLoadingError={this.onLoadingError}
onLoadingFinish={this.onLoadingFinish}
onLoadingProgress={this.onLoadingProgress}
onLoadingStart={this.onLoadingStart}
onHttpError={this.onHttpError}
onMessage={this.onMessage}
onScroll={this.props.onScroll}
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
onContentProcessDidTerminate={this.onContentProcessDidTerminate}
ref={this.webViewRef}
// TODO: find a better way to type this.
source={resolveAssetSource(this.props.source as ImageSourcePropType)}
style={webViewStyles}
{...nativeConfig.props}
/>
);
return (
<View style={webViewContainerStyle}>
{webView}
{otherView}
</View>
);
}
}
export default WebView;

View File

@ -28,7 +28,7 @@ interface RNCWebViewUIManager<Commands extends string> extends UIManagerStatic {
export type RNCWebViewUIManagerAndroid = RNCWebViewUIManager<WebViewCommands | AndroidWebViewCommands>
export type RNCWebViewUIManagerIOS = RNCWebViewUIManager<WebViewCommands>
export type RNCWebViewUIManagerMacOS = RNCWebViewUIManager<WebViewCommands>
type WebViewState = 'IDLE' | 'LOADING' | 'ERROR';
@ -57,6 +57,14 @@ declare const NativeWebViewIOSBase: Constructor<NativeMethodsMixin> &
typeof NativeWebViewIOSComponent;
export class NativeWebViewIOS extends NativeWebViewIOSBase {}
// eslint-disable-next-line react/prefer-stateless-function
declare class NativeWebViewMacOSComponent extends Component<
MacOSNativeWebViewProps
> {}
declare const NativeWebViewMacOSBase: Constructor<NativeMethodsMixin> &
typeof NativeWebViewMacOSComponent;
export class NativeWebViewMacOS extends NativeWebViewMacOSBase {}
// eslint-disable-next-line react/prefer-stateless-function
declare class NativeWebViewAndroidComponent extends Component<
AndroidNativeWebViewProps
@ -104,7 +112,7 @@ export interface WebViewMessage extends WebViewNativeEvent {
export interface WebViewError extends WebViewNativeEvent {
/**
* `domain` is only used on iOS
* `domain` is only used on iOS and macOS
*/
domain?: string;
code: number;
@ -195,7 +203,7 @@ export interface WebViewNativeConfig {
/**
* The native component used to render the WebView.
*/
component?: typeof NativeWebViewIOS | typeof NativeWebViewAndroid;
component?: typeof NativeWebViewIOS | typeof NativeWebViewMacOS | typeof NativeWebViewAndroid;
/**
* Set props directly on the native component WebView. Enables custom props which the
* original WebView doesn't pass through.
@ -203,7 +211,7 @@ export interface WebViewNativeConfig {
props?: Object;
/**
* Set the ViewManager to use for communication with the native side.
* @platform ios
* @platform ios, macos
*/
viewManager?: ViewManager;
}
@ -258,6 +266,13 @@ export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps {
urlPrefixesForDefaultIntent?: readonly string[];
}
export enum ContentInsetAdjustmentBehavior {
automatic = 'automatic',
scrollableAxes = 'scrollableAxes',
never = 'never',
always = 'always'
};
export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
allowingReadAccessToURL?: string;
allowsBackForwardNavigationGestures?: boolean;
@ -266,11 +281,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
automaticallyAdjustContentInsets?: boolean;
bounces?: boolean;
contentInset?: ContentInsetProp;
contentInsetAdjustmentBehavior?:
| 'automatic'
| 'scrollableAxes'
| 'never'
| 'always';
contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
dataDetectorTypes?: DataDetectorTypes | readonly DataDetectorTypes[];
decelerationRate?: number;
directionalLockEnabled?: boolean;
@ -281,6 +292,23 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
}
export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps {
allowingReadAccessToURL?: string;
allowsBackForwardNavigationGestures?: boolean;
allowsInlineMediaPlayback?: boolean;
allowsLinkPreview?: boolean;
automaticallyAdjustContentInsets?: boolean;
bounces?: boolean;
contentInset?: ContentInsetProp;
contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
directionalLockEnabled?: boolean;
hideKeyboardAccessoryView?: boolean;
pagingEnabled?: boolean;
scrollEnabled?: boolean;
useSharedProcessPool?: boolean;
onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
}
export interface IOSWebViewProps extends WebViewSharedProps {
/**
* Does not store any data within the lifetime of the WebView.
@ -335,11 +363,7 @@ export interface IOSWebViewProps extends WebViewSharedProps {
* content area of the scroll view. The default value of this property is
* "never". Available on iOS 11 and later.
*/
contentInsetAdjustmentBehavior?:
| 'automatic'
| 'scrollableAxes'
| 'never'
| 'always';
contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
/**
* The amount by which the web view content is inset from the edges of
@ -460,6 +484,143 @@ export interface IOSWebViewProps extends WebViewSharedProps {
onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
}
export interface MacOSWebViewProps extends WebViewSharedProps {
/**
* Does not store any data within the lifetime of the WebView.
*/
incognito?: boolean;
/**
* Boolean value that determines whether the web view bounces
* when it reaches the edge of the content. The default value is `true`.
* @platform macos
*/
bounces?: boolean;
/**
* Boolean value that determines whether scrolling is enabled in the
* `WebView`. The default value is `true`.
* @platform macos
*/
scrollEnabled?: boolean;
/**
* If the value of this property is true, the scroll view stops on multiples
* of the scroll views bounds when the user scrolls.
* The default value is false.
* @platform macos
*/
pagingEnabled?: boolean;
/**
* Controls whether to adjust the content inset for web views that are
* placed behind a navigation bar, tab bar, or toolbar. The default value
* is `true`.
* @platform macos
*/
automaticallyAdjustContentInsets?: boolean;
/**
* This property specifies how the safe area insets are used to modify the
* content area of the scroll view. The default value of this property is
* "never". Available on iOS 11 and later.
*/
contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
/**
* The amount by which the web view content is inset from the edges of
* the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.
* @platform macos
*/
contentInset?: ContentInsetProp;
/**
* Boolean that determines whether HTML5 videos play inline or use the
* native full-screen controller. The default value is `false`.
*
* **NOTE** : In order for video to play inline, not only does this
* property need to be set to `true`, but the video element in the HTML
* document must also include the `webkit-playsinline` attribute.
* @platform macos
*/
allowsInlineMediaPlayback?: boolean;
/**
* Hide the accessory view when the keyboard is open. Default is false to be
* backward compatible.
*/
hideKeyboardAccessoryView?: boolean;
/**
* A Boolean value indicating whether horizontal swipe gestures will trigger
* back-forward list navigations.
*/
allowsBackForwardNavigationGestures?: boolean;
/**
* A Boolean value indicating whether WebKit WebView should be created using a shared
* process pool, enabling WebViews to share cookies and localStorage between each other.
* Default is true but can be set to false for backwards compatibility.
* @platform macos
*/
useSharedProcessPool?: boolean;
/**
* The custom user agent string.
*/
userAgent?: string;
/**
* A Boolean value that determines whether pressing on a link
* displays a preview of the destination for the link.
*
* This property is available on devices that support Force Touch trackpad.
* @platform macos
*/
allowsLinkPreview?: boolean;
/**
* Set true if shared cookies from HTTPCookieStorage should used for every load request.
* The default value is `false`.
* @platform macos
*/
sharedCookiesEnabled?: boolean;
/**
* A Boolean value that determines whether scrolling is disabled in a particular direction.
* The default value is `true`.
* @platform macos
*/
directionalLockEnabled?: boolean;
/**
* A Boolean value indicating whether web content can programmatically display the keyboard.
*
* When this property is set to true, the user must explicitly tap the elements in the
* web view to display the keyboard (or other relevant input view) for that element.
* When set to false, a focus event on an element causes the input view to be displayed
* and associated with that element automatically.
*
* The default value is `true`.
* @platform macos
*/
keyboardDisplayRequiresUserAction?: boolean;
/**
* 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
* 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.
* @platform macos
*/
allowingReadAccessToURL?: string;
/**
* Function that is invoked when the WebKit WebView content process gets terminated.
* @platform macos
*/
onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
}
export interface AndroidWebViewProps extends WebViewSharedProps {
onNavigationStateChange?: (event: WebViewNavigation) => void;
onContentSizeChange?: (event: WebViewEvent) => void;

319
yarn.lock
View File

@ -699,7 +699,14 @@
dependencies:
regenerator-runtime "^0.13.2"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.4.5":
"@babel/runtime@^7.0.0":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.3.tgz#0811944f73a6c926bb2ad35e918dcc1bfab279f1"
integrity sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==
dependencies:
regenerator-runtime "^0.13.2"
"@babel/runtime@^7.4.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
@ -1035,6 +1042,19 @@
dependencies:
serve-static "^1.13.1"
"@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0":
version "2.9.0"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e"
integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag==
dependencies:
"@react-native-community/cli-tools" "^2.8.3"
chalk "^2.4.2"
execa "^1.0.0"
jetifier "^1.6.2"
logkitty "^0.6.0"
slash "^3.0.0"
xmldoc "^1.1.2"
"@react-native-community/cli-platform-android@^3.0.0":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.3.tgz#e652abce79a7c1e3a8280228123e99df2c4b97b6"
@ -1048,6 +1068,15 @@
slash "^3.0.0"
xmldoc "^1.1.2"
"@react-native-community/cli-platform-ios@^2.10.0", "@react-native-community/cli-platform-ios@^2.4.1":
version "2.10.0"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.10.0.tgz#ee494d2f9a8f8727bd5eb3c446f22ebb5429b624"
integrity sha512-z5BQKyT/bgTSdHhvsFNf++6VP50vtOOaITnNKvw4954wURjv5JOQh1De3BngyaDOoGfV1mXkCxutqAXqSeuIjw==
dependencies:
"@react-native-community/cli-tools" "^2.8.3"
chalk "^2.4.2"
xcode "^2.0.0"
"@react-native-community/cli-platform-ios@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0.tgz#3a48a449c0c33af3b0b3d19d3256de99388fe15f"
@ -1058,6 +1087,16 @@
js-yaml "^3.13.1"
xcode "^2.0.0"
"@react-native-community/cli-tools@^2.8.3":
version "2.8.3"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-2.8.3.tgz#0e2249f48cf4603fb8d740a9f0715c31ac131ceb"
integrity sha512-N5Pz+pR+GFq3JApjd0SW4jp9KC7kbKsMH65QLRh30JNsxdPvNkYox6/ZZdkvdXaI5ev3EckR7eqlcwi5gpVTYQ==
dependencies:
chalk "^2.4.2"
lodash "^4.17.5"
mime "^2.4.1"
node-fetch "^2.5.0"
"@react-native-community/cli-tools@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-3.0.0.tgz#fe48b80822ed7e49b8af051f9fe41e22a2a710b1"
@ -1073,6 +1112,45 @@
resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0.tgz#488d46605cb05e88537e030f38da236eeda74652"
integrity sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg==
"@react-native-community/cli@^2.6.0":
version "2.10.0"
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.10.0.tgz#3bda7a77dadfde006d81ee835263b5ff88f1b590"
integrity sha512-KldnMwYzNJlbbJpJQ4AxwTMp89qqwilI1lEvCAwKmiviWuyYGACCQsXI7ikShRaQeakc28zyN2ldbkbrHeOoJA==
dependencies:
"@hapi/joi" "^15.0.3"
"@react-native-community/cli-platform-android" "^2.9.0"
"@react-native-community/cli-platform-ios" "^2.10.0"
"@react-native-community/cli-tools" "^2.8.3"
chalk "^2.4.2"
commander "^2.19.0"
compression "^1.7.1"
connect "^3.6.5"
cosmiconfig "^5.1.0"
deepmerge "^3.2.0"
envinfo "^7.1.0"
errorhandler "^1.5.0"
execa "^1.0.0"
fs-extra "^7.0.1"
glob "^7.1.1"
graceful-fs "^4.1.3"
inquirer "^3.0.6"
lodash "^4.17.5"
metro "^0.54.1"
metro-config "^0.54.1"
metro-core "^0.54.1"
metro-react-native-babel-transformer "^0.54.1"
minimist "^1.2.0"
mkdirp "^0.5.1"
morgan "^1.9.0"
node-notifier "^5.2.1"
open "^6.2.0"
ora "^3.4.0"
plist "^3.0.0"
semver "^5.0.3"
serve-static "^1.13.1"
shell-quote "1.6.1"
ws "^1.1.0"
"@react-native-community/cli@^3.0.0":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.4.tgz#a9dba1bc77855a6e45fccaabb017360645d936bb"
@ -4169,6 +4247,11 @@ hermes-engine@^0.2.1:
resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2"
integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ==
hermesvm@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.1.tgz#bd1df92b4dc504e261c23df34864daf24b844d03"
integrity sha512-EosSDeUqTTGvlc9vQiy5Y/9GBlucEyo6lYuxg/FnukHCD/CP3NYeDAGV54TyZ19FgSqMEoPgOH9cyxvv8epQ1g==
hook-std@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/hook-std/-/hook-std-2.0.0.tgz#ff9aafdebb6a989a354f729bb6445cf4a3a7077c"
@ -5190,7 +5273,7 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jsc-android@^245459.0.0:
jsc-android@245459.0.0, jsc-android@^245459.0.0:
version "245459.0.0"
resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9"
integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg==
@ -5902,6 +5985,24 @@ merge2@^1.2.3:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.4.tgz#c9269589e6885a60cf80605d9522d4b67ca646e3"
integrity sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A==
metro-babel-register@0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.54.1.tgz#7d2bfe444b1ccef8de99aedc7d9330891d806076"
integrity sha512-j3VydgncUG8HP6AZala6GTIt3V01nptodnnOke3JMYLqgk8EJ1LOVOdotK9pXi80o7EmmNKFs/LyyH8z+uAJzQ==
dependencies:
"@babel/core" "^7.0.0"
"@babel/plugin-proposal-class-properties" "^7.0.0"
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0"
"@babel/plugin-proposal-object-rest-spread" "^7.0.0"
"@babel/plugin-proposal-optional-catch-binding" "^7.0.0"
"@babel/plugin-proposal-optional-chaining" "^7.0.0"
"@babel/plugin-transform-async-to-generator" "^7.0.0"
"@babel/plugin-transform-flow-strip-types" "^7.0.0"
"@babel/plugin-transform-modules-commonjs" "^7.0.0"
"@babel/register" "^7.0.0"
core-js "^2.2.2"
escape-string-regexp "^1.0.5"
metro-babel-register@^0.56.0, metro-babel-register@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.56.4.tgz#b0c627a1cfdd1bdd768f81af79481754e833a902"
@ -5920,6 +6021,13 @@ metro-babel-register@^0.56.0, metro-babel-register@^0.56.4:
core-js "^2.2.2"
escape-string-regexp "^1.0.5"
metro-babel-transformer@0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc"
integrity sha512-2aiAnuYBdcLV1VINb8ENAA4keIaJIepHgR9+iRvIde+9GSjKnexqx4nNmJN392285gRDp1fVZ7uY0uQawK/A5g==
dependencies:
"@babel/core" "^7.0.0"
metro-babel-transformer@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.4.tgz#fe1d0dc600fcf90201a5bea4d42caea10b801057"
@ -5935,6 +6043,16 @@ metro-babel7-plugin-react-transform@0.54.1:
dependencies:
"@babel/helper-module-imports" "^7.0.0"
metro-cache@0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.54.1.tgz#2e9017cbd11106837b8c385c9eb8c8175469a8c1"
integrity sha512-RxCFoNcANHXZYi4MIQNnqh68gUnC3bMpzCFJY5pBoqqdrkkn8ibYglBweA0/DW7hx1OZTJWelwS1Dp8xxmE2CA==
dependencies:
jest-serializer "^24.4.0"
metro-core "0.54.1"
mkdirp "^0.5.1"
rimraf "^2.5.4"
metro-cache@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.4.tgz#542f9f8a35f8fb9d5576f46fd3ab4d4f42851a7e"
@ -5945,6 +6063,18 @@ metro-cache@^0.56.4:
mkdirp "^0.5.1"
rimraf "^2.5.4"
metro-config@0.54.1, metro-config@^0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.54.1.tgz#808b4e17625d9f4e9afa34232778fdf8e63cc8dd"
integrity sha512-FpxrA+63rGkPGvGI653dvuSreJzU+eOTILItVnnhmqwn2SAK5V00N/qGTOIJe2YIuWEFXwCzw9lXmANrXbwuGg==
dependencies:
cosmiconfig "^5.0.5"
jest-validate "^24.7.0"
metro "0.54.1"
metro-cache "0.54.1"
metro-core "0.54.1"
pretty-format "^24.7.0"
metro-config@^0.56.0, metro-config@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.56.4.tgz#338fd8165fba59424cec427c1a881757945e57e9"
@ -5957,6 +6087,16 @@ metro-config@^0.56.0, metro-config@^0.56.4:
metro-core "^0.56.4"
pretty-format "^24.7.0"
metro-core@0.54.1, metro-core@^0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.54.1.tgz#17f6ecc167918da8819d4af5726349e55714954b"
integrity sha512-8oz3Ck7QFBzW9dG9tKFhrXHKPu2Ajx3R7eatf61Gl6Jf/tF7PNouv3wHxPsJW3oXDFiwKLszd89+OgleTGkB5g==
dependencies:
jest-haste-map "^24.7.1"
lodash.throttle "^4.1.1"
metro-resolver "0.54.1"
wordwrap "^1.0.0"
metro-core@^0.56.0, metro-core@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.56.4.tgz#67cc41b3c0bf66e9c2306f50239a1080b1e82312"
@ -5967,6 +6107,17 @@ metro-core@^0.56.0, metro-core@^0.56.4:
metro-resolver "^0.56.4"
wordwrap "^1.0.0"
metro-inspector-proxy@0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.54.1.tgz#0ef48ee3feb11c6da47aa100151a9bf2a7c358ee"
integrity sha512-sf6kNu7PgFW6U+hU7YGZfbAUKAPVvCJhY8YVu/A1RMKH9nNULrCo+jlWh0gWgmFfWRQiAPCElevROg+5somk8A==
dependencies:
connect "^3.6.5"
debug "^2.2.0"
rxjs "^5.4.3"
ws "^1.1.5"
yargs "^9.0.0"
metro-inspector-proxy@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.56.4.tgz#7343ff3c5908af4fd99e96b6d646e24e99816be4"
@ -5978,6 +6129,13 @@ metro-inspector-proxy@^0.56.4:
ws "^1.1.5"
yargs "^9.0.0"
metro-minify-uglify@0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.54.1.tgz#54ed1cb349245ce82dba8cc662bbf69fbca142c3"
integrity sha512-z+pOPna/8IxD4OhjW6Xo1mV2EszgqqQHqBm1FdmtdF6IpWkQp33qpDBNEi9NGZTOr7pp2bvcxZnvNJdC2lrK9Q==
dependencies:
uglify-es "^3.1.9"
metro-minify-uglify@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.56.4.tgz#13589dfb1d43343608aacb7f78ddfcc052daa63c"
@ -6068,6 +6226,16 @@ metro-react-native-babel-preset@^0.56.4:
"@babel/template" "^7.0.0"
react-refresh "^0.4.0"
metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17"
integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g==
dependencies:
"@babel/core" "^7.0.0"
babel-preset-fbjs "^3.1.2"
metro-babel-transformer "0.54.1"
metro-react-native-babel-preset "0.54.1"
metro-react-native-babel-transformer@^0.56.0:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.4.tgz#3c6e48b605c305362ee624e45ff338656e35fc1d"
@ -6079,6 +6247,13 @@ metro-react-native-babel-transformer@^0.56.0:
metro-react-native-babel-preset "^0.56.4"
metro-source-map "^0.56.4"
metro-resolver@0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087"
integrity sha512-Byv1LIawYAASy9CFRwzrncYnqaFGLe8vpw178EtzStqP05Hu6hXSqkNTrfoXa+3V9bPFGCrVzFx2NY3gFp2btg==
dependencies:
absolute-path "^0.0.0"
metro-resolver@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.56.4.tgz#9876f57bca37fd1bfcffd733541e2ee4a89fad7f"
@ -6086,6 +6261,28 @@ metro-resolver@^0.56.4:
dependencies:
absolute-path "^0.0.0"
metro-source-map@0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.54.1.tgz#e17bad53c11978197d3c05c9168d799c2e04dcc5"
integrity sha512-E9iSYMSUSq5qYi1R2hTQtxH4Mxjzfgr/jaSmQIWi7h3fG2P1qOZNNSzeaeUeTK+s2N/ksVlkcL5kMikol8CDrQ==
dependencies:
"@babel/traverse" "^7.0.0"
"@babel/types" "^7.0.0"
source-map "^0.5.6"
metro-source-map@0.55.0, metro-source-map@^0.55.0:
version "0.55.0"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.55.0.tgz#1f6289905f08277c398f2b9b9c13e7e0e5a6f540"
integrity sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw==
dependencies:
"@babel/traverse" "^7.0.0"
"@babel/types" "^7.0.0"
invariant "^2.2.4"
metro-symbolicate "0.55.0"
ob1 "0.55.0"
source-map "^0.5.6"
vlq "^1.0.0"
metro-source-map@^0.56.0, metro-source-map@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.56.4.tgz#868ccac3f3519fe14eca358bc186f63651b2b9bc"
@ -6099,6 +6296,16 @@ metro-source-map@^0.56.0, metro-source-map@^0.56.4:
source-map "^0.5.6"
vlq "^1.0.0"
metro-symbolicate@0.55.0:
version "0.55.0"
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.55.0.tgz#4086a2adae54b5e44a4911ca572d8a7b03c71fa1"
integrity sha512-3r3Gpv5L4U7rBGpIqw5S1nun5MelfUMLRiScJsPRGZVTX3WY1w+zpaQKlWBi5yuHf5dMQ+ZUVbhb02IdrfJ2Fg==
dependencies:
metro-source-map "0.55.0"
source-map "^0.5.6"
through2 "^2.0.1"
vlq "^1.0.0"
metro-symbolicate@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.56.4.tgz#53e9d40beac9049fa75a3e620ddd47d4907ff015"
@ -6110,6 +6317,65 @@ metro-symbolicate@^0.56.4:
through2 "^2.0.1"
vlq "^1.0.0"
metro@0.54.1, metro@^0.54.1:
version "0.54.1"
resolved "https://registry.yarnpkg.com/metro/-/metro-0.54.1.tgz#a629be00abee5a450a25a8f71c24745f70cc9b44"
integrity sha512-6ODPT4mEo4FCpbExRNnQAcZmf1VeNvYOTMj2Na03FjGqhNODHhI2U/wF/Ul5gqTyJ2dVdkXeyvKW3gl/LrnJRg==
dependencies:
"@babel/core" "^7.0.0"
"@babel/generator" "^7.0.0"
"@babel/parser" "^7.0.0"
"@babel/plugin-external-helpers" "^7.0.0"
"@babel/template" "^7.0.0"
"@babel/traverse" "^7.0.0"
"@babel/types" "^7.0.0"
absolute-path "^0.0.0"
async "^2.4.0"
babel-preset-fbjs "^3.1.2"
buffer-crc32 "^0.2.13"
chalk "^2.4.1"
concat-stream "^1.6.0"
connect "^3.6.5"
debug "^2.2.0"
denodeify "^1.2.1"
eventemitter3 "^3.0.0"
fbjs "^1.0.0"
fs-extra "^1.0.0"
graceful-fs "^4.1.3"
image-size "^0.6.0"
invariant "^2.2.4"
jest-haste-map "^24.7.1"
jest-worker "^24.6.0"
json-stable-stringify "^1.0.1"
lodash.throttle "^4.1.1"
merge-stream "^1.0.1"
metro-babel-register "0.54.1"
metro-babel-transformer "0.54.1"
metro-cache "0.54.1"
metro-config "0.54.1"
metro-core "0.54.1"
metro-inspector-proxy "0.54.1"
metro-minify-uglify "0.54.1"
metro-react-native-babel-preset "0.54.1"
metro-resolver "0.54.1"
metro-source-map "0.54.1"
mime-types "2.1.11"
mkdirp "^0.5.1"
node-fetch "^2.2.0"
nullthrows "^1.1.0"
react-transform-hmr "^1.0.4"
resolve "^1.5.0"
rimraf "^2.5.4"
serialize-error "^2.1.0"
source-map "^0.5.6"
temp "0.8.3"
throat "^4.1.0"
wordwrap "^1.0.0"
write-file-atomic "^1.2.0"
ws "^1.1.5"
xpipe "^1.0.5"
yargs "^9.0.0"
metro@^0.56.0, metro@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.4.tgz#be7e1380ee6ac3552c25ead8098eab261029e4d7"
@ -6832,6 +7098,11 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
ob1@0.55.0:
version "0.55.0"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.55.0.tgz#e393b4ae786ef442b3ef2a298ab70d6ec353dbdd"
integrity sha512-pfyiMVsUItl8WiRKMT15eCi662pCRAuYTq2+V3UpE+PpFErJI/TvRh/M/l/9TaLlbFr7krJ7gdl+FXJNcybmvw==
ob1@^0.56.4:
version "0.56.4"
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.56.4.tgz#c4acb3baa42f4993a44b35b2da7c8ef443dcccec"
@ -7623,7 +7894,7 @@ react-deep-force-update@^1.0.0:
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1"
integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA==
react-devtools-core@^3.6.3:
react-devtools-core@^3.6.1, react-devtools-core@^3.6.3:
version "3.6.3"
resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814"
integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ==
@ -7636,6 +7907,40 @@ react-is@^16.8.1, react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==
react-native-macos@0.60.0-microsoft.49:
version "0.60.0-microsoft.49"
resolved "https://registry.yarnpkg.com/react-native-macos/-/react-native-macos-0.60.0-microsoft.49.tgz#ac506343f7450f12f852769102e6262b531b181f"
integrity sha512-2631KIggGpw1RoLC/lWRZ/agFgAAMWuoQrRcmGsN+0neXHggEY5jUzz1uV6LeqKkrcudV+qaz3ajo85UjwqDIA==
dependencies:
"@babel/runtime" "^7.0.0"
"@react-native-community/cli" "^2.6.0"
"@react-native-community/cli-platform-android" "^2.6.0"
"@react-native-community/cli-platform-ios" "^2.4.1"
abort-controller "^3.0.0"
art "^0.10.0"
base64-js "^1.1.2"
connect "^3.6.5"
create-react-class "^15.6.3"
escape-string-regexp "^1.0.5"
event-target-shim "^5.0.1"
fbjs "^1.0.0"
fbjs-scripts "^1.1.0"
hermesvm "^0.1.0"
invariant "^2.2.4"
jsc-android "245459.0.0"
metro-babel-register "0.54.1"
metro-react-native-babel-transformer "0.54.1"
metro-source-map "^0.55.0"
nullthrows "^1.1.0"
pretty-format "^24.7.0"
promise "^7.1.1"
prop-types "^15.7.2"
react-devtools-core "^3.6.1"
regenerator-runtime "^0.13.2"
scheduler "0.14.0"
stacktrace-parser "^0.1.3"
whatwg-fetch "^3.0.0"
react-native@0.61.5:
version "0.61.5"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.5.tgz#6e21acb56cbd75a3baeb1f70201a66f42600bba8"
@ -8228,6 +8533,14 @@ sax@^1.2.1, sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
scheduler@0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.14.0.tgz#b392c23c9c14bfa2933d4740ad5603cc0d59ea5b"
integrity sha512-9CgbS06Kki2f4R9FjLSITjZo5BZxPsryiRNyL3LpvrM9WxcVmhlqAOc9E+KQbeI2nqej4JIIbOsfdL51cNb4Iw==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
scheduler@0.15.0:
version "0.15.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.15.0.tgz#6bfcf80ff850b280fed4aeecc6513bc0b4f17f8e"