Skip to content

Commit

Permalink
fix(ReactWebView): Add ReactWebView
Browse files Browse the repository at this point in the history
ReactWebView provides access to native webview UI components for React Native JavaScript applications.
- PR comments #2 implemented

Fixes #118
  • Loading branch information
ebragge authored and rozele committed May 16, 2016
1 parent 737a0df commit 6b99170
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ class WebViewLoadingErrorEvent : Event
private readonly double _code;
private readonly string _description;

public WebViewLoadingErrorEvent(int viewTag, WebErrorStatus error)
public WebViewLoadingErrorEvent(int viewTag, WebErrorStatus error, string description)
: base(viewTag, TimeSpan.FromTicks(Environment.TickCount))
{
_code = (double)error;
_description = ErrorString(error);
if (description == null)
{
_description = ErrorString(error);
}
else
{
_description = description;
}
}

public override string EventName
Expand Down
12 changes: 3 additions & 9 deletions ReactWindows/ReactNative/Views/Web/Events/WebViewLoadingEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ namespace ReactNative.Views.Web.Events
{
class WebViewLoadingEvent : Event
{
public enum LoadingEventType
{
Start,
Finish,
};

private readonly LoadingEventType _type;
private readonly string _type;

private readonly string _url;
private readonly bool _loading;
Expand All @@ -22,7 +16,7 @@ public enum LoadingEventType

public WebViewLoadingEvent(
int viewTag,
LoadingEventType type,
string type,
string url,
bool loading,
string title,
Expand All @@ -42,7 +36,7 @@ public override string EventName
{
get
{
if (_type == LoadingEventType.Start)
if (_type.Equals("Start"))
{
return "topLoadingStart";
}
Expand Down
110 changes: 50 additions & 60 deletions ReactWindows/ReactNative/Views/Web/ReactWebViewManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
using ReactNative.Views.Web.Events;
using System;
using System.Collections.Generic;
using Windows.ApplicationModel.Core;
using Windows.UI.Core;
using Windows.UI.Xaml.Controls;
using Windows.Web;
using Windows.Web.Http;

namespace ReactNative.Views.Web
Expand Down Expand Up @@ -52,9 +51,9 @@ public override IReadOnlyDictionary<string, object> CommandsMap
}

/// <summary>
/// Sets whether JavaScript is enabled or not.
/// Sets flag signaling whether JavaScript is enabled.
/// </summary>
/// <param name="view">a webview instance.</param>
/// <param name="view">A webview instance.</param>
/// <param name="enabled"></param>
[ReactProp("javaScriptEnabled")]
public void SetJavaScriptEnabled(WebView view, bool enabled)
Expand All @@ -63,9 +62,9 @@ public void SetJavaScriptEnabled(WebView view, bool enabled)
}

/// <summary>
/// CSets whether Indexed DB is enabled or not.
/// Sets flag signaling whether Indexed DB is enabled.
/// </summary>
/// <param name="view">a webview instance.</param>
/// <param name="view">A webview instance.</param>
/// <param name="enabled"></param>
[ReactProp("indexedDbEnabled")]
public void SetIndexedDbEnabled(WebView view, bool enabled)
Expand All @@ -74,27 +73,20 @@ public void SetIndexedDbEnabled(WebView view, bool enabled)
}

/// <summary>
/// Sets the JS to be injected when the webpage loads.
/// Sets the JavaScript to be injected when the webpage loads.
/// </summary>
/// <param name="view">a webview instance.</param>
/// <param name="view">A webview instance.</param>
/// <param name="injectedJavaScript"></param>
[ReactProp("injectedJavaScript")]
public void SetInjectedJavaScript(WebView view, string injectedJavaScript)
{
if (_injectedJS.ContainsKey(view.GetTag()))
{
_injectedJS[view.GetTag()] = injectedJavaScript;
}
else
{
_injectedJS.Add(view.GetTag(), injectedJavaScript);
}
_injectedJS[view.GetTag()] = injectedJavaScript;
}

/// <summary>
/// Sets webview source.
/// </summary>
/// <param name="view">a webview instance.</param>
/// <param name="view">A webview instance.</param>
/// <param name="source"></param>
[ReactProp("source")]
public void SetSource(WebView view, JObject source)
Expand Down Expand Up @@ -133,15 +125,16 @@ public void SetSource(WebView view, JObject source)
}
else
{
return;
throw new InvalidOperationException(
$"Unsupported method '{method}' received by '{typeof(ReactWebViewManager)}'.");
}
}
else
{
request.Method = HttpMethod.Get;
}

var headers = source.Value<string>("headers");
var headers = source.Value<JObject>("headers");
if (headers != null)
{
IEnumerator<KeyValuePair<string, JToken>> enumerator = ((JObject)headers).GetEnumerator();
Expand Down Expand Up @@ -228,10 +221,10 @@ protected override void AddEventEmitters(ThemedReactContext reactContext, WebVie
view.NavigationStarting += OnNavigationStarting;
}

private void OnNavigationCompleted(object sender, WebViewNavigationCompletedEventArgs e)
private async void OnNavigationCompleted(object sender, WebViewNavigationCompletedEventArgs e)
{
var webView = (WebView)sender;
var reactContext = webView.GetReactContext();
LoadFinished(webView, e.Uri?.ToString());

if (e.IsSuccess)
{
Expand All @@ -240,67 +233,64 @@ private void OnNavigationCompleted(object sender, WebViewNavigationCompletedEven
if (_injectedJS.TryGetValue(webView.GetTag(), out script) && script.Length > 0)
{
string[] args = { script };
RunOnDispatcher(async () =>
try
{
try
{
await webView.InvokeScriptAsync("eval", args);
}
catch (Exception)
{
// Invalid script
}
});
}

var uri = e.Uri?.ToString();

reactContext.GetNativeModule<UIManagerModule>()
.EventDispatcher
.DispatchEvent(
new WebViewLoadingEvent(
webView.GetTag(),
WebViewLoadingEvent.LoadingEventType.Finish,
uri,
false,
webView.DocumentTitle,
webView.CanGoBack,
webView.CanGoForward));
await webView.InvokeScriptAsync("eval", args);
}
catch (Exception ex)
{
LoadFailed(webView, e.WebErrorStatus, ex.Message);
}
}
}
else
{
reactContext.GetNativeModule<UIManagerModule>()
.EventDispatcher
.DispatchEvent(
new WebViewLoadingErrorEvent(
webView.GetTag(),
e.WebErrorStatus));
LoadFailed(webView, e.WebErrorStatus, null);
}
}

private void OnNavigationStarting(object sender, WebViewNavigationStartingEventArgs e)
{
var webView = (WebView)sender;
var reactContext = webView.GetReactContext();

var uri = e.Uri?.ToString();

reactContext.GetNativeModule<UIManagerModule>()
webView.GetReactContext().GetNativeModule<UIManagerModule>()
.EventDispatcher
.DispatchEvent(
new WebViewLoadingEvent(
webView.GetTag(),
WebViewLoadingEvent.LoadingEventType.Start,
uri,
"Start",
e.Uri?.ToString(),
true,
webView.DocumentTitle,
webView.CanGoBack,
webView.CanGoForward));
}

private static async void RunOnDispatcher(DispatchedHandler action)
private void LoadFinished(WebView webView, string uri)
{
webView.GetReactContext().GetNativeModule<UIManagerModule>()
.EventDispatcher
.DispatchEvent(
new WebViewLoadingEvent(
webView.GetTag(),
"Finish",
uri,
false,
webView.DocumentTitle,
webView.CanGoBack,
webView.CanGoForward));
}

private void LoadFailed(WebView webView, WebErrorStatus status, string message)
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, action);
var reactContext = webView.GetReactContext();
reactContext.GetNativeModule<UIManagerModule>()
.EventDispatcher
.DispatchEvent(
new WebViewLoadingErrorEvent(
webView.GetTag(),
status,
message));
}
}
}
4 changes: 2 additions & 2 deletions ReactWindows/js/Components/WebView/WebView.windows.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ var WebView = React.createClass({
]),

/**
* Used on Android only, JS is enabled by default for WebView on iOS
* Used on Android and Windows only, JS is enabled by default for WebView on iOS
* @platform android
* @platform windows
*/
javaScriptEnabled: PropTypes.bool,

Expand Down Expand Up @@ -146,7 +147,6 @@ var WebView = React.createClass({
getDefaultProps: function() {
return {
javaScriptEnabled : true,
scalesPageToFit: true,
};
},

Expand Down

0 comments on commit 6b99170

Please sign in to comment.