Skip to content

Commit eeba270

Browse files
committed
Merge branch 'master' of github.com:tht13/electrino
2 parents 83b2ed7 + 904fc05 commit eeba270

File tree

6 files changed

+276
-18
lines changed

6 files changed

+276
-18
lines changed

Electrino/win10/Electrino/App.xaml.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Diagnostics;
1818
using System.Threading.Tasks;
1919
using Windows.Storage;
20+
using Windows.UI.ViewManagement;
2021

2122
namespace Electrino
2223
{
@@ -90,18 +91,21 @@ private void Suspended()
9091
}
9192
}
9293

93-
public static void NewWindow()
94+
public static void NewWindow(int width, int height)
9495
{
9596
if (instance == null)
9697
{
9798
Log("App no ready yet");
9899
return;
99100
}
100-
App.instance._NewWindow();
101+
App.instance._NewWindow(width, height);
101102
}
102103

103-
private void _NewWindow()
104+
private void _NewWindow(int width, int height)
104105
{
106+
ApplicationView.PreferredLaunchViewSize = new Size(width, height);
107+
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
108+
105109
Frame rootFrame = Window.Current.Content as Frame;
106110

107111
// Do not repeat app initialization when the Window already has content,
@@ -113,7 +117,6 @@ private void _NewWindow()
113117

114118
rootFrame.NavigationFailed += OnNavigationFailed;
115119

116-
117120
// Place the frame in the current Window
118121
Window.Current.Content = rootFrame;
119122
}
@@ -127,7 +130,6 @@ private void _NewWindow()
127130
}
128131
// Ensure the current window is active
129132
Window.Current.Activate();
130-
131133
}
132134

133135
/// <summary>

Electrino/win10/Electrino/Electrino.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
<Compile Include="Hosting\JavaScriptValueType.cs" />
129129
<Compile Include="Hosting\Native.cs" />
130130
<Compile Include="JavaScriptApp.cs" />
131+
<Compile Include="JS\JavaScriptValueToJTokenConverter.cs" />
131132
<Compile Include="JS\JSApp.cs" />
132133
<Compile Include="JS\JSBrowserWindow.cs" />
133134
<Compile Include="JS\JSConsole.cs" />
@@ -137,6 +138,7 @@
137138
<Compile Include="JS\JSProcess.cs" />
138139
<Compile Include="JS\JSRequire.cs" />
139140
<Compile Include="JS\JSUrl.cs" />
141+
<Compile Include="JS\JTokenToJavaScriptValueConverter.cs" />
140142
<Compile Include="MainPage.xaml.cs">
141143
<DependentUpon>MainPage.xaml</DependentUpon>
142144
</Compile>
@@ -175,6 +177,9 @@
175177
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
176178
<Version>5.3.3</Version>
177179
</PackageReference>
180+
<PackageReference Include="Newtonsoft.Json">
181+
<Version>10.0.2</Version>
182+
</PackageReference>
178183
</ItemGroup>
179184
<ItemGroup>
180185
<ProjectReference Include="..\RenderAPI\RenderAPI.csproj">

Electrino/win10/Electrino/JS/JSBrowserWindow.cs

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
using System;
1+
using ChakraHost.Hosting;
2+
using Newtonsoft.Json.Linq;
3+
using System;
24
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
using ChakraHost.Hosting;
7-
using System.Diagnostics;
85

96
namespace Electrino.JS
107
{
@@ -22,20 +19,52 @@ protected override JavaScriptValue Main(JavaScriptValue callee, bool isConstruct
2219
return JavaScriptValue.CreateTypeError(JavaScriptValue.FromString("BrowserWindow must be constructed"));
2320
}
2421

25-
JSBrowserWindowInstance instance = new JSBrowserWindowInstance();
22+
JToken options;
23+
try
24+
{
25+
options = JavaScriptValueToJTokenConverter.Convert(arguments[1]);
26+
}
27+
catch (Exception)
28+
{
29+
// If no object is passed to the BrowserWindow constructor we'll provide a default one
30+
options = JObject.Parse("{ width: 800, height: 600 }");
31+
}
32+
33+
JSBrowserWindowInstance instance = new JSBrowserWindowInstance(options);
2634
return instance.GetModule();
2735
}
2836
}
2937

3038
class JSBrowserWindowInstance : AbstractJSModule
3139
{
40+
private JToken options;
41+
// I don't really like putting this here, I think we should probably have a class that contains all our constants
42+
private const int defaultWindowWidth = 800, defaultWindowHeight = 600;
3243
private Dictionary<string, List<Tuple<JavaScriptValue, JavaScriptValue>>> listeners = new Dictionary<string, List<Tuple<JavaScriptValue, JavaScriptValue>>>();
3344

34-
public JSBrowserWindowInstance() : base("BrowserWindowInstance")
45+
public JSBrowserWindowInstance(JToken options) : base("BrowserWindowInstance")
3546
{
47+
this.options = options;
48+
3649
AttachMethod(LoadURL, "loadURL");
3750
AttachMethod(On, "on");
38-
App.NewWindow();
51+
52+
if (this.options != null)
53+
{
54+
int width = 0, height = 0;
55+
56+
Int32.TryParse(options["width"].ToString(), out width);
57+
Int32.TryParse(options["height"].ToString(), out height);
58+
59+
if (width <= 0) width = defaultWindowWidth;
60+
if (height <= 0) height = defaultWindowHeight;
61+
62+
App.NewWindow(width, height);
63+
}
64+
else
65+
{
66+
App.NewWindow(defaultWindowWidth, defaultWindowHeight);
67+
}
3968
}
4069
protected JavaScriptValue LoadURL(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
4170
{
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using ChakraHost.Hosting;
2+
using Newtonsoft.Json.Linq;
3+
using System;
4+
5+
namespace Electrino.JS
6+
{
7+
// Borrowed from: https://www.microsoft.com/reallifecode/2016/06/02/hybrid-apps-using-c-and-javascript-with-chakracore/
8+
public sealed class JTokenToJavaScriptValueConverter
9+
{
10+
private static readonly JTokenToJavaScriptValueConverter s_instance =
11+
new JTokenToJavaScriptValueConverter();
12+
13+
private JTokenToJavaScriptValueConverter() { }
14+
15+
public static JavaScriptValue Convert(JToken token)
16+
{
17+
return s_instance.Visit(token);
18+
}
19+
20+
private JavaScriptValue Visit(JToken token)
21+
{
22+
if (token == null)
23+
throw new ArgumentNullException(nameof(token));
24+
25+
switch (token.Type)
26+
{
27+
case JTokenType.Array:
28+
return VisitArray((JArray)token);
29+
case JTokenType.Boolean:
30+
return VisitBoolean((JValue)token);
31+
case JTokenType.Float:
32+
return VisitFloat((JValue)token);
33+
case JTokenType.Integer:
34+
return VisitInteger((JValue)token);
35+
case JTokenType.Null:
36+
return VisitNull(token);
37+
case JTokenType.Object:
38+
return VisitObject((JObject)token);
39+
case JTokenType.String:
40+
return VisitString((JValue)token);
41+
case JTokenType.Undefined:
42+
return VisitUndefined(token);
43+
default:
44+
throw new NotSupportedException();
45+
}
46+
}
47+
48+
private JavaScriptValue VisitArray(JArray token)
49+
{
50+
var n = token.Count;
51+
var array = AddRef(JavaScriptValue.CreateArray((uint)n));
52+
for (var i = 0; i < n; ++i)
53+
{
54+
var value = Visit(token[i]);
55+
array.SetIndexedProperty(JavaScriptValue.FromInt32(i), value);
56+
value.Release();
57+
}
58+
59+
return array;
60+
}
61+
62+
private JavaScriptValue VisitBoolean(JValue token)
63+
{
64+
return token.Value<bool>()
65+
? JavaScriptValue.True
66+
: JavaScriptValue.False;
67+
}
68+
69+
private JavaScriptValue VisitFloat(JValue token)
70+
{
71+
return AddRef(JavaScriptValue.FromDouble(token.Value<double>()));
72+
}
73+
74+
private JavaScriptValue VisitInteger(JValue token)
75+
{
76+
return AddRef(JavaScriptValue.FromDouble(token.Value<double>()));
77+
}
78+
79+
private JavaScriptValue VisitNull(JToken token)
80+
{
81+
return JavaScriptValue.Null;
82+
}
83+
84+
private JavaScriptValue VisitObject(JObject token)
85+
{
86+
var jsonObject = AddRef(JavaScriptValue.CreateObject());
87+
foreach (var entry in token)
88+
{
89+
var value = Visit(entry.Value);
90+
var propertyId = JavaScriptPropertyId.FromString(entry.Key);
91+
jsonObject.SetProperty(propertyId, value, true);
92+
value.Release();
93+
}
94+
95+
return jsonObject;
96+
}
97+
98+
private JavaScriptValue VisitString(JValue token)
99+
{
100+
return AddRef(JavaScriptValue.FromString(token.Value<string>()));
101+
}
102+
103+
private JavaScriptValue VisitUndefined(JToken token)
104+
{
105+
return JavaScriptValue.Undefined;
106+
}
107+
108+
private JavaScriptValue AddRef(JavaScriptValue value)
109+
{
110+
value.AddRef();
111+
return value;
112+
}
113+
}
114+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using ChakraHost.Hosting;
2+
using Newtonsoft.Json.Linq;
3+
using System;
4+
5+
namespace Electrino.JS
6+
{
7+
// Borrowed from: https://www.microsoft.com/reallifecode/2016/06/02/hybrid-apps-using-c-and-javascript-with-chakracore/
8+
public sealed class JavaScriptValueToJTokenConverter
9+
{
10+
private static readonly JToken s_true = new JValue(true);
11+
private static readonly JToken s_false = new JValue(false);
12+
private static readonly JToken s_null = JValue.CreateNull();
13+
private static readonly JToken s_undefined = JValue.CreateUndefined();
14+
15+
private static readonly JavaScriptValueToJTokenConverter s_instance =
16+
new JavaScriptValueToJTokenConverter();
17+
18+
private JavaScriptValueToJTokenConverter() { }
19+
20+
public static JToken Convert(JavaScriptValue value)
21+
{
22+
return s_instance.Visit(value);
23+
}
24+
25+
private JToken Visit(JavaScriptValue value)
26+
{
27+
switch (value.ValueType)
28+
{
29+
case JavaScriptValueType.Array:
30+
return VisitArray(value);
31+
case JavaScriptValueType.Boolean:
32+
return VisitBoolean(value);
33+
case JavaScriptValueType.Null:
34+
return VisitNull(value);
35+
case JavaScriptValueType.Number:
36+
return VisitNumber(value);
37+
case JavaScriptValueType.Object:
38+
return VisitObject(value);
39+
case JavaScriptValueType.String:
40+
return VisitString(value);
41+
case JavaScriptValueType.Undefined:
42+
return VisitUndefined(value);
43+
case JavaScriptValueType.Function:
44+
case JavaScriptValueType.Error:
45+
default:
46+
throw new NotSupportedException();
47+
}
48+
}
49+
50+
private JToken VisitArray(JavaScriptValue value)
51+
{
52+
var array = new JArray();
53+
var propertyId = JavaScriptPropertyId.FromString("length");
54+
var length = (int)value.GetProperty(propertyId).ToDouble();
55+
for (var i = 0; i < length; ++i)
56+
{
57+
var index = JavaScriptValue.FromInt32(i);
58+
var element = value.GetIndexedProperty(index);
59+
array.Add(Visit(element));
60+
}
61+
62+
return array;
63+
}
64+
65+
private JToken VisitBoolean(JavaScriptValue value)
66+
{
67+
return value.ToBoolean() ? s_true : s_false;
68+
}
69+
70+
private JToken VisitNull(JavaScriptValue value)
71+
{
72+
return s_null;
73+
}
74+
75+
private JToken VisitNumber(JavaScriptValue value)
76+
{
77+
var number = value.ToDouble();
78+
79+
return number % 1 == 0
80+
? new JValue((long)number)
81+
: new JValue(number);
82+
}
83+
84+
private JToken VisitObject(JavaScriptValue value)
85+
{
86+
var jsonObject = new JObject();
87+
var properties = Visit(value.GetOwnPropertyNames()).ToObject<string[]>();
88+
foreach (var property in properties)
89+
{
90+
var propertyId = JavaScriptPropertyId.FromString(property);
91+
var propertyValue = value.GetProperty(propertyId);
92+
jsonObject.Add(property, Visit(propertyValue));
93+
}
94+
95+
return jsonObject;
96+
}
97+
98+
private JToken VisitString(JavaScriptValue value)
99+
{
100+
return JValue.CreateString(value.ToString());
101+
}
102+
103+
private JToken VisitUndefined(JavaScriptValue value)
104+
{
105+
return s_undefined;
106+
}
107+
}
108+
}

Electrino/win10/Electrino/test-app/main.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ var win = null;
1010

1111
console.log("hello world starting, app is: ", app);
1212

13-
function createWindow () {
14-
// Create the browser window.
13+
function createWindow() {
14+
// Create the browser window.
1515
win = new BrowserWindow({ width: 800, height: 600 });
1616

1717
console.log("createWindow", BrowserWindow, win);
18-
// and load the index.html of the app.
18+
// and load the index.html of the app.
1919
win.loadURL(url.format({
2020
pathname: path.join("/test-app", 'index.html'),
2121
protocol: 'ms-appx-web:',
2222
slashes: true
2323
}));
24-
// Emitted when the window is closed.
24+
// Emitted when the window is closed.
2525
win.on('closed', function () {
2626
// Dereference the window object, usually you would store windows
2727
// in an array if your app supports multi windows, this is the time

0 commit comments

Comments
 (0)