Skip to content

Instantly share code, notes, and snippets.

@ryyppy
Created May 15, 2021 17:35
Show Gist options
  • Save ryyppy/37fb84de311286df408de9bf4030f7d1 to your computer and use it in GitHub Desktop.
Save ryyppy/37fb84de311286df408de9bf4030f7d1 to your computer and use it in GitHub Desktop.
rescript-react-native-webview
open ReactNative
include NativeElement
module Methods = {
module Make = (
T: {
type t
},
) => {
@send external clearFormData: T.t => unit = "clearFormData"
@send external clearCache: T.t => unit = "clearCache"
@send external clearHistory: T.t => unit = "clearHistory"
@send external requestFocus: T.t => unit = "requestFocus"
@send external goForward: T.t => unit = "goForward"
@send external goBack: T.t => unit = "goBack"
@send external reload: T.t => unit = "reload"
@send external stopLoading: T.t => unit = "stopLoading"
@send
external injectJavaScript: (T.t, string) => unit = "injectJavaScript"
}
}
module Element = {
/*type element*/
/*type ref = React.ref<Js.nullable<element>>*/
include Methods.Make({
type t = element
})
include ReactNative.NativeMethods.Make({
type t = element
})
}
module Source = {
type t
@obj
external uri: (
~uri: string=?,
~method: [
| #CONNECT
| #DELETE
| #GET
| #HEAD
| #OPTIONS
| #PATCH
| #POST
| #PUT
| #TRACE
]=?,
~headers: Js.t<'a>=?,
~body: string=?,
unit,
) => t = ""
@obj external html: (~html: string=?, ~baseUrl: string=?, unit) => t = ""
}
module DataDetectorTypes = {
type t = string
@inline
let phoneNumber = "phoneNumber"
@inline
let link = "link"
@inline
let address = "address"
@inline
let calendarEvent = "calendarEvent"
@inline
let none = "none"
@inline
let all = "all"
@inline
let trackingNumber = "trackingNumber"
@inline
let flightNumber = "flightNumber"
@inline
let lookupSuggestion = "lookupSuggestion"
}
module DecelerationRate = {
type t = string
external value: float => t = "%identity"
@inline
let normal = "normal"
@inline
let fast = "fast"
}
module NavigationType = {
type t = string
@inline
let click = "click"
@inline
let formsubmit = "formsubmit"
@inline
let backforward = "backforward"
@inline
let reload = "reload"
@inline
let formresubmit = "formresubmit"
@inline
let other = "other"
}
type webViewNativeEvent = {
target: ReactNative.NativeTypes.nodeHandle,
url: string,
title: string,
loading: bool,
canGoBack: bool,
canGoForward: bool,
}
type webViewError = {
description: string,
domain: option<string>,
code: int,
didFailProvisionalNavigation: option<bool>,
}
type webViewHttpError = {
description: string,
statusCode: int,
}
type webViewMessage = {data: string}
type webViewNativeProgressEvent = {progress: float}
type webViewNavigation = {
navigationType: NavigationType.t,
mainDocumentURL: option<string>,
// todo: not sure if this is correct
url: string,
}
type webViewShouldStartLoadWithRequest = {
navigationType: NavigationType.t,
mainDocumentURL: option<string>,
lockIdentifier: int,
isTopFrame: bool,
}
type webViewNavigationOrError
module WebViewDownloadEvent = {
type payload = {downloadUrl: string}
include Event.SyntheticEvent({
type _payload = payload
})
}
module WebViewErrorEvent = {
type payload = Js.t<webViewError>
include Event.SyntheticEvent({
type _payload = payload
})
}
module WebViewHttpErrorEvent = {
type payload = Js.t<webViewHttpError>
include Event.SyntheticEvent({
type _payload = payload
})
}
module WebViewMessageEvent = {
type payload = Js.t<webViewMessage>
include Event.SyntheticEvent({
type _payload = payload
})
}
module WebViewNavigationEvent = {
type payload = Js.t<webViewNavigation>
include Event.SyntheticEvent({
type _payload = payload
})
}
module WebViewProgressEvent = {
type payload = Js.t<webViewNativeProgressEvent>
include Event.SyntheticEvent({
type _payload = payload
})
}
module WebViewRenderProcessGone = {
type payload = {didCrash: bool}
include Event.SyntheticEvent({
type _payload = payload
})
}
module WebViewTerminatedEvent = {
type payload = Js.t<webViewNativeEvent>
include Event.SyntheticEvent({
type _payload = payload
})
}
module UnionCallbackMaker = {
include NativeElement
module Make = (
T: {
type union
type navigationEvent
type errorEvent
},
) => {
module WebViewEvent = {
type payload = T.union
include Event.SyntheticEvent({
type _payload = payload
})
}
type t = WebViewEvent.t => unit
@get external description: T.union => option<string> = "description"
external convert: WebViewEvent.t => 'a = "%identity"
let make = (
~navigationCallback: T.navigationEvent => unit,
~errorCallback: T.errorEvent => unit,
): t =>
x =>
switch description(x.nativeEvent) {
| None => navigationCallback(convert(x))
| Some(_) => errorCallback(convert(x))
}
let uncurriedMake = (
~navigationCallback: (. T.navigationEvent) => unit,
~errorCallback: (. T.errorEvent) => unit,
): t =>
x =>
switch description(x.nativeEvent) {
| None => navigationCallback(. convert(x))
| Some(_) => errorCallback(. convert(x))
}
}
}
module UnionCallback = UnionCallbackMaker.Make({
type union = Js.t<webViewNavigationOrError>
type navigationEvent = WebViewNavigationEvent.t
type errorEvent = WebViewErrorEvent.t
})
type nativeConfig
@obj
external nativeConfig: (
~component: React.component<'a>=?,
~props: Js.t<'b>=?,
~viewManager: Js.t<'c>=?,
) => nativeConfig = ""
@react.component @module("react-native-webview")
external make: (
~ref: ref=?,
~allowingReadAccessToURL: // WebView props
string=?,
~allowFileAccess: bool=?,
~allowUniversalAccessFromFileURLs: bool=?,
~allowsBackForwardNavigationGestures: bool=?,
~allowsFullscreenVideo: bool=?,
~allowsInlineMediaPlayback: bool=?,
~allowsLinkPreview: bool=?,
~androidHardwareAccelerationDisabled: bool=?,
~androidLayerType: [#none | #software | #hardware]=?,
~applicationNameForUserAgent: string=?,
~automaticallyAdjustContentInsets: bool=?,
~bounces: bool=?,
~cacheEnabled: bool=?,
~cacheMode: @string
[
| @as("LOAD_DEFAULT") #default
| @as("LOAD_CACHE_ONLY") #cacheOnly
| @as("LOAD_CACHE_ELSE_NETWORK") #cacheElseNetwork
| @as("LOAD_NO_CACHE") #noCache
]=?,
~containerStyle: ReactNative.Style.t=?,
~contentInset: ReactNative.View.edgeInsets=?,
~contentInsetAdjustmentBehavior: [
| #never
| #always
| #automatic
| #scrollableAxes
]=?,
~contentMode: [#recommended | #mobile | #desktop]=?,
~dataDetectorTypes: array<DataDetectorTypes.t>=?,
~decelerationRate: DecelerationRate.t=?,
~directionalLockEnabled: bool=?,
~domStorageEnabled: bool=?,
~geolocationEnabled: bool=?,
~hideKeyboardAccessoryView: bool=?,
~incognito: bool=?,
~injectedJavaScript: string=?,
~injectedJavaScriptForMainFrameOnly: bool=?,
~injectedJavaScriptBeforeContentLoaded: string=?,
~injectedJavaScriptBeforeContentLoadedForMainFrameOnly: bool=?,
~javaScriptCanOpenWindowsAutomatically: bool=?,
~javaScriptEnabled: bool=?,
~keyboardDisplayRequiresUserAction: bool=?,
~mediaPlaybackRequiresUserAction: bool=?,
~mixedContentMode: [#never | #always | #compatibility]=?,
~nativeConfig: nativeConfig=?,
~onContentProcessDidTerminate: WebViewTerminatedEvent.t => unit=?,
~onFileDownload: WebViewDownloadEvent.t => unit=?,
~onError: WebViewErrorEvent.t => unit=?,
~onHttpError: WebViewHttpErrorEvent.t => unit=?,
~onLoad: WebViewNavigationEvent.t => unit=?,
~onLoadEnd: UnionCallback.t=?,
~onLoadProgress: WebViewProgressEvent.t => unit=?,
~onLoadStart: WebViewNavigationEvent.t => unit=?,
~onMessage: WebViewMessageEvent.t => unit=?,
~onNavigationStateChange: {"url": string} => unit=?,
~onRenderProcessGone: WebViewRenderProcessGone.t => unit=?,
~onShouldStartLoadWithRequest: Js.t<webViewShouldStartLoadWithRequest> => bool=?,
~originWhitelist: array<string>=?,
~overScrollMode: [#never | #always | #content]=?,
~pagingEnabled: bool=?,
~pullToRefreshEnabled: bool=?,
~renderError: string => React.element=?,
~renderLoading: unit => React.element=?,
~saveFormDataDisabled: bool=?,
~scalesPageToFit: bool=?,
~scrollEnabled: bool=?,
~sharedCookiesEnabled: bool=?,
~showsHorizontalScrollIndicator: bool=?,
~showsVerticalScrollIndicator: bool=?,
~source: Source.t=?,
~startInLoadingState: bool=?,
~textZoom: float=?,
~ignoreSilentHardwareSwitch: bool=?,
~thirdPartyCookiesEnabled: bool=?,
~userAgent: string=?,
/*~accessibilityActions: // View props 0.63.0*/
/*array<Accessibility.actionInfo>=?,*/
~accessibilityElementsHidden: bool=?,
~accessibilityHint: string=?,
~accessibilityIgnoresInvertColors: bool=?,
~accessibilityLabel: string=?,
/*~accessibilityLiveRegion: Accessibility.liveRegion=?,*/
/*~accessibilityRole: Accessibility.role=?,*/
~accessibilityState: Accessibility.state=?,
~accessibilityValue: Accessibility.value=?,
~accessibilityViewIsModal: bool=?,
~accessible: bool=?,
~collapsable: bool=?,
~hitSlop: View.edgeInsets=?,
~importantForAccessibility: @string
[
| #auto
| #yes
| #no
| @as("no-hide-descendants") #noHideDescendants
]=?,
~nativeID: string=?,
~needsOffscreenAlphaCompositing: bool=?,
/*~onAccessibilityAction: Accessibility.actionEvent => unit=?,*/
~onAccessibilityEscape: unit => unit=?,
~onAccessibilityTap: unit => unit=?,
~onLayout: Event.layoutEvent => unit=?,
~onMagicTap: unit => unit=?,
~onMoveShouldSetResponder: // Gesture Responder props
Event.pressEvent => bool=?,
~onMoveShouldSetResponderCapture: Event.pressEvent => bool=?,
~onResponderEnd: Event.pressEvent => unit=?,
~onResponderGrant: Event.pressEvent => unit=?,
~onResponderMove: Event.pressEvent => unit=?,
~onResponderReject: Event.pressEvent => unit=?,
~onResponderRelease: Event.pressEvent => unit=?,
~onResponderStart: Event.pressEvent => unit=?,
~onResponderTerminate: Event.pressEvent => unit=?,
~onResponderTerminationRequest: Event.pressEvent => bool=?,
~onStartShouldSetResponder: Event.pressEvent => bool=?,
~onStartShouldSetResponderCapture: Event.pressEvent => bool=?,
~pointerEvents: @string
[
| #auto
| #none
| @as("box-none") #boxNone
| @as("box-only") #boxOnly
]=?,
~removeClippedSubviews: bool=?,
~renderToHardwareTextureAndroid: bool=?,
~shouldRasterizeIOS: bool=?,
~style: Style.t=?,
~testID: string=?,
~children: React.element=?,
~onMouseDown: // React Native Web Props
ReactEvent.Mouse.t => unit=?,
~onMouseEnter: ReactEvent.Mouse.t => unit=?,
~onMouseLeave: ReactEvent.Mouse.t => unit=?,
~onMouseMove: ReactEvent.Mouse.t => unit=?,
~onMouseOver: ReactEvent.Mouse.t => unit=?,
~onMouseOut: ReactEvent.Mouse.t => unit=?,
~onMouseUp: ReactEvent.Mouse.t => unit=?,
) => React.element = "default"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment