├── .gitattributes
├── .gitignore
├── Electrino
├── macOS
│ ├── Electrino.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcuserdata
│ │ │ │ └── pauli.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ └── xcuserdata
│ │ │ └── pauli.xcuserdatad
│ │ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ │ └── xcschemes
│ │ │ ├── Electrino.xcscheme
│ │ │ └── xcschememanagement.plist
│ └── Electrino
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ └── MainMenu.xib
│ │ ├── ENOBrowserWindowController.h
│ │ ├── ENOBrowserWindowController.m
│ │ ├── ENOBrowserWindowController.xib
│ │ ├── ENOJSApp.h
│ │ ├── ENOJSApp.m
│ │ ├── ENOJSBrowserWindow.h
│ │ ├── ENOJSBrowserWindow.m
│ │ ├── ENOJSConsole.h
│ │ ├── ENOJSConsole.m
│ │ ├── ENOJSIPCMain.h
│ │ ├── ENOJSIPCMain.m
│ │ ├── ENOJSNativeImage.h
│ │ ├── ENOJSNativeImage.m
│ │ ├── ENOJSPath.h
│ │ ├── ENOJSPath.m
│ │ ├── ENOJSProcess.h
│ │ ├── ENOJSProcess.m
│ │ ├── ENOJSTray.h
│ │ ├── ENOJSTray.m
│ │ ├── ENOJSUrl.h
│ │ ├── ENOJSUrl.m
│ │ ├── ENOJavaScriptApp.h
│ │ ├── ENOJavaScriptApp.m
│ │ ├── Info.plist
│ │ └── main.m
├── test-app
│ ├── index.html
│ ├── main.js
│ └── package.json
├── test-tray
│ ├── index.html
│ ├── index.js
│ ├── main.js
│ └── package.json
└── win10
│ ├── Electrino.sln
│ ├── Electrino
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── Assets
│ │ ├── LockScreenLogo.scale-200.png
│ │ ├── SplashScreen.scale-200.png
│ │ ├── Square150x150Logo.scale-200.png
│ │ ├── Square44x44Logo.scale-200.png
│ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ │ ├── StoreLogo.png
│ │ └── Wide310x150Logo.scale-200.png
│ ├── Electrino.csproj
│ ├── Hosting
│ │ ├── JavaScriptBackgroundWorkItemCallback.cs
│ │ ├── JavaScriptBeforeCollectCallback.cs
│ │ ├── JavaScriptContext.cs
│ │ ├── JavaScriptEngineException.cs
│ │ ├── JavaScriptErrorCode.cs
│ │ ├── JavaScriptException.cs
│ │ ├── JavaScriptFatalException.cs
│ │ ├── JavaScriptMemoryAllocationCallback.cs
│ │ ├── JavaScriptMemoryEventType.cs
│ │ ├── JavaScriptNativeFunction.cs
│ │ ├── JavaScriptObjectBeforeCollectCallback.cs
│ │ ├── JavaScriptObjectFinalizeCallback.cs
│ │ ├── JavaScriptProjectionEnqueueCallback.cs
│ │ ├── JavaScriptPromiseContinuationCallback.cs
│ │ ├── JavaScriptPropertyId.cs
│ │ ├── JavaScriptPropertyIdType.cs
│ │ ├── JavaScriptRuntime.cs
│ │ ├── JavaScriptRuntimeAttributes.cs
│ │ ├── JavaScriptRuntimeVersion.cs
│ │ ├── JavaScriptScriptException.cs
│ │ ├── JavaScriptSerializedScriptLoadSourceCallback.cs
│ │ ├── JavaScriptSerializedScriptUnloadCallback.cs
│ │ ├── JavaScriptSourceContext.cs
│ │ ├── JavaScriptThreadServiceCallback.cs
│ │ ├── JavaScriptTypedArrayType.cs
│ │ ├── JavaScriptUsageException.cs
│ │ ├── JavaScriptValue.cs
│ │ ├── JavaScriptValueType.cs
│ │ └── Native.cs
│ ├── JS
│ │ ├── JSApp.cs
│ │ ├── JSBrowserWindow.cs
│ │ ├── JSConsole.cs
│ │ ├── JSElectrino.cs
│ │ ├── JSModule.cs
│ │ ├── JSPath.cs
│ │ ├── JSProcess.cs
│ │ ├── JSRequire.cs
│ │ ├── JSUrl.cs
│ │ ├── JTokenToJavaScriptValueConverter.cs
│ │ └── JavaScriptValueToJTokenConverter.cs
│ ├── JavaScriptApp.cs
│ ├── MainPage.xaml
│ ├── MainPage.xaml.cs
│ ├── Package.appxmanifest
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Default.rd.xml
│ └── test-app
│ │ ├── index.html
│ │ ├── main.js
│ │ └── test.js
│ └── RenderAPI
│ ├── JSOs.cs
│ ├── JSProcess.cs
│ ├── JSRequire.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ └── RenderAPI.csproj
├── LICENSE
├── README.md
├── docs
└── electron-and-electrino-helloworld-screenshot.png
├── package.json
└── test-app
├── index.html
├── main.js
└── package.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac desktop data
2 | .DS_Store
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
34 | # Win10
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.userosscache
43 | *.sln.docstates
44 |
45 | # User-specific files (MonoDevelop/Xamarin Studio)
46 | *.userprefs
47 |
48 | # Build results
49 | [Dd]ebug/
50 | [Dd]ebugPublic/
51 | [Rr]elease/
52 | [Rr]eleases/
53 | x64/
54 | x86/
55 | bld/
56 | [Bb]in/
57 | [Oo]bj/
58 | [Ll]og/
59 |
60 | # Visual Studio 2015 cache/options directory
61 | .vs/
62 | # Uncomment if you have tasks that create the project's static files in wwwroot
63 | #wwwroot/
64 |
65 | # MSTest test Results
66 | [Tt]est[Rr]esult*/
67 | [Bb]uild[Ll]og.*
68 |
69 | # NUNIT
70 | *.VisualState.xml
71 | TestResult.xml
72 |
73 | # Build Results of an ATL Project
74 | [Dd]ebugPS/
75 | [Rr]eleasePS/
76 | dlldata.c
77 |
78 | # DNX
79 | project.lock.json
80 | project.fragment.lock.json
81 | artifacts/
82 |
83 | *_i.c
84 | *_p.c
85 | *_i.h
86 | *.ilk
87 | *.meta
88 | *.obj
89 | *.pch
90 | *.pdb
91 | *.pgc
92 | *.pgd
93 | *.rsp
94 | *.sbr
95 | *.tlb
96 | *.tli
97 | *.tlh
98 | *.tmp
99 | *.tmp_proj
100 | *.log
101 | *.vspscc
102 | *.vssscc
103 | .builds
104 | *.pidb
105 | *.svclog
106 | *.scc
107 |
108 | # Chutzpah Test files
109 | _Chutzpah*
110 |
111 | # Visual C++ cache files
112 | ipch/
113 | *.aps
114 | *.ncb
115 | *.opendb
116 | *.opensdf
117 | *.sdf
118 | *.cachefile
119 | *.VC.db
120 | *.VC.VC.opendb
121 |
122 | # Visual Studio profiler
123 | *.psess
124 | *.vsp
125 | *.vspx
126 | *.sap
127 |
128 | # TFS 2012 Local Workspace
129 | $tf/
130 |
131 | # Guidance Automation Toolkit
132 | *.gpState
133 |
134 | # ReSharper is a .NET coding add-in
135 | _ReSharper*/
136 | *.[Rr]e[Ss]harper
137 | *.DotSettings.user
138 |
139 | # JustCode is a .NET coding add-in
140 | .JustCode
141 |
142 | # TeamCity is a build add-in
143 | _TeamCity*
144 |
145 | # DotCover is a Code Coverage Tool
146 | *.dotCover
147 |
148 | # NCrunch
149 | _NCrunch_*
150 | .*crunch*.local.xml
151 | nCrunchTemp_*
152 |
153 | # MightyMoose
154 | *.mm.*
155 | AutoTest.Net/
156 |
157 | # Web workbench (sass)
158 | .sass-cache/
159 |
160 | # Installshield output folder
161 | [Ee]xpress/
162 |
163 | # DocProject is a documentation generator add-in
164 | DocProject/buildhelp/
165 | DocProject/Help/*.HxT
166 | DocProject/Help/*.HxC
167 | DocProject/Help/*.hhc
168 | DocProject/Help/*.hhk
169 | DocProject/Help/*.hhp
170 | DocProject/Help/Html2
171 | DocProject/Help/html
172 |
173 | # Click-Once directory
174 | publish/
175 |
176 | # Publish Web Output
177 | *.[Pp]ublish.xml
178 | *.azurePubxml
179 | # TODO: Comment the next line if you want to checkin your web deploy settings
180 | # but database connection strings (with potential passwords) will be unencrypted
181 | #*.pubxml
182 | *.publishproj
183 |
184 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
185 | # checkin your Azure Web App publish settings, but sensitive information contained
186 | # in these scripts will be unencrypted
187 | PublishScripts/
188 |
189 | # NuGet Packages
190 | *.nupkg
191 | # The packages folder can be ignored because of Package Restore
192 | **/packages/*
193 | # except build/, which is used as an MSBuild target.
194 | !**/packages/build/
195 | # Uncomment if necessary however generally it will be regenerated when needed
196 | #!**/packages/repositories.config
197 | # NuGet v3's project.json files produces more ignoreable files
198 | *.nuget.props
199 | *.nuget.targets
200 |
201 | # Microsoft Azure Build Output
202 | csx/
203 | *.build.csdef
204 |
205 | # Microsoft Azure Emulator
206 | ecf/
207 | rcf/
208 |
209 | # Windows Store app package directories and files
210 | AppPackages/
211 | BundleArtifacts/
212 | Package.StoreAssociation.xml
213 | _pkginfo.txt
214 |
215 | # Visual Studio cache files
216 | # files ending in .cache can be ignored
217 | *.[Cc]ache
218 | # but keep track of directories ending in .cache
219 | !*.[Cc]ache/
220 |
221 | # Others
222 | ClientBin/
223 | ~$*
224 | *~
225 | *.dbmdl
226 | *.dbproj.schemaview
227 | *.jfm
228 | *.pfx
229 | *.publishsettings
230 | node_modules/
231 | orleans.codegen.cs
232 |
233 | # Since there are multiple workflows, uncomment next line to ignore bower_components
234 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
235 | #bower_components/
236 |
237 | # RIA/Silverlight projects
238 | Generated_Code/
239 |
240 | # Backup & report files from converting an old project file
241 | # to a newer Visual Studio version. Backup files are not needed,
242 | # because we have git ;-)
243 | _UpgradeReport_Files/
244 | Backup*/
245 | UpgradeLog*.XML
246 | UpgradeLog*.htm
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 |
252 | # Business Intelligence projects
253 | *.rdl.data
254 | *.bim.layout
255 | *.bim_*.settings
256 |
257 | # Microsoft Fakes
258 | FakesAssemblies/
259 |
260 | # GhostDoc plugin setting file
261 | *.GhostDoc.xml
262 |
263 | # Node.js Tools for Visual Studio
264 | .ntvs_analysis.dat
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio LightSwitch build output
273 | **/*.HTMLClient/GeneratedArtifacts
274 | **/*.DesktopClient/GeneratedArtifacts
275 | **/*.DesktopClient/ModelManifest.xml
276 | **/*.Server/GeneratedArtifacts
277 | **/*.Server/ModelManifest.xml
278 | _Pvt_Extensions
279 |
280 | # Paket dependency manager
281 | .paket/paket.exe
282 | paket-files/
283 |
284 | # FAKE - F# Make
285 | .fake/
286 |
287 | # JetBrains Rider
288 | .idea/
289 | *.sln.iml
290 |
291 | # CodeRush
292 | .cr/
293 |
294 | # Python Tools for Visual Studio (PTVS)
295 | __pycache__/
296 | *.pyc
297 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino.xcodeproj/project.xcworkspace/xcuserdata/pauli.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/Electrino/macOS/Electrino.xcodeproj/project.xcworkspace/xcuserdata/pauli.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino.xcodeproj/xcuserdata/pauli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino.xcodeproj/xcuserdata/pauli.xcuserdatad/xcschemes/Electrino.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino.xcodeproj/xcuserdata/pauli.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Electrino.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 5AA9DBAD1EB9F58A00EF7CC9
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 |
13 | @interface AppDelegate : NSObject
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "AppDelegate.h"
12 | #import "ENOJavaScriptApp.h"
13 | #import "ENOBrowserWindowController.h"
14 |
15 |
16 | @interface AppDelegate ()
17 |
18 | @end
19 |
20 |
21 |
22 |
23 | @implementation AppDelegate
24 |
25 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
26 | {
27 | // enable WebKit devtools
28 | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"WebKitDeveloperExtras"];
29 |
30 |
31 | NSString *appDir = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"app"];
32 | NSString *mainJSPath = [appDir stringByAppendingPathComponent:@"main.js"];
33 |
34 | if ( ![[NSFileManager defaultManager] fileExistsAtPath:mainJSPath]) {
35 | NSLog(@"** no main.js found in dir: %@", appDir);
36 | [NSApp terminate:nil]; // --
37 | }
38 |
39 | NSString *mainJS = [NSString stringWithContentsOfFile:mainJSPath encoding:NSUTF8StringEncoding error:NULL];
40 | ENOJavaScriptApp *jsApp = [ENOJavaScriptApp sharedApp];
41 | NSError *error = nil;
42 |
43 | // app setup
44 | jsApp.jsContext[@"__dirname"] = appDir;
45 |
46 | // load code
47 | if ( ![jsApp loadMainJS:mainJS error:&error]) {
48 | NSLog(@"** could not load main.js: %@, path: %@", error, mainJSPath);
49 |
50 | [self _presentJSError:error message:@"Main program execution failed."];
51 |
52 | [NSApp terminate:nil]; // --
53 | }
54 |
55 | // for the old-style WebView, it seems that there needs to be an instance initialized early;
56 | // otherwise it can go into a weird state where scripts and default styles don't load at all.
57 | {
58 | ENOBrowserWindowController *windowController = [[ENOBrowserWindowController alloc] initWithWindowNibName:@"ENOBrowserWindowController"];
59 | NSWindow *win = windowController.window;
60 | [win setFrame:NSMakeRect(0, 0, 1, 1) display:NO];
61 | }
62 |
63 | // send 'ready' event to the main app
64 | if ( ![jsApp.jsAppGlobalObject emitReady:&error]) {
65 | NSLog(@"** app.on('ready'): %@", error);
66 |
67 | [self _presentJSError:error message:@"Exception in app.on('ready')"];
68 | }
69 | }
70 |
71 | - (void)_presentJSError:(NSError *)error message:(NSString *)msg
72 | {
73 | NSAlert *alert = [[NSAlert alloc] init];
74 | alert.alertStyle = NSCriticalAlertStyle;
75 | alert.messageText = msg ?: @"JavaScript error";
76 | alert.informativeText = [NSString stringWithFormat:@"\n%@\n\n(On line %@)", error.localizedDescription, error.userInfo[@"SourceLineNumber"]];
77 |
78 | [alert runModal];
79 | }
80 |
81 | - (void)applicationWillTerminate:(NSNotification *)aNotification
82 | {
83 |
84 | }
85 |
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOBrowserWindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOBrowserWindowController.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 |
14 |
15 | @interface ENOBrowserWindowController : NSWindowController
16 |
17 | @property (nonatomic, strong) IBOutlet WebView *testWebView;
18 |
19 | - (instancetype)initAsResizable:(BOOL)resizable hasFrame:(BOOL)hasFrame;
20 |
21 | - (void)loadURL:(NSURL *)url;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOBrowserWindowController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOBrowserWindowController.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOBrowserWindowController.h"
12 | #import
13 |
14 |
15 | // The new WKWebView class doesn't give access to its JSContext (because it runs in a separate process);
16 | // therefore it doesn't seem suitable for hosting Electrino apps.
17 | // Let's just stick with good old WebView for now.
18 | #define USE_WKWEBVIEW 0
19 |
20 |
21 | #import "ENOJSProcess.h"
22 |
23 |
24 |
25 | @interface ENOBrowserWindowController ()
26 |
27 | #if USE_WKWEBVIEW
28 | @property (nonatomic, strong) WKWebView *webView;
29 | #else
30 | @property (nonatomic, strong) WebView *webView;
31 | #endif
32 |
33 | @end
34 |
35 |
36 |
37 | @implementation ENOBrowserWindowController
38 |
39 | - (instancetype)initAsResizable:(BOOL)resizable hasFrame:(BOOL)hasFrame
40 | {
41 | NSWindowStyleMask styleMask = 0;
42 | if (resizable) {
43 | styleMask |= NSWindowStyleMaskResizable;
44 | }
45 | if (hasFrame) {
46 | styleMask |= NSWindowStyleMaskTitled;
47 | styleMask |= NSWindowStyleMaskMiniaturizable;
48 | }
49 |
50 | NSWindow *window = [[NSWindow alloc] initWithContentRect:NSMakeRect(100, 100, 640, 480)
51 | styleMask:styleMask
52 | backing:NSBackingStoreBuffered
53 | defer:NO];
54 |
55 | window.opaque = NO;
56 | window.hasShadow = YES;
57 | window.ignoresMouseEvents = NO;
58 | window.allowsConcurrentViewDrawing = YES;
59 | window.releasedWhenClosed = NO;
60 |
61 | #if USE_WKWEBVIEW
62 | WKWebViewConfiguration *wkConf = [[WKWebViewConfiguration alloc] init];
63 |
64 | WKWebView *webView = [[WKWebView alloc] initWithFrame:window.contentView.bounds configuration:wkConf];
65 |
66 | #else
67 | WebView *webView = [[WebView alloc] initWithFrame:window.contentView.frame];
68 |
69 | webView.frameLoadDelegate = self;
70 |
71 | webView.drawsBackground = NO;
72 |
73 | WebPreferences *prefs = [webView preferences];
74 | prefs.javaScriptEnabled = YES;
75 | prefs.plugInsEnabled = NO;
76 | //prefs.defaultFontSize = 20;
77 |
78 | #endif
79 |
80 | window.contentView = webView;
81 | self.webView = webView;
82 |
83 | return [self initWithWindow:window];
84 | }
85 |
86 |
87 | - (void)loadURL:(NSURL *)url
88 | {
89 | if (url.isFileURL) {
90 | #if USE_WKWEBVIEW
91 | NSString *dir = [url.path stringByDeletingLastPathComponent];
92 | NSURL *baseURL = [NSURL fileURLWithPath:dir isDirectory:YES];
93 |
94 | NSLog(@"%s, using WKWebView, %@", __func__, url);
95 |
96 | [self.webView loadFileURL:url allowingReadAccessToURL:baseURL];
97 |
98 | #else
99 | NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
100 | [self.webView.mainFrame loadRequest:req];
101 |
102 | #endif
103 | }
104 | else {
105 | NSLog(@"** %s: only supports file urls", __func__);
106 | }
107 |
108 | }
109 |
110 | #if !USE_WKWEBVIEW
111 | - (void)webView:(WebView *)webView didCreateJavaScriptContext:(JSContext *)jsContext forFrame:(WebFrame *)frame
112 | {
113 | ENOJSProcess *process = [[ENOJSProcess alloc] init];
114 | jsContext[@"process"] = process;
115 | }
116 |
117 | - (void)webView:(WebView *)webView didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
118 | {
119 | if (frame == self.webView.mainFrame) {
120 | self.window.title = title;
121 | }
122 | }
123 | #endif
124 |
125 | @end
126 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOBrowserWindowController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSApp.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSApp.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 | @class ENOJavaScriptApp;
14 |
15 |
16 | @protocol ENOJSAppExports
17 |
18 | JSExportAs(on,
19 | - (void)on:(NSString *)event withCallback:(JSValue *)cb
20 | );
21 |
22 | @end
23 |
24 |
25 | @interface ENOJSApp : NSObject
26 |
27 | @property (nonatomic, weak) ENOJavaScriptApp *jsApp;
28 |
29 | - (BOOL)emitReady:(NSError **)outError;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSApp.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSApp.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSApp.h"
12 | #import "ENOJavaScriptApp.h"
13 |
14 |
15 | @interface ENOJSApp ()
16 |
17 | @property (nonatomic, strong) NSMutableDictionary *eventCallbacks;
18 |
19 | @end
20 |
21 |
22 | @implementation ENOJSApp
23 |
24 | - (id)init
25 | {
26 | self = [super init];
27 |
28 | self.eventCallbacks = [NSMutableDictionary dictionary];
29 |
30 | return self;
31 | }
32 |
33 | - (void)on:(NSString *)event withCallback:(JSValue *)cb
34 | {
35 | if (event.length > 0 && cb) {
36 | NSMutableArray *cbArr = self.eventCallbacks[event] ?: [NSMutableArray array];
37 | [cbArr addObject:cb];
38 |
39 | self.eventCallbacks[event] = cbArr;
40 | }
41 | }
42 |
43 | - (BOOL)emitReady:(NSError **)outError
44 | {
45 | self.jsApp.lastException = nil;
46 |
47 | for (JSValue *cb in self.eventCallbacks[@"ready"]) {
48 | //NSLog(@"%s, %@", __func__, cb);
49 |
50 | [cb callWithArguments:@[]];
51 |
52 | if (self.jsApp.lastException) {
53 | if (outError) {
54 | *outError = [NSError errorWithDomain:kENOJavaScriptErrorDomain
55 | code:102
56 | userInfo:@{
57 | NSLocalizedDescriptionKey: self.jsApp.lastException,
58 | @"SourceLineNumber": @(self.jsApp.lastExceptionLine),
59 | }];
60 | }
61 | return NO;
62 | }
63 | }
64 | return YES;
65 | }
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSBrowserWindow.h:
--------------------------------------------------------------------------------
1 | ;//
2 | // ENOJSBrowserWindow.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 | #import "ENOBrowserWindowController.h"
14 |
15 |
16 | @protocol ENOJSBrowserWindowExports
17 |
18 | - (instancetype)initWithOptions:(NSDictionary *)opts;
19 |
20 | - (void)loadURL:(NSString *)url;
21 |
22 | - (BOOL)isVisible;
23 | - (void)show;
24 | - (void)hide;
25 | - (void)focus;
26 |
27 | - (NSDictionary *)getBounds;
28 |
29 | JSExportAs(setPosition,
30 | - (void)setPositionX:(double)x y:(double)y
31 | );
32 |
33 | JSExportAs(on,
34 | - (void)on:(NSString *)event withCallback:(JSValue *)cb
35 | );
36 |
37 | @end
38 |
39 |
40 | @interface ENOJSBrowserWindow : NSObject
41 |
42 | @property (nonatomic, strong) ENOBrowserWindowController *windowController;
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSBrowserWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSBrowserWindow.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSBrowserWindow.h"
12 | #import "ENOBrowserWindowController.h"
13 |
14 |
15 | @interface ENOJSBrowserWindow ()
16 |
17 | @property (nonatomic, strong) NSMutableDictionary *eventCallbacks;
18 |
19 | @end
20 |
21 |
22 | @implementation ENOJSBrowserWindow
23 |
24 | - (instancetype)initWithOptions:(NSDictionary *)opts
25 | {
26 | self = [super init];
27 |
28 | //NSLog(@"%s, %@", __func__, opts);
29 |
30 | self.eventCallbacks = [NSMutableDictionary dictionary];
31 |
32 | id val;
33 | BOOL show = YES;
34 | BOOL resizable = YES;
35 | BOOL hasFrame = YES;
36 | if ((val = opts[@"show"])) {
37 | show = [val boolValue];
38 | }
39 | if ((val = opts[@"resizable"])) {
40 | resizable = [val boolValue];
41 | }
42 | if ((val = opts[@"frame"])) {
43 | hasFrame = [val boolValue];
44 | }
45 |
46 | self.windowController = [[ENOBrowserWindowController alloc] initAsResizable:resizable hasFrame:hasFrame];
47 |
48 | NSWindow *win = self.windowController.window;
49 | NSRect frame = win.frame;
50 | if ((val = opts[@"width"]) && [val integerValue] > 0) {
51 | frame.size.width = [val doubleValue];
52 | }
53 | if ((val = opts[@"height"]) && [val integerValue] > 0) {
54 | frame.size.height = [val doubleValue];
55 | }
56 |
57 | [win setFrame:frame display:NO];
58 | [win center];
59 |
60 | if (show)
61 | [self show];
62 |
63 | return self;
64 | }
65 |
66 | - (void)loadURL:(NSString *)urlStr
67 | {
68 | NSURL *url = [NSURL URLWithString:urlStr];
69 |
70 | [self.windowController loadURL:url];
71 | }
72 |
73 | - (void)on:(NSString *)event withCallback:(JSValue *)cb
74 | {
75 | if (event.length > 0 && cb) {
76 | NSMutableArray *cbArr = self.eventCallbacks[event] ?: [NSMutableArray array];
77 | [cbArr addObject:cb];
78 |
79 | self.eventCallbacks[event] = cbArr;
80 | }
81 | }
82 |
83 | - (BOOL)isVisible
84 | {
85 | return self.windowController.window.visible;
86 | }
87 |
88 | - (void)show
89 | {
90 | [self.windowController showWindow:nil];
91 | }
92 |
93 | - (void)hide
94 | {
95 | [self.windowController.window orderOut:nil];
96 | }
97 |
98 | - (void)focus
99 | {
100 | [self.windowController.window makeKeyWindow];
101 | }
102 |
103 | - (void)setPositionX:(double)x y:(double)y
104 | {
105 | NSRect r = self.windowController.window.frame;
106 | r.origin = NSMakePoint(x, y - r.size.height);
107 |
108 | //NSLog(@"setting window frame: %@", NSStringFromRect(r));
109 | [self.windowController.window setFrameOrigin:r.origin];
110 | }
111 |
112 | - (NSDictionary *)getBounds
113 | {
114 | NSRect r = self.windowController.window.frame;
115 |
116 | return @{
117 | @"x": @(r.origin.x),
118 | @"y": @(r.origin.y),
119 | @"width": @(r.size.width),
120 | @"height": @(r.size.height),
121 | };
122 | }
123 |
124 |
125 | @end
126 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSConsole.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSConsole.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 |
14 |
15 | @protocol ENOJSConsoleExports
16 |
17 | @property (nonatomic, copy) void (^log)(NSString *str);
18 |
19 | @end
20 |
21 |
22 | @interface ENOJSConsole : NSObject
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSConsole.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSConsole.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSConsole.h"
12 |
13 |
14 | @implementation ENOJSConsole
15 |
16 | @synthesize log;
17 |
18 | - (id)init
19 | {
20 | self = [super init];
21 |
22 | self.log = ^(NSString *str){
23 | NSArray *args = [JSContext currentArguments];
24 |
25 | if (args.count > 1) {
26 | NSString *argsStr = [[args subarrayWithRange:NSMakeRange(1, args.count - 1)] componentsJoinedByString:@", "];
27 | str = [str stringByAppendingFormat:@" %@", argsStr];
28 | }
29 |
30 | NSLog(@"JS: %@", str);
31 | };
32 |
33 | return self;
34 | }
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSIPCMain.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSIPCMain.h
3 | // Electrino
4 | //
5 | // Created by Pauli Ojala on 17/05/2017.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 |
14 |
15 | @protocol ENOJSIPCMainExports
16 |
17 | JSExportAs(on,
18 | - (void)on:(NSString *)event withCallback:(JSValue *)cb
19 | );
20 |
21 | @end
22 |
23 |
24 | @interface ENOJSIPCMain : NSObject
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSIPCMain.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSIPCMain.m
3 | // Electrino
4 | //
5 | // Created by Pauli Ojala on 17/05/2017.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSIPCMain.h"
12 |
13 |
14 | @interface ENOJSIPCMain ()
15 |
16 | @property (nonatomic, strong) NSMutableDictionary *eventCallbacks;
17 |
18 | @end
19 |
20 |
21 | @implementation ENOJSIPCMain
22 |
23 | - (id)init
24 | {
25 | self.eventCallbacks = [NSMutableDictionary dictionary];
26 |
27 | return self;
28 | }
29 |
30 | - (void)on:(NSString *)event withCallback:(JSValue *)cb
31 | {
32 | if (event.length > 0 && cb) {
33 | NSMutableArray *cbArr = self.eventCallbacks[event] ?: [NSMutableArray array];
34 | [cbArr addObject:cb];
35 |
36 | self.eventCallbacks[event] = cbArr;
37 | }
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSNativeImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSNativeImage.h
3 | // Electrino
4 | //
5 | // Created by Pauli Ojala on 17/05/2017.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 |
14 |
15 | @protocol ENOJSNativeImageAPIExports
16 |
17 | - (id)createFromDataURL:(NSString *)dataURL;
18 |
19 | @end
20 |
21 |
22 | @interface ENOJSNativeImageAPI : NSObject
23 |
24 | @end
25 |
26 |
27 | @interface ENOJSNativeImageInstance : NSObject
28 |
29 | @property (nonatomic, strong) NSImage *image;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSNativeImage.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSNativeImage.m
3 | // Electrino
4 | //
5 | // Created by Pauli Ojala on 17/05/2017.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSNativeImage.h"
12 |
13 |
14 | @implementation ENOJSNativeImageAPI
15 |
16 | - (id)createFromDataURL:(NSString *)dataURL
17 | {
18 | NSString *pngPrefix = @"data:image/png;base64,";
19 | if ( ![dataURL hasPrefix:pngPrefix]) {
20 | NSLog(@"** %s: invalid data url", __func__);
21 | return nil; // --
22 | }
23 |
24 | NSString *base64Str = [dataURL substringFromIndex:pngPrefix.length];
25 |
26 | NSData *data = [[NSData alloc] initWithBase64EncodedString:base64Str options:NSDataBase64DecodingIgnoreUnknownCharacters];
27 | NSImage *image = [[NSImage alloc] initWithData:data];
28 |
29 | ENOJSNativeImageInstance *jsImage = [[ENOJSNativeImageInstance alloc] init];
30 | jsImage.image = image;
31 |
32 | return jsImage;
33 | }
34 |
35 | @end
36 |
37 |
38 |
39 | @implementation ENOJSNativeImageInstance
40 | @end
41 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSPath.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSPath.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 |
14 |
15 | @protocol ENOJSPathExports
16 |
17 | @property (nonatomic, copy) NSString *(^join)();
18 |
19 | @end
20 |
21 |
22 |
23 | @interface ENOJSPath : NSObject
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSPath.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSPath.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSPath.h"
12 |
13 |
14 | @implementation ENOJSPath
15 |
16 | @synthesize join;
17 |
18 | - (id)init
19 | {
20 | self = [super init];
21 |
22 | self.join = ^NSString *(){
23 | NSArray *args = [JSContext currentArguments];
24 | NSString *pathSep = @"/";
25 |
26 | return [args componentsJoinedByString:pathSep];
27 | };
28 |
29 | return self;
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSProcess.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSProcess.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 |
14 |
15 | @protocol ENOJSProcessExports
16 |
17 | @property (nonatomic, copy) NSString *platform;
18 | @property (nonatomic, copy) NSDictionary *versions;
19 |
20 | @end
21 |
22 |
23 | @interface ENOJSProcess : NSObject
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSProcess.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSProcess.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSProcess.h"
12 |
13 |
14 | @implementation ENOJSProcess
15 |
16 | @synthesize platform;
17 | @synthesize versions;
18 |
19 |
20 | - (id)init
21 | {
22 | self = [super init];
23 |
24 | self.platform = @"darwin";
25 |
26 | self.versions = @{
27 | @"electrino": @"0.0.1"
28 | };
29 |
30 | return self;
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSTray.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSTray.h
3 | // Electrino
4 | //
5 | // Created by Pauli Ojala on 17/05/2017.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 |
14 |
15 | @protocol ENOJSTrayExports
16 |
17 | - (instancetype)initWithIcon:(id)icon;
18 |
19 | JSExportAs(on,
20 | - (void)on:(NSString *)event withCallback:(JSValue *)cb
21 | );
22 |
23 | - (NSDictionary *)getBounds;
24 |
25 | @end
26 |
27 |
28 | @interface ENOJSTray : NSObject
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSTray.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSTray.m
3 | // Electrino
4 | //
5 | // Created by Pauli Ojala on 17/05/2017.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSTray.h"
12 | #import "ENOJSNativeImage.h"
13 |
14 |
15 | @interface ENOJSTray ()
16 |
17 | @property (nonatomic, strong) NSMutableDictionary *eventCallbacks;
18 |
19 | @property (nonatomic, strong) NSStatusItem *statusItem;
20 |
21 | @end
22 |
23 |
24 | @implementation ENOJSTray
25 |
26 | - (instancetype)initWithIcon:(id)icon
27 | {
28 | self = [super init];
29 |
30 | NSLog(@"%s: %@", __func__, icon);
31 |
32 | self.eventCallbacks = [NSMutableDictionary dictionary];
33 |
34 |
35 | self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
36 | self.statusItem.highlightMode = YES;
37 |
38 | NSStatusBarButton *barButton = self.statusItem.button;
39 | barButton.action = @selector(statusBarButtonAction:);
40 | barButton.target = self;
41 |
42 | NSImage *image = nil;
43 | if ([icon respondsToSelector:@selector(image)]) {
44 | image = [icon image];
45 | }
46 | if (image) {
47 | image.template = YES;
48 | barButton.image = image;
49 | }
50 | else {
51 | barButton.title = @"E";
52 | barButton.font = [NSFont systemFontOfSize:17.0 weight:NSFontWeightBlack];
53 | }
54 |
55 |
56 | return self;
57 | }
58 |
59 | - (void)on:(NSString *)event withCallback:(JSValue *)cb
60 | {
61 | if (event.length > 0 && cb) {
62 | NSMutableArray *cbArr = self.eventCallbacks[event] ?: [NSMutableArray array];
63 | [cbArr addObject:cb];
64 |
65 | self.eventCallbacks[event] = cbArr;
66 | }
67 | }
68 |
69 | - (NSDictionary *)getBounds
70 | {
71 | NSView *view = self.statusItem.button;
72 | NSRect frameInWindow = [view convertRect:view.bounds toView:nil];
73 | NSRect frameOnScreen = [view.window convertRectToScreen:frameInWindow];
74 |
75 | //NSLog(@"frame %@ - window %@ - screen %@ / %p, %p", NSStringFromRect(view.frame), NSStringFromRect(frameInWindow), NSStringFromRect(frameOnScreen), view, view.window);
76 |
77 | return @{
78 | @"x": @(frameOnScreen.origin.x),
79 | @"y": @(frameOnScreen.origin.y),
80 | @"width": @(frameOnScreen.size.width),
81 | @"height": @(frameOnScreen.size.width),
82 | };
83 | }
84 |
85 |
86 | #pragma mark --- actions ---
87 |
88 | - (IBAction)statusBarButtonAction:(id)sender
89 | {
90 | //NSStatusBarButton *barButton = self.statusItem.button;
91 |
92 | for (JSValue *cb in self.eventCallbacks[@"click"]) {
93 | //NSLog(@"%s, %@", __func__, cb);
94 |
95 | [cb callWithArguments:@[]];
96 | }
97 |
98 | /*
99 | if (self.popover.shown) {
100 | [self.popover close];
101 | } else {
102 | [self.popover showRelativeToRect:barButton.bounds ofView:barButton preferredEdge:NSMinYEdge];
103 |
104 | if ( !self.popoverTransiencyMonitor) {
105 | self.popoverTransiencyMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDownMask | NSRightMouseDownMask | NSKeyUpMask) handler:^(NSEvent *event) {
106 | [NSEvent removeMonitor:self.popoverTransiencyMonitor];
107 | self.popoverTransiencyMonitor = nil;
108 | [self.popover close];
109 | }];
110 | }
111 | }*/
112 | }
113 |
114 |
115 | @end
116 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSUrl.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSUrl.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 |
14 |
15 | @protocol ENOJSUrlExports
16 |
17 | @property (nonatomic, copy) NSString *(^format)(NSDictionary *urlDict);
18 |
19 | @end
20 |
21 |
22 |
23 | @interface ENOJSUrl : NSObject
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJSUrl.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJSUrl.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJSUrl.h"
12 |
13 |
14 | @implementation ENOJSUrl
15 |
16 | @synthesize format;
17 |
18 | - (id)init
19 | {
20 | self = [super init];
21 |
22 | self.format = ^NSString *(NSDictionary *urlDict){
23 | NSString *protocol = urlDict[@"protocol"];
24 | NSString *path = urlDict[@"pathname"];
25 |
26 | //NSLog(@"%s, %@", __func__, urlDict);
27 |
28 | return [NSString stringWithFormat:@"%@//%@", protocol, path];
29 | };
30 |
31 | return self;
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJavaScriptApp.h:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJavaScriptApp.h
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 | #import
13 | #import "ENOJSApp.h"
14 |
15 |
16 | extern NSString * const kENOJavaScriptErrorDomain;
17 |
18 |
19 | @interface ENOJavaScriptApp : NSObject
20 |
21 | + (instancetype)sharedApp;
22 |
23 | @property (nonatomic, readonly) JSContext *jsContext;
24 |
25 | @property (nonatomic, readonly) ENOJSApp *jsAppGlobalObject;
26 |
27 | @property (nonatomic, strong) NSString *lastException;
28 | @property (nonatomic, assign) NSInteger lastExceptionLine;
29 |
30 |
31 | - (BOOL)loadMainJS:(NSString *)js error:(NSError **)outError;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/ENOJavaScriptApp.m:
--------------------------------------------------------------------------------
1 | //
2 | // ENOJavaScriptApp.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import "ENOJavaScriptApp.h"
12 | #import "ENOJSPath.h"
13 | #import "ENOJSUrl.h"
14 | #import "ENOJSBrowserWindow.h"
15 | #import "ENOJSApp.h"
16 | #import "ENOJSProcess.h"
17 | #import "ENOJSConsole.h"
18 | #import "ENOJSTray.h"
19 | #import "ENOJSNativeImage.h"
20 | #import "ENOJSIPCMain.h"
21 |
22 |
23 | NSString * const kENOJavaScriptErrorDomain = @"ENOJavaScriptErrorDomain";
24 |
25 |
26 | @interface ENOJavaScriptApp ()
27 |
28 | @property (nonatomic, strong) JSVirtualMachine *jsVM;
29 | @property (nonatomic, strong) JSContext *jsContext;
30 | @property (nonatomic, strong) NSDictionary *jsModules;
31 | @property (nonatomic, strong) ENOJSApp *jsAppGlobalObject;
32 | @property (nonatomic, strong) ENOJSIPCMain *jsIPCMain;
33 |
34 | @property (nonatomic, assign) BOOL inException;
35 |
36 | @end
37 |
38 |
39 | @implementation ENOJavaScriptApp
40 |
41 | + (instancetype)sharedApp
42 | {
43 | static ENOJavaScriptApp *s_app = nil;
44 | static dispatch_once_t onceToken;
45 | dispatch_once(&onceToken, ^{
46 | s_app = [[self alloc] init];
47 | });
48 | return s_app;
49 | }
50 |
51 | - (id)init
52 | {
53 | self = [super init];
54 |
55 |
56 | self.jsVM = [[JSVirtualMachine alloc] init];
57 | self.jsContext = [[JSContext alloc] initWithVirtualMachine:self.jsVM];
58 |
59 | self.jsAppGlobalObject = [[ENOJSApp alloc] init];
60 | self.jsAppGlobalObject.jsApp = self;
61 |
62 | self.jsIPCMain = [[ENOJSIPCMain alloc] init];
63 |
64 | // initialize available modules
65 |
66 | NSMutableDictionary *modules = [NSMutableDictionary dictionary];
67 |
68 | modules[@"electrino"] = @{
69 | // singletons
70 | @"app": self.jsAppGlobalObject,
71 | @"ipcMain": self.jsIPCMain,
72 | @"nativeImage": [[ENOJSNativeImageAPI alloc] init],
73 |
74 | // classes that can be constructed
75 | @"BrowserWindow": [ENOJSBrowserWindow class],
76 | @"Tray": [ENOJSTray class],
77 | };
78 |
79 | modules[@"path"] = [[ENOJSPath alloc] init];
80 | modules[@"url"] = [[ENOJSUrl alloc] init];
81 |
82 | self.jsModules = modules;
83 |
84 |
85 | // add exception handler and global functions
86 |
87 | __block __weak ENOJavaScriptApp *weakSelf = self;
88 |
89 | self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
90 | [weakSelf _jsException:exception];
91 | };
92 |
93 | self.jsContext[@"require"] = ^(NSString *arg) {
94 | id module = weakSelf.jsModules[arg];
95 | return module;
96 | };
97 |
98 | self.jsContext[@"process"] = [[ENOJSProcess alloc] init];
99 | self.jsContext[@"console"] = [[ENOJSConsole alloc] init];
100 |
101 | return self;
102 | }
103 |
104 | - (void)dealloc
105 | {
106 | self.jsContext.exceptionHandler = NULL;
107 | self.jsContext[@"require"] = nil;
108 | }
109 |
110 | - (void)_jsException:(JSValue *)exception
111 | {
112 | NSLog(@"%s, %@", __func__, exception);
113 |
114 | if (self.inException) { // prevent recursion, just in case
115 | return; // --
116 | }
117 |
118 | self.inException = YES;
119 |
120 | self.lastException = exception.toString;
121 | self.lastExceptionLine = [exception valueForProperty:@"line"].toInt32;
122 |
123 | self.inException = NO;
124 | }
125 |
126 | - (BOOL)loadMainJS:(NSString *)js error:(NSError **)outError
127 | {
128 | self.lastException = nil;
129 |
130 | NSLog(@"%s...", __func__);
131 |
132 | [self.jsContext evaluateScript:js];
133 |
134 | if (self.lastException) {
135 | if (outError) {
136 | *outError = [NSError errorWithDomain:kENOJavaScriptErrorDomain
137 | code:101
138 | userInfo:@{
139 | NSLocalizedDescriptionKey: self.lastException,
140 | @"SourceLineNumber": @(self.lastExceptionLine),
141 | }];
142 | }
143 | return NO; // --
144 | }
145 |
146 | NSLog(@"%s done", __func__);
147 |
148 | return YES;
149 | }
150 |
151 |
152 |
153 |
154 | @end
155 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | Copyright © 2017 Pauli Olavi Ojala
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Electrino/macOS/Electrino/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Electrino
4 | //
5 | // Created by Pauli Olavi Ojala on 03/05/17.
6 | // Copyright © 2017 Pauli Olavi Ojala.
7 | //
8 | // This software may be modified and distributed under the terms of the MIT license. See the LICENSE file for details.
9 | //
10 |
11 | #import
12 |
13 | int main(int argc, const char * argv[]) {
14 | return NSApplicationMain(argc, argv);
15 | }
16 |
--------------------------------------------------------------------------------
/Electrino/test-app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello World!
6 |
7 |
8 | Hello World!
9 | We are using Electrino .
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Electrino/test-app/main.js:
--------------------------------------------------------------------------------
1 | const {app, BrowserWindow} = require('electrino')
2 | const path = require('path')
3 | const url = require('url')
4 |
5 | // Keep a global reference of the window object, if you don't, the window will
6 | // be closed automatically when the JavaScript object is garbage collected.
7 | let win
8 |
9 | function createWindow () {
10 | // Create the browser window.
11 | win = new BrowserWindow({width: 800, height: 600})
12 |
13 | // and load the index.html of the app.
14 | win.loadURL(url.format({
15 | pathname: path.join(__dirname, 'index.html'),
16 | protocol: 'file:',
17 | slashes: true
18 | }))
19 |
20 | // Open the DevTools.
21 | win.webContents.openDevTools()
22 |
23 | // Emitted when the window is closed.
24 | win.on('closed', () => {
25 | // Dereference the window object, usually you would store windows
26 | // in an array if your app supports multi windows, this is the time
27 | // when you should delete the corresponding element.
28 | win = null
29 | })
30 | }
31 |
32 | // This method will be called when Electron has finished
33 | // initialization and is ready to create browser windows.
34 | // Some APIs can only be used after this event occurs.
35 | app.on('ready', createWindow)
36 |
37 | // Quit when all windows are closed.
38 | app.on('window-all-closed', () => {
39 | // On macOS it is common for applications and their menu bar
40 | // to stay active until the user quits explicitly with Cmd + Q
41 | if (process.platform !== 'darwin') {
42 | app.quit()
43 | }
44 | })
45 |
46 | app.on('activate', () => {
47 | // On macOS it's common to re-create a window in the app when the
48 | // dock icon is clicked and there are no other windows open.
49 | if (win === null) {
50 | createWindow()
51 | }
52 | })
53 |
--------------------------------------------------------------------------------
/Electrino/test-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "your-app",
3 | "version" : "0.1.0",
4 | "main" : "main.js"
5 | }
--------------------------------------------------------------------------------
/Electrino/test-tray/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Sample Menubar App
4 |
5 |
6 |
7 | Hello Menubar App
8 |
9 |
--------------------------------------------------------------------------------
/Electrino/test-tray/index.js:
--------------------------------------------------------------------------------
1 |
2 | console.log("index.js loading")
3 |
4 | document.addEventListener('DOMContentLoaded', () => {
5 | console.log("index.js dom loaded")
6 |
7 | let n = new Notification('You did it!', {
8 | body: 'Nice work.'
9 | })
10 |
11 | // Tell the notification to show the menubar popup window on click
12 | n.onclick = () => { ipcRenderer.send('show-window') }
13 |
14 | })
15 |
--------------------------------------------------------------------------------
/Electrino/test-tray/main.js:
--------------------------------------------------------------------------------
1 | const {app, BrowserWindow, ipcMain, Tray, nativeImage} = require('electrino')
2 | const path = require('path')
3 |
4 | const assetsDir = path.join(__dirname, 'assets')
5 |
6 | let tray = undefined
7 | let window = undefined
8 |
9 | app.on('ready', () => {
10 | // Setup the menubar with an icon
11 |
12 | let icon = nativeImage.createFromDataURL(base64Icon)
13 | tray = new Tray(icon)
14 |
15 | // Add a click handler so that when the user clicks on the menubar icon, it shows
16 | // our popup window
17 | tray.on('click', function(event) {
18 | toggleWindow()
19 |
20 | // Show devtools when command clicked
21 | if (window.isVisible() && process.defaultApp && event.metaKey) {
22 | window.openDevTools({mode: 'detach'})
23 | }
24 | })
25 |
26 | // Make the popup window for the menubar
27 | window = new BrowserWindow({
28 | width: 300,
29 | height: 350,
30 | show: false,
31 | frame: false,
32 | resizable: false,
33 | })
34 |
35 | // Tell the popup window to load our index.html file
36 | window.loadURL(`file://${path.join(__dirname, 'index.html')}`)
37 |
38 | // Only close the window on blur if dev tools isn't opened
39 | window.on('blur', () => {
40 | if(!window.webContents.isDevToolsOpened()) {
41 | window.hide()
42 | }
43 | })
44 | })
45 |
46 | const toggleWindow = () => {
47 | if (window.isVisible()) {
48 | window.hide()
49 | } else {
50 | showWindow()
51 | }
52 | }
53 |
54 | const showWindow = () => {
55 | const trayPos = tray.getBounds()
56 | const windowPos = window.getBounds()
57 | let x, y = 0
58 | if (process.platform == 'darwin') {
59 | x = Math.round(trayPos.x + (trayPos.width / 2) - (windowPos.width / 2))
60 | y = Math.round(trayPos.y + trayPos.height)
61 | } else {
62 | x = Math.round(trayPos.x + (trayPos.width / 2) - (windowPos.width / 2))
63 | y = Math.round(trayPos.y + trayPos.height * 10)
64 | }
65 |
66 |
67 | window.setPosition(x, y, false)
68 | window.show()
69 | window.focus()
70 | }
71 |
72 | ipcMain.on('show-window', () => {
73 | showWindow()
74 | })
75 |
76 | app.on('window-all-closed', () => {
77 | // On macOS it is common for applications and their menu bar
78 | // to stay active until the user quits explicitly with Cmd + Q
79 | if (process.platform !== 'darwin') {
80 | app.quit()
81 | }
82 | })
83 |
84 | // Tray Icon as Base64 so tutorial has less overhead
85 | let base64Icon = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw
86 | 7AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AkZCg87wZW7ewA
87 | AAp1JREFUOMuV1U2IVlUcx/HPnbc0MWwEF40hRWRQmWhEUi4KorlTQ0zQKgqSxKinRYuWrdq0iIp8DAy
88 | CFmYUUVTYY0Qw0SsYVDQRlFlQU4o4VDMUY9NzWtz/45znzo3yv7n/l3O+53fOPS+F/7R9G0l34Vlap/x
89 | PG+gPby76471jpJdxI4p/x5QrakPVZ3yI4lLSLH4LpetIT5N24AWKpZXAW4boXogFnGxQXEzhdQYHl0v
90 | pbtJkBIOkBqXpVhzAWIPi8hocxCyH5qp0e10oHY6BNy3P7szULyc9hzkGTjat8WPRqctkD3QORrJ211J
91 | srPV7CKP4i7S6CXxF+GtY2lG5D5yg+D6bckHaRXs463dV+OtJVzeBj4Q/inuy2uf4NYPvyVR38Vn4GzD
92 | ZAC5ezHbITsqtEU8HvGcjpFblDncpDma16yhvqit+c3mLuQj3Vm7rJ4r3kW+z+6sD80aKQWcivwm318B
93 | pHk9mA11PuSXil/B1thyrSA9HMI8nMtYNlDszcKdbHVcLkduCO0L1VxTv1VTv5plR3lrCuzga+c2YqB2
94 | QNEfqjV7EWl8c8X78kKleTTfWeuA49maDjlNuz8CHFykOYDEabKvg0Jqh+AB/Z4D7qs+h03gbxyK/FVf
95 | WL6FfsC/8tdGoZ0/hRKZ6A+2pUP1jdZecse01cGcBr2YNzqdcG6q/oDgS+7e3XLeF6j/wTvzM6Lfi2nQ
96 | KP8e0P6Ezn9X2488MvLnW75vwP2wCr8J5eD4upsxaHZzOwNNZcU2c3FfwWg1cDuISfIxH6fzedE8G90s
97 | 8nuXH8B0eoXNc/6tQjsQfXaQz0/BEXUD3W4oF0hQPflTlJwZIl+FcOp86e2vvoj1Le6I/P974ZA2dBXk
98 | 97qQ13Z8+3PS0+AdjKa1R95YOZgAAAABJRU5ErkJggg==`
99 |
100 |
--------------------------------------------------------------------------------
/Electrino/test-tray/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "your-app",
3 | "version" : "0.1.0",
4 | "main" : "main.js"
5 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26430.6
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Electrino", "Electrino\Electrino.csproj", "{1AF63BD2-3E24-4B9D-9336-B97EA3580C09}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderAPI", "RenderAPI\RenderAPI.csproj", "{77B6E3D3-17E6-46CB-B699-C118776F54DE}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|ARM = Debug|ARM
14 | Debug|x64 = Debug|x64
15 | Debug|x86 = Debug|x86
16 | Release|Any CPU = Release|Any CPU
17 | Release|ARM = Release|ARM
18 | Release|x64 = Release|x64
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|Any CPU.ActiveCfg = Debug|x86
23 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|ARM.ActiveCfg = Debug|ARM
24 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|ARM.Build.0 = Debug|ARM
25 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|ARM.Deploy.0 = Debug|ARM
26 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|x64.ActiveCfg = Debug|x64
27 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|x64.Build.0 = Debug|x64
28 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|x64.Deploy.0 = Debug|x64
29 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|x86.ActiveCfg = Debug|x86
30 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|x86.Build.0 = Debug|x86
31 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Debug|x86.Deploy.0 = Debug|x86
32 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|Any CPU.ActiveCfg = Release|x86
33 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|ARM.ActiveCfg = Release|ARM
34 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|ARM.Build.0 = Release|ARM
35 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|ARM.Deploy.0 = Release|ARM
36 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|x64.ActiveCfg = Release|x64
37 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|x64.Build.0 = Release|x64
38 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|x64.Deploy.0 = Release|x64
39 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|x86.ActiveCfg = Release|x86
40 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|x86.Build.0 = Release|x86
41 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}.Release|x86.Deploy.0 = Release|x86
42 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Debug|ARM.ActiveCfg = Debug|ARM
45 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Debug|ARM.Build.0 = Debug|ARM
46 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Debug|x64.ActiveCfg = Debug|x64
47 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Debug|x64.Build.0 = Debug|x64
48 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Debug|x86.ActiveCfg = Debug|x86
49 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Debug|x86.Build.0 = Debug|x86
50 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Release|Any CPU.Build.0 = Release|Any CPU
52 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Release|ARM.ActiveCfg = Release|ARM
53 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Release|ARM.Build.0 = Release|ARM
54 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Release|x64.ActiveCfg = Release|x64
55 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Release|x64.Build.0 = Release|x64
56 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Release|x86.ActiveCfg = Release|x86
57 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}.Release|x86.Build.0 = Release|x86
58 | EndGlobalSection
59 | GlobalSection(SolutionProperties) = preSolution
60 | HideSolutionNode = FALSE
61 | EndGlobalSection
62 | EndGlobal
63 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.ApplicationModel;
7 | using Windows.ApplicationModel.Activation;
8 | using Windows.Foundation;
9 | using Windows.Foundation.Collections;
10 | using Windows.UI.Xaml;
11 | using Windows.UI.Xaml.Controls;
12 | using Windows.UI.Xaml.Controls.Primitives;
13 | using Windows.UI.Xaml.Data;
14 | using Windows.UI.Xaml.Input;
15 | using Windows.UI.Xaml.Media;
16 | using Windows.UI.Xaml.Navigation;
17 | using System.Diagnostics;
18 | using System.Threading.Tasks;
19 | using Windows.Storage;
20 | using Windows.UI.ViewManagement;
21 |
22 | namespace Electrino
23 | {
24 | ///
25 | /// Provides application-specific behavior to supplement the default Application class.
26 | ///
27 | sealed partial class App : Application
28 | {
29 | private JavaScriptApp jsApp = new JavaScriptApp();
30 | private static App instance;
31 | private LaunchActivatedEventArgs launchArgs;
32 |
33 | ///
34 | /// Initializes the singleton application object. This is the first line of authored code
35 | /// executed, and as such is the logical equivalent of main() or WinMain().
36 | ///
37 | public App()
38 | {
39 | instance = this;
40 | this.InitializeComponent();
41 | this.Suspending += OnSuspending;
42 | }
43 |
44 | public static void Log(string msg)
45 | {
46 | #if DEBUG
47 | Debug.WriteLine(msg);
48 | #endif
49 | }
50 |
51 | private async void Run()
52 | {
53 | string js = await ReadJS("main.js");
54 | Log(jsApp.Init());
55 | Log(jsApp.RunScript(js));
56 | Ready();
57 | }
58 |
59 | private async Task ReadJS(string filename)
60 | {
61 | StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///test-app/" + filename));
62 | string js;
63 | using (StreamReader sRead = new StreamReader(await file.OpenStreamForReadAsync()))
64 | js = await sRead.ReadToEndAsync();
65 | return js;
66 | }
67 |
68 | ///
69 | /// Invoked when the application is launched normally by the end user. Other entry points
70 | /// will be used such as when the application is launched to open a specific file.
71 | ///
72 | /// Details about the launch request and process.
73 | protected override void OnLaunched(LaunchActivatedEventArgs e)
74 | {
75 | launchArgs = e;
76 | Run();
77 | }
78 |
79 | private void Ready() {
80 | if (JS.JSApp.GetInstance() != null)
81 | {
82 | JS.JSApp.GetInstance().Call("ready");
83 | }
84 | }
85 |
86 | private void Suspended()
87 | {
88 | if (JS.JSApp.GetInstance() != null)
89 | {
90 | JS.JSApp.GetInstance().Call("window-all-closed");
91 | }
92 | }
93 |
94 | public static void NewWindow(int width, int height)
95 | {
96 | if (instance == null)
97 | {
98 | Log("App no ready yet");
99 | return;
100 | }
101 | App.instance._NewWindow(width, height);
102 | }
103 |
104 | private void _NewWindow(int width, int height)
105 | {
106 | ApplicationView.PreferredLaunchViewSize = new Size(width, height);
107 | ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
108 |
109 | Frame rootFrame = Window.Current.Content as Frame;
110 |
111 | // Do not repeat app initialization when the Window already has content,
112 | // just ensure that the window is active
113 | if (rootFrame == null)
114 | {
115 | // Create a Frame to act as the navigation context and navigate to the first page
116 | rootFrame = new Frame();
117 |
118 | rootFrame.NavigationFailed += OnNavigationFailed;
119 |
120 | // Place the frame in the current Window
121 | Window.Current.Content = rootFrame;
122 | }
123 |
124 | if (rootFrame.Content == null)
125 | {
126 | // When the navigation stack isn't restored navigate to the first page,
127 | // configuring the new page by passing required information as a navigation
128 | // parameter
129 | rootFrame.Navigate(typeof(MainPage), launchArgs.Arguments);
130 | }
131 | // Ensure the current window is active
132 | Window.Current.Activate();
133 | }
134 |
135 | ///
136 | /// Invoked when Navigation to a certain page fails
137 | ///
138 | /// The Frame which failed navigation
139 | /// Details about the navigation failure
140 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
141 | {
142 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
143 | }
144 |
145 | ///
146 | /// Invoked when application execution is being suspended. Application state is saved
147 | /// without knowing whether the application will be terminated or resumed with the contents
148 | /// of memory still intact.
149 | ///
150 | /// The source of the suspend request.
151 | /// Details about the suspend request.
152 | private void OnSuspending(object sender, SuspendingEventArgs e)
153 | {
154 | var deferral = e.SuspendingOperation.GetDeferral();
155 | //TODO: Save application state and stop any background activity
156 | deferral.Complete();
157 | Suspended();
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Assets/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/Electrino/win10/Electrino/Assets/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/Electrino/win10/Electrino/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/Electrino/win10/Electrino/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/Electrino/win10/Electrino/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/Electrino/win10/Electrino/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/Electrino/win10/Electrino/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/Electrino/win10/Electrino/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Electrino.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x86
7 | {1AF63BD2-3E24-4B9D-9336-B97EA3580C09}
8 | AppContainerExe
9 | Properties
10 | Electrino
11 | Electrino
12 | en-US
13 | UAP
14 | 10.0.15063.0
15 | 10.0.10586.0
16 | 14
17 | 512
18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | true
20 | Electrino_TemporaryKey.pfx
21 | True
22 | Always
23 | x86|x64|arm
24 |
25 |
26 | true
27 | bin\x86\Debug\
28 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
29 | ;2008
30 | full
31 | x86
32 | false
33 | prompt
34 | true
35 |
36 |
37 | bin\x86\Release\
38 | TRACE;NETFX_CORE;WINDOWS_UWP
39 | true
40 | ;2008
41 | pdbonly
42 | x86
43 | false
44 | prompt
45 | true
46 | true
47 |
48 |
49 | true
50 | bin\ARM\Debug\
51 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
52 | ;2008
53 | full
54 | ARM
55 | false
56 | prompt
57 | true
58 |
59 |
60 | bin\ARM\Release\
61 | TRACE;NETFX_CORE;WINDOWS_UWP
62 | true
63 | ;2008
64 | pdbonly
65 | ARM
66 | false
67 | prompt
68 | true
69 | true
70 |
71 |
72 | true
73 | bin\x64\Debug\
74 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
75 | ;2008
76 | full
77 | x64
78 | false
79 | prompt
80 | true
81 |
82 |
83 | bin\x64\Release\
84 | TRACE;NETFX_CORE;WINDOWS_UWP
85 | true
86 | ;2008
87 | pdbonly
88 | x64
89 | false
90 | prompt
91 | true
92 | true
93 |
94 |
95 | PackageReference
96 |
97 |
98 |
99 | App.xaml
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | MainPage.xaml
144 |
145 |
146 |
147 |
148 |
149 | Designer
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | MSBuild:Compile
169 | Designer
170 |
171 |
172 | MSBuild:Compile
173 | Designer
174 |
175 |
176 |
177 |
178 | 5.3.3
179 |
180 |
181 | 10.0.2
182 |
183 |
184 |
185 |
186 | {77b6e3d3-17e6-46cb-b699-c118776f54de}
187 | RenderAPI
188 |
189 |
190 |
191 |
192 | 14.0
193 |
194 |
195 |
202 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptBackgroundWorkItemCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A background work item callback.
7 | ///
8 | ///
9 | /// This is passed to the host's thread service (if provided) to allow the host to
10 | /// invoke the work item callback on the background thread of its choice.
11 | ///
12 | /// Data argument passed to the thread service.
13 | public delegate void JavaScriptBackgroundWorkItemCallback(IntPtr callbackData);
14 | }
15 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptBeforeCollectCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A callback called before collection.
7 | ///
8 | /// The state passed to SetBeforeCollectCallback.
9 | public delegate void JavaScriptBeforeCollectCallback(IntPtr callbackState);
10 | }
11 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptEngineException.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 | using System.Runtime.Serialization;
5 |
6 | ///
7 | /// An exception that occurred in the workings of the JavaScript engine itself.
8 | ///
9 | public sealed class JavaScriptEngineException : JavaScriptException
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The error code returned.
15 | public JavaScriptEngineException(JavaScriptErrorCode code) :
16 | this(code, "A fatal exception has occurred in a JavaScript runtime")
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// The error code returned.
24 | /// The error message.
25 | public JavaScriptEngineException(JavaScriptErrorCode code, string message) :
26 | base(code, message)
27 | {
28 | }
29 |
30 | ///
31 | /// Initializes a new instance of the class.
32 | ///
33 | /// The serialization info.
34 | /// The streaming context.
35 | private JavaScriptEngineException(string message, Exception innerException) :
36 | base(message, innerException)
37 | {
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptErrorCode.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | ///
4 | /// An error code returned from a Chakra hosting API.
5 | ///
6 | public enum JavaScriptErrorCode : uint
7 | {
8 | ///
9 | /// Success error code.
10 | ///
11 | NoError = 0,
12 |
13 | ///
14 | /// Category of errors that relates to incorrect usage of the API itself.
15 | ///
16 | CategoryUsage = 0x10000,
17 |
18 | ///
19 | /// An argument to a hosting API was invalid.
20 | ///
21 | InvalidArgument,
22 |
23 | ///
24 | /// An argument to a hosting API was null in a context where null is not allowed.
25 | ///
26 | NullArgument,
27 |
28 | ///
29 | /// The hosting API requires that a context be current, but there is no current context.
30 | ///
31 | NoCurrentContext,
32 |
33 | ///
34 | /// The engine is in an exception state and no APIs can be called until the exception is
35 | /// cleared.
36 | ///
37 | InExceptionState,
38 |
39 | ///
40 | /// A hosting API is not yet implemented.
41 | ///
42 | NotImplemented,
43 |
44 | ///
45 | /// A hosting API was called on the wrong thread.
46 | ///
47 | WrongThread,
48 |
49 | ///
50 | /// A runtime that is still in use cannot be disposed.
51 | ///
52 | RuntimeInUse,
53 |
54 | ///
55 | /// A bad serialized script was used, or the serialized script was serialized by a
56 | /// different version of the Chakra engine.
57 | ///
58 | BadSerializedScript,
59 |
60 | ///
61 | /// The runtime is in a disabled state.
62 | ///
63 | InDisabledState,
64 |
65 | ///
66 | /// Runtime does not support reliable script interruption.
67 | ///
68 | CannotDisableExecution,
69 |
70 | ///
71 | /// A heap enumeration is currently underway in the script context.
72 | ///
73 | HeapEnumInProgress,
74 |
75 | ///
76 | /// A hosting API that operates on object values was called with a non-object value.
77 | ///
78 | ArgumentNotObject,
79 |
80 | ///
81 | /// A script context is in the middle of a profile callback.
82 | ///
83 | InProfileCallback,
84 |
85 | ///
86 | /// A thread service callback is currently underway.
87 | ///
88 | InThreadServiceCallback,
89 |
90 | ///
91 | /// Scripts cannot be serialized in debug contexts.
92 | ///
93 | CannotSerializeDebugScript,
94 |
95 | ///
96 | /// The context cannot be put into a debug state because it is already in a debug state.
97 | ///
98 | AlreadyDebuggingContext,
99 |
100 | ///
101 | /// The context cannot start profiling because it is already profiling.
102 | ///
103 | AlreadyProfilingContext,
104 |
105 | ///
106 | /// Idle notification given when the host did not enable idle processing.
107 | ///
108 | IdleNotEnabled,
109 |
110 | ///
111 | /// The context did not accept the enqueue callback.
112 | ///
113 | CannotSetProjectionEnqueueCallback,
114 |
115 | ///
116 | /// Failed to start projection.
117 | ///
118 | CannotStartProjection,
119 |
120 | ///
121 | /// The operation is not supported in an object before collect callback.
122 | ///
123 | InObjectBeforeCollectCallback,
124 |
125 | ///
126 | /// Object cannot be unwrapped to IInspectable pointer.
127 | ///
128 | ObjectNotInspectable,
129 |
130 | ///
131 | /// A hosting API that operates on symbol property ids but was called with a non-symbol property id.
132 | /// The error code is returned by JsGetSymbolFromPropertyId if the function is called with non-symbol property id.
133 | ///
134 | PropertyNotSymbol,
135 |
136 | ///
137 | /// A hosting API that operates on string property ids but was called with a non-string property id.
138 | /// The error code is returned by existing JsGetPropertyNamefromId if the function is called with non-string property id.
139 | ///
140 | PropertyNotString,
141 |
142 | ///
143 | /// Category of errors that relates to errors occurring within the engine itself.
144 | ///
145 | CategoryEngine = 0x20000,
146 |
147 | ///
148 | /// The Chakra engine has run out of memory.
149 | ///
150 | OutOfMemory,
151 |
152 | ///
153 | /// Category of errors that relates to errors in a script.
154 | ///
155 | CategoryScript = 0x30000,
156 |
157 | ///
158 | /// A JavaScript exception occurred while running a script.
159 | ///
160 | ScriptException,
161 |
162 | ///
163 | /// JavaScript failed to compile.
164 | ///
165 | ScriptCompile,
166 |
167 | ///
168 | /// A script was terminated due to a request to suspend a runtime.
169 | ///
170 | ScriptTerminated,
171 |
172 | ///
173 | /// A script was terminated because it tried to use eval or function and eval
174 | /// was disabled.
175 | ///
176 | ScriptEvalDisabled,
177 |
178 | ///
179 | /// Category of errors that are fatal and signify failure of the engine.
180 | ///
181 | CategoryFatal = 0x40000,
182 |
183 | ///
184 | /// A fatal error in the engine has occurred.
185 | ///
186 | Fatal,
187 |
188 | ///
189 | /// A hosting API was called with object created on different javascript runtime.
190 | ///
191 | WrongRuntime,
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptException.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 | using System.Runtime.Serialization;
5 |
6 | ///
7 | /// An exception returned from the Chakra engine.
8 | ///
9 | public class JavaScriptException : Exception
10 | {
11 | ///
12 | /// The error code.
13 | ///
14 | private readonly JavaScriptErrorCode code;
15 |
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// The error code returned.
20 | public JavaScriptException(JavaScriptErrorCode code) :
21 | this(code, "A fatal exception has occurred in a JavaScript runtime")
22 | {
23 | }
24 |
25 | ///
26 | /// Initializes a new instance of the class.
27 | ///
28 | /// The error code returned.
29 | /// The error message.
30 | public JavaScriptException(JavaScriptErrorCode code, string message) :
31 | base(message)
32 | {
33 | this.code = code;
34 | }
35 |
36 | ///
37 | /// Initializes a new instance of the class.
38 | ///
39 | /// The serialization info.
40 | /// The streaming context.
41 | protected JavaScriptException(string message, Exception innerException) :
42 | base(message, innerException)
43 | {
44 | if (message != null)
45 | {
46 | code = (JavaScriptErrorCode) base.HResult;
47 | }
48 | }
49 |
50 | /*
51 | ///
52 | /// Serializes the exception information.
53 | ///
54 | /// The serialization information.
55 | /// The streaming context.
56 | public override void GetObjectData(SerializationInfo info, StreamingContext context)
57 | {
58 | base.GetObjectData(info, context);
59 | info.AddValue("code", (uint)code);
60 | }
61 | */
62 | ///
63 | /// Gets the error code.
64 | ///
65 | public JavaScriptErrorCode ErrorCode
66 | {
67 | get { return code; }
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptFatalException.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 | using System.Runtime.Serialization;
5 |
6 | ///
7 | /// A fatal exception occurred.
8 | ///
9 | public sealed class JavaScriptFatalException : JavaScriptException
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The error code returned.
15 | public JavaScriptFatalException(JavaScriptErrorCode code) :
16 | this(code, "A fatal exception has occurred in a JavaScript runtime")
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// The error code returned.
24 | /// The error message.
25 | public JavaScriptFatalException(JavaScriptErrorCode code, string message) :
26 | base(code, message)
27 | {
28 | }
29 |
30 | ///
31 | /// Initializes a new instance of the class.
32 | ///
33 | /// The serialization info.
34 | /// The streaming context.
35 | private JavaScriptFatalException(string message, Exception innerException) :
36 | base(message, innerException)
37 | {
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptMemoryAllocationCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// User implemented callback routine for memory allocation events
7 | ///
8 | /// The state passed to SetRuntimeMemoryAllocationCallback.
9 | /// The type of type allocation event.
10 | /// The size of the allocation.
11 | ///
12 | /// For the Allocate event, returning true allows the runtime to continue with
13 | /// allocation. Returning false indicates the allocation request is rejected. The return value
14 | /// is ignored for other allocation events.
15 | ///
16 | public delegate bool JavaScriptMemoryAllocationCallback(IntPtr callbackState, JavaScriptMemoryEventType allocationEvent, UIntPtr allocationSize);
17 | }
18 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptMemoryEventType.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | ///
4 | /// Allocation callback event type.
5 | ///
6 | public enum JavaScriptMemoryEventType
7 | {
8 | ///
9 | /// Indicates a request for memory allocation.
10 | ///
11 | Allocate = 0,
12 |
13 | ///
14 | /// Indicates a memory freeing event.
15 | ///
16 | Free = 1,
17 |
18 | ///
19 | /// Indicates a failed allocation event.
20 | ///
21 | Failure = 2
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptNativeFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ChakraHost.Hosting
4 | {
5 | using System.Runtime.InteropServices;
6 |
7 | ///
8 | /// A function callback.
9 | ///
10 | ///
11 | /// A Function object that represents the function being invoked.
12 | ///
13 | /// Indicates whether this is a regular call or a 'new' call.
14 | /// The arguments to the call.
15 | /// The number of arguments.
16 | /// Callback data, if any.
17 | /// The result of the call, if any.
18 | public delegate JavaScriptValue JavaScriptNativeFunction(JavaScriptValue callee, [MarshalAs(UnmanagedType.U1)] bool isConstructCall, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData);
19 | }
20 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptObjectBeforeCollectCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A callback called before collecting an object.
7 | ///
8 | ///
9 | /// Use JsSetObjectBeforeCollectCallback to register this callback.
10 | ///
11 | /// The object to be collected.
12 | /// The state passed to JsSetObjectBeforeCollectCallback.
13 | public delegate void JavaScriptObjectBeforeCollectCallback(JavaScriptValue reference, IntPtr callbackState);
14 | }
15 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptObjectFinalizeCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A finalization callback.
7 | ///
8 | ///
9 | /// The external data that was passed in when creating the object being finalized.
10 | ///
11 | public delegate void JavaScriptObjectFinalizeCallback(IntPtr data);
12 | }
13 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptProjectionEnqueueCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// The context passed into application callback, JsProjectionEnqueueCallback, from Jsrt and
7 | /// then passed back to Jsrt in the provided callback, JsProjectionCallback, by the application
8 | /// on the correct thread.
9 | ///
10 | ///
11 | /// Requires calling JsSetProjectionEnqueueCallback to receive callbacks.
12 | ///
13 | public struct JavaScriptProjectionCallbackContext
14 | {
15 | ///
16 | /// The reference.
17 | ///
18 | private readonly IntPtr reference;
19 | }
20 |
21 | ///
22 | /// The Jsrt callback which should be called with the context passed to JsProjectionEnqueueCallback on
23 | /// the correct thread.
24 | ///
25 | ///
26 | /// Requires calling JsSetProjectionEnqueueCallback to receive callbacks.
27 | ///
28 | /// The context originally received by a call to JsProjectionEnqueueCallback.
29 | public delegate void JavaScriptProjectionCallback(JavaScriptProjectionCallbackContext jsContext);
30 |
31 | ///
32 | /// The application callback which is called by Jsrt when a projection API is completed on
33 | /// a different thread than the original.
34 | ///
35 | ///
36 | /// Requires calling JsSetProjectionEnqueueCallback to receive callbacks.
37 | ///
38 | /// The callback to be invoked on the original thread.
39 | /// The applications context.
40 | /// The Jsrt context that must be passed into jsCallback.
41 | public delegate void JavaScriptProjectionEnqueueCallback(JavaScriptProjectionCallback jsCallback, JavaScriptProjectionCallbackContext jsContext, IntPtr callbackState);
42 | }
43 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptPromiseContinuationCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A promise continuation callback.
7 | ///
8 | ///
9 | /// The host can specify a promise continuation callback in JsSetPromiseContinuationCallback. If
10 | /// a script creates a task to be run later, then the promise continuation callback will be called with
11 | /// the task and the task should be put in a FIFO queue, to be run when the current script is
12 | /// done executing.
13 | ///
14 | /// The task, represented as a JavaScript function.
15 | /// The data argument to be passed to the callback.
16 | public delegate void JavaScriptPromiseContinuationCallback(JavaScriptValue task, IntPtr callbackState);
17 | }
18 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptPropertyId.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A property identifier.
7 | ///
8 | ///
9 | /// Property identifiers are used to refer to properties of JavaScript objects instead of using
10 | /// strings.
11 | ///
12 | public struct JavaScriptPropertyId : IEquatable
13 | {
14 | ///
15 | /// The id.
16 | ///
17 | private readonly IntPtr id;
18 |
19 | ///
20 | /// Initializes a new instance of the struct.
21 | ///
22 | /// The ID.
23 | internal JavaScriptPropertyId(IntPtr id)
24 | {
25 | this.id = id;
26 | }
27 |
28 | ///
29 | /// Gets an invalid ID.
30 | ///
31 | public static JavaScriptPropertyId Invalid
32 | {
33 | get { return new JavaScriptPropertyId(IntPtr.Zero); }
34 | }
35 |
36 | ///
37 | /// Gets the name associated with the property ID.
38 | ///
39 | ///
40 | ///
41 | /// Requires an active script context.
42 | ///
43 | ///
44 | public string Name
45 | {
46 | get
47 | {
48 | string name;
49 | Native.ThrowIfError(Native.JsGetPropertyNameFromId(this, out name));
50 | return name;
51 | }
52 | }
53 |
54 | ///
55 | /// Gets the property ID associated with the name.
56 | ///
57 | ///
58 | ///
59 | /// Property IDs are specific to a context and cannot be used across contexts.
60 | ///
61 | ///
62 | /// Requires an active script context.
63 | ///
64 | ///
65 | ///
66 | /// The name of the property ID to get or create. The name may consist of only digits.
67 | ///
68 | /// The property ID in this runtime for the given name.
69 | public static JavaScriptPropertyId FromString(string name)
70 | {
71 | JavaScriptPropertyId id;
72 | Native.ThrowIfError(Native.JsGetPropertyIdFromName(name, out id));
73 | return id;
74 | }
75 |
76 | ///
77 | /// The equality operator for property IDs.
78 | ///
79 | /// The first property ID to compare.
80 | /// The second property ID to compare.
81 | /// Whether the two property IDs are the same.
82 | public static bool operator ==(JavaScriptPropertyId left, JavaScriptPropertyId right)
83 | {
84 | return left.Equals(right);
85 | }
86 |
87 | ///
88 | /// The inequality operator for property IDs.
89 | ///
90 | /// The first property ID to compare.
91 | /// The second property ID to compare.
92 | /// Whether the two property IDs are not the same.
93 | public static bool operator !=(JavaScriptPropertyId left, JavaScriptPropertyId right)
94 | {
95 | return !left.Equals(right);
96 | }
97 |
98 | ///
99 | /// Checks for equality between property IDs.
100 | ///
101 | /// The other property ID to compare.
102 | /// Whether the two property IDs are the same.
103 | public bool Equals(JavaScriptPropertyId other)
104 | {
105 | return id == other.id;
106 | }
107 |
108 | ///
109 | /// Checks for equality between property IDs.
110 | ///
111 | /// The other property ID to compare.
112 | /// Whether the two property IDs are the same.
113 | public override bool Equals(object obj)
114 | {
115 | if (ReferenceEquals(null, obj))
116 | {
117 | return false;
118 | }
119 |
120 | return obj is JavaScriptPropertyId && Equals((JavaScriptPropertyId)obj);
121 | }
122 |
123 | ///
124 | /// The hash code.
125 | ///
126 | /// The hash code of the property ID.
127 | public override int GetHashCode()
128 | {
129 | return id.ToInt32();
130 | }
131 |
132 | ///
133 | /// Converts the property ID to a string.
134 | ///
135 | /// The name of the property ID.
136 | public override string ToString()
137 | {
138 | return Name;
139 | }
140 | }
141 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptPropertyIdType.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | ///
4 | /// Type enumeration of a JavaScript property
5 | ///
6 | public enum JavaScriptPropertyIdType
7 | {
8 | ///
9 | /// Type enumeration of a JavaScript string property
10 | ///
11 | String,
12 | ///
13 | /// Type enumeration of a JavaScript symbol property
14 | ///
15 | Symbol
16 | };
17 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptRuntime.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A Chakra runtime.
7 | ///
8 | ///
9 | ///
10 | /// Each Chakra runtime has its own independent execution engine, JIT compiler, and garbage
11 | /// collected heap. As such, each runtime is completely isolated from other runtimes.
12 | ///
13 | ///
14 | /// Runtimes can be used on any thread, but only one thread can call into a runtime at any
15 | /// time.
16 | ///
17 | ///
18 | /// NOTE: A JavaScriptRuntime, unlike other objects in the Chakra hosting API, is not
19 | /// garbage collected since it contains the garbage collected heap itself. A runtime will
20 | /// continue to exist until Dispose is called.
21 | ///
22 | ///
23 | public struct JavaScriptRuntime : IDisposable
24 | {
25 | ///
26 | /// The handle.
27 | ///
28 | private IntPtr handle;
29 |
30 | ///
31 | /// Gets a value indicating whether the runtime is valid.
32 | ///
33 | public bool IsValid
34 | {
35 | get { return handle != IntPtr.Zero; }
36 | }
37 |
38 | ///
39 | /// Gets the current memory usage for a runtime.
40 | ///
41 | ///
42 | /// Memory usage can be always be retrieved, regardless of whether or not the runtime is active
43 | /// on another thread.
44 | ///
45 | public UIntPtr MemoryUsage
46 | {
47 | get
48 | {
49 | UIntPtr memoryUsage;
50 | Native.ThrowIfError(Native.JsGetRuntimeMemoryUsage(this, out memoryUsage));
51 | return memoryUsage;
52 | }
53 | }
54 |
55 | ///
56 | /// Gets or sets the current memory limit for a runtime.
57 | ///
58 | ///
59 | /// The memory limit of a runtime can be always be retrieved, regardless of whether or not the
60 | /// runtime is active on another thread.
61 | ///
62 | public UIntPtr MemoryLimit
63 | {
64 | get
65 | {
66 | UIntPtr memoryLimit;
67 | Native.ThrowIfError(Native.JsGetRuntimeMemoryLimit(this, out memoryLimit));
68 | return memoryLimit;
69 | }
70 |
71 | set
72 | {
73 | Native.ThrowIfError(Native.JsSetRuntimeMemoryLimit(this, value));
74 | }
75 | }
76 |
77 | ///
78 | /// Gets or sets a value indicating whether script execution is disabled in the runtime.
79 | ///
80 | public bool Disabled
81 | {
82 | get
83 | {
84 | bool isDisabled;
85 | Native.ThrowIfError(Native.JsIsRuntimeExecutionDisabled(this, out isDisabled));
86 | return isDisabled;
87 | }
88 |
89 | set
90 | {
91 | Native.ThrowIfError(value
92 | ? Native.JsDisableRuntimeExecution(this)
93 | : Native.JsEnableRuntimeExecution(this));
94 | }
95 | }
96 |
97 | ///
98 | /// Creates a new runtime.
99 | ///
100 | /// The attributes of the runtime to be created.
101 | /// The version of the runtime to be created.
102 | /// The thread service for the runtime. Can be null.
103 | /// The runtime created.
104 | public static JavaScriptRuntime Create(JavaScriptRuntimeAttributes attributes, JavaScriptRuntimeVersion version, JavaScriptThreadServiceCallback threadServiceCallback)
105 | {
106 | JavaScriptRuntime handle;
107 | Native.ThrowIfError(Native.JsCreateRuntime(attributes, threadServiceCallback, out handle));
108 | return handle;
109 | }
110 |
111 | ///
112 | /// Creates a new runtime.
113 | ///
114 | /// The attributes of the runtime to be created.
115 | /// The version of the runtime to be created.
116 | /// The runtime created.
117 | public static JavaScriptRuntime Create(JavaScriptRuntimeAttributes attributes, JavaScriptRuntimeVersion version)
118 | {
119 | return Create(attributes, version, null);
120 | }
121 |
122 | ///
123 | /// Creates a new runtime.
124 | ///
125 | /// The runtime created.
126 | public static JavaScriptRuntime Create()
127 | {
128 | return Create(JavaScriptRuntimeAttributes.None, JavaScriptRuntimeVersion.Version11, null);
129 | }
130 |
131 | ///
132 | /// Disposes a runtime.
133 | ///
134 | ///
135 | /// Once a runtime has been disposed, all resources owned by it are invalid and cannot be used.
136 | /// If the runtime is active (i.e. it is set to be current on a particular thread), it cannot
137 | /// be disposed.
138 | ///
139 | public void Dispose()
140 | {
141 | if (IsValid)
142 | {
143 | Native.ThrowIfError(Native.JsDisposeRuntime(this));
144 | }
145 |
146 | handle = IntPtr.Zero;
147 | }
148 |
149 | ///
150 | /// Performs a full garbage collection.
151 | ///
152 | public void CollectGarbage()
153 | {
154 | Native.ThrowIfError(Native.JsCollectGarbage(this));
155 | }
156 |
157 | ///
158 | /// Sets a memory allocation callback for specified runtime
159 | ///
160 | ///
161 | ///
162 | /// Registering a memory allocation callback will cause the runtime to call back to the host
163 | /// whenever it acquires memory from, or releases memory to, the OS. The callback routine is
164 | /// called before the runtime memory manager allocates a block of memory. The allocation will
165 | /// be rejected if the callback returns false. The runtime memory manager will also invoke the
166 | /// callback routine after freeing a block of memory, as well as after allocation failures.
167 | ///
168 | ///
169 | /// The callback is invoked on the current runtime execution thread, therefore execution is
170 | /// blocked until the callback completes.
171 | ///
172 | ///
173 | /// The return value of the callback is not stored; previously rejected allocations will not
174 | /// prevent the runtime from invoking the callback again later for new memory allocations.
175 | ///
176 | ///
177 | ///
178 | /// User provided state that will be passed back to the callback.
179 | ///
180 | ///
181 | /// Memory allocation callback to be called for memory allocation events.
182 | ///
183 | public void SetMemoryAllocationCallback(IntPtr callbackState, JavaScriptMemoryAllocationCallback allocationCallback)
184 | {
185 | Native.ThrowIfError(Native.JsSetRuntimeMemoryAllocationCallback(this, callbackState, allocationCallback));
186 | }
187 |
188 | ///
189 | /// Sets a callback function that is called by the runtime before garbage collection.
190 | ///
191 | ///
192 | ///
193 | /// The callback is invoked on the current runtime execution thread, therefore execution is
194 | /// blocked until the callback completes.
195 | ///
196 | ///
197 | /// The callback can be used by hosts to prepare for garbage collection. For example, by
198 | /// releasing unnecessary references on Chakra objects.
199 | ///
200 | ///
201 | ///
202 | /// User provided state that will be passed back to the callback.
203 | ///
204 | /// The callback function being set.
205 | public void SetBeforeCollectCallback(IntPtr callbackState, JavaScriptBeforeCollectCallback beforeCollectCallback)
206 | {
207 | Native.ThrowIfError(Native.JsSetRuntimeBeforeCollectCallback(this, callbackState, beforeCollectCallback));
208 | }
209 |
210 | ///
211 | /// Creates a script context for running scripts.
212 | ///
213 | ///
214 | /// Each script context has its own global object that is isolated from all other script
215 | /// contexts.
216 | ///
217 | /// The created script context.
218 | public JavaScriptContext CreateContext()
219 | {
220 | JavaScriptContext reference;
221 | Native.ThrowIfError(Native.JsCreateContext(this, out reference));
222 | return reference;
223 | }
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptRuntimeAttributes.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 | using System.Diagnostics.CodeAnalysis;
5 |
6 | ///
7 | /// Attributes of a runtime.
8 | ///
9 | [Flags]
10 | public enum JavaScriptRuntimeAttributes
11 | {
12 | ///
13 | /// No special attributes.
14 | ///
15 | None = 0x00000000,
16 |
17 | ///
18 | /// The runtime will not do any work (such as garbage collection) on background threads.
19 | ///
20 | DisableBackgroundWork = 0x00000001,
21 |
22 | ///
23 | /// The runtime should support reliable script interruption. This increases the number of
24 | /// places where the runtime will check for a script interrupt request at the cost of a
25 | /// small amount of runtime performance.
26 | ///
27 | AllowScriptInterrupt = 0x00000002,
28 |
29 | ///
30 | /// Host will call Idle, so enable idle processing. Otherwise, the runtime will manage
31 | /// memory slightly more aggressively.
32 | ///
33 | EnableIdleProcessing = 0x00000004,
34 |
35 | ///
36 | /// Runtime will not generate native code.
37 | ///
38 | DisableNativeCodeGeneration = 0x00000008,
39 |
40 | ///
41 | /// Using Eval or Function constructor will throw an exception.
42 | ///
43 | [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Eval is a valid function name.")]
44 | DisableEval = 0x00000010,
45 |
46 | ///
47 | /// Runtime will enable all experimental features.
48 | ///
49 | ///
50 | EnableExperimentalFeatures = 0x00000020,
51 |
52 | ///
53 | /// Calling JsSetException will also dispatch the exception to the script debugger
54 | /// (if any) giving the debugger a chance to break on the exception.
55 | ///
56 | DispatchSetExceptionsToDebugger = 0x00000040
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptRuntimeVersion.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | ///
4 | /// Version of the runtime.
5 | ///
6 | public enum JavaScriptRuntimeVersion
7 | {
8 | ///
9 | /// Create runtime with IE10 version.
10 | ///
11 | Version10 = 0,
12 |
13 | ///
14 | /// Create runtime with IE11 version.
15 | ///
16 | Version11 = 1,
17 |
18 | ///
19 | /// Create runtime with highest version present on the machine at runtime.
20 | ///
21 | VersionEdge = -1,
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptScriptException.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 | using System.Runtime.Serialization;
5 |
6 | ///
7 | /// A script exception.
8 | ///
9 | public sealed class JavaScriptScriptException : JavaScriptException
10 | {
11 | ///
12 | /// The error.
13 | ///
14 | private readonly JavaScriptValue error;
15 |
16 | ///
17 | /// Initializes a new instance of the class.
18 | ///
19 | /// The error code returned.
20 | /// The JavaScript error object.
21 | public JavaScriptScriptException(JavaScriptErrorCode code, JavaScriptValue error) :
22 | this(code, error, "JavaScript Exception")
23 | {
24 | }
25 |
26 | ///
27 | /// Initializes a new instance of the class.
28 | ///
29 | /// The error code returned.
30 | /// The JavaScript error object.
31 | /// The error message.
32 | public JavaScriptScriptException(JavaScriptErrorCode code, JavaScriptValue error, string message) :
33 | base(code, message)
34 | {
35 | this.error = error;
36 | }
37 |
38 | ///
39 | /// Initializes a new instance of the class.
40 | ///
41 | /// The serialization info.
42 | /// The streaming context.
43 | private JavaScriptScriptException(string message, Exception innerException) :
44 | base(message, innerException)
45 | {
46 | }
47 |
48 | ///
49 | /// Gets a JavaScript object representing the script error.
50 | ///
51 | public JavaScriptValue Error
52 | {
53 | get
54 | {
55 | return error;
56 | }
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptSerializedScriptLoadSourceCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// Called by the runtime to load the source code of the serialized script.
7 | /// The caller must keep the script buffer valid until the JsSerializedScriptUnloadCallback.
8 | ///
9 | /// The context passed to Js[Parse|Run]SerializedScriptWithCallback
10 | /// The script returned.
11 | ///
12 | /// true if the operation succeeded, false otherwise.
13 | ///
14 | public delegate bool JavaScriptSerializedScriptLoadSourceCallback(JavaScriptSourceContext sourceContext, out string scriptBuffer);
15 | }
16 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptSerializedScriptUnloadCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// Called by the runtime when it is finished with all resources related to the script execution.
7 | /// The caller should free the source if loaded, the byte code, and the context at this time.
8 | ///
9 | /// The context passed to Js[Parse|Run]SerializedScriptWithCallback
10 | public delegate void JavaScriptSerializedScriptUnloadCallback(JavaScriptSourceContext sourceContext);
11 | }
12 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptSourceContext.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A cookie that identifies a script for debugging purposes.
7 | ///
8 | public struct JavaScriptSourceContext : IEquatable
9 | {
10 | ///
11 | /// The context.
12 | ///
13 | private readonly IntPtr context;
14 |
15 | ///
16 | /// Initializes a new instance of the struct.
17 | ///
18 | /// The context.
19 | private JavaScriptSourceContext(IntPtr context)
20 | {
21 | this.context = context;
22 | }
23 |
24 | ///
25 | /// Gets an empty source context.
26 | ///
27 | public static JavaScriptSourceContext None
28 | {
29 | get { return new JavaScriptSourceContext(new IntPtr(-1)); }
30 | }
31 |
32 | ///
33 | /// The equality operator for source contexts.
34 | ///
35 | /// The first source context to compare.
36 | /// The second source context to compare.
37 | /// Whether the two source contexts are the same.
38 | public static bool operator ==(JavaScriptSourceContext left, JavaScriptSourceContext right)
39 | {
40 | return left.Equals(right);
41 | }
42 |
43 | ///
44 | /// The inequality operator for source contexts.
45 | ///
46 | /// The first source context to compare.
47 | /// The second source context to compare.
48 | /// Whether the two source contexts are not the same.
49 | public static bool operator !=(JavaScriptSourceContext left, JavaScriptSourceContext right)
50 | {
51 | return !left.Equals(right);
52 | }
53 |
54 | ///
55 | /// Subtracts an offset from the value of the source context.
56 | ///
57 | /// The source context to subtract the offset from.
58 | /// The offset to subtract.
59 | /// A new source context that reflects the subtraction of the offset from the context.
60 | public static JavaScriptSourceContext operator -(JavaScriptSourceContext context, int offset)
61 | {
62 | return FromIntPtr(context.context - offset);
63 | }
64 |
65 | ///
66 | /// Subtracts an offset from the value of the source context.
67 | ///
68 | /// The source context to subtract the offset from.
69 | /// The offset to subtract.
70 | /// A new source context that reflects the subtraction of the offset from the context.
71 | public static JavaScriptSourceContext Subtract(JavaScriptSourceContext left, int right)
72 | {
73 | return left - right;
74 | }
75 |
76 | ///
77 | /// Decrements the value of the source context.
78 | ///
79 | /// The source context to decrement.
80 | /// A new source context that reflects the decrementing of the context.
81 | public static JavaScriptSourceContext operator --(JavaScriptSourceContext context)
82 | {
83 | return FromIntPtr(context.context - 1);
84 | }
85 |
86 | ///
87 | /// Decrements the value of the source context.
88 | ///
89 | /// The source context to decrement.
90 | /// A new source context that reflects the decrementing of the context.
91 | public static JavaScriptSourceContext Decrement(JavaScriptSourceContext left)
92 | {
93 | return --left;
94 | }
95 |
96 | ///
97 | /// Adds an offset from the value of the source context.
98 | ///
99 | /// The source context to add the offset to.
100 | /// The offset to add.
101 | /// A new source context that reflects the addition of the offset to the context.
102 | public static JavaScriptSourceContext operator +(JavaScriptSourceContext context, int offset)
103 | {
104 | return FromIntPtr(context.context + offset);
105 | }
106 |
107 | ///
108 | /// Adds an offset from the value of the source context.
109 | ///
110 | /// The source context to add the offset to.
111 | /// The offset to add.
112 | /// A new source context that reflects the addition of the offset to the context.
113 | public static JavaScriptSourceContext Add(JavaScriptSourceContext left, int right)
114 | {
115 | return left + right;
116 | }
117 |
118 | ///
119 | /// Increments the value of the source context.
120 | ///
121 | /// The source context to increment.
122 | /// A new source context that reflects the incrementing of the context.
123 | public static JavaScriptSourceContext operator ++(JavaScriptSourceContext context)
124 | {
125 | return FromIntPtr(context.context + 1);
126 | }
127 |
128 | ///
129 | /// Increments the value of the source context.
130 | ///
131 | /// The source context to increment.
132 | /// A new source context that reflects the incrementing of the context.
133 | public static JavaScriptSourceContext Increment(JavaScriptSourceContext left)
134 | {
135 | return ++left;
136 | }
137 |
138 | ///
139 | /// Creates a new source context.
140 | ///
141 | ///
142 | /// The cookie for the source context.
143 | ///
144 | /// The new source context.
145 | public static JavaScriptSourceContext FromIntPtr(IntPtr cookie)
146 | {
147 | return new JavaScriptSourceContext(cookie);
148 | }
149 |
150 | ///
151 | /// Checks for equality between source contexts.
152 | ///
153 | /// The other source context to compare.
154 | /// Whether the two source contexts are the same.
155 | public bool Equals(JavaScriptSourceContext other)
156 | {
157 | return context == other.context;
158 | }
159 |
160 | ///
161 | /// Checks for equality between source contexts.
162 | ///
163 | /// The other source context to compare.
164 | /// Whether the two source contexts are the same.
165 | public override bool Equals(object obj)
166 | {
167 | if (ReferenceEquals(null, obj))
168 | {
169 | return false;
170 | }
171 |
172 | return obj is JavaScriptSourceContext && Equals((JavaScriptSourceContext)obj);
173 | }
174 |
175 | ///
176 | /// The hash code.
177 | ///
178 | /// The hash code of the source context.
179 | public override int GetHashCode()
180 | {
181 | return context.ToInt32();
182 | }
183 | }
184 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptThreadServiceCallback.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 |
5 | ///
6 | /// A thread service callback.
7 | ///
8 | ///
9 | /// The host can specify a background thread service when creating a runtime. If
10 | /// specified, then background work items will be passed to the host using this callback. The
11 | /// host is expected to either begin executing the background work item immediately and return
12 | /// true or return false and the runtime will handle the work item in-thread.
13 | ///
14 | /// The callback for the background work item.
15 | /// The data argument to be passed to the callback.
16 | /// Whether the thread service will execute the callback.
17 | public delegate bool JavaScriptThreadServiceCallback(JavaScriptBackgroundWorkItemCallback callbackFunction, IntPtr callbackData);
18 | }
19 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptTypedArrayType.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | ///
4 | /// The type of a typed JavaScript array.
5 | ///
6 | public enum JavaScriptTypedArrayType
7 | {
8 | ///
9 | /// An int8 array.
10 | ///
11 | Int8,
12 | ///
13 | /// An uint8 array.
14 | ///
15 | Uint8,
16 | ///
17 | /// An uint8 clamped array.
18 | ///
19 | Uint8Clamped,
20 | ///
21 | /// An int16 array.
22 | ///
23 | Int16,
24 | ///
25 | /// An uint16 array.
26 | ///
27 | Uint16,
28 | ///
29 | /// An int32 array.
30 | ///
31 | Int32,
32 | ///
33 | /// An uint32 array.
34 | ///
35 | Uint32,
36 | ///
37 | /// A float32 array.
38 | ///
39 | Float32,
40 | ///
41 | /// A float64 array.
42 | ///
43 | Float64
44 | };
45 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptUsageException.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | using System;
4 | using System.Runtime.Serialization;
5 |
6 | ///
7 | /// An API usage exception occurred.
8 | ///
9 | public sealed class JavaScriptUsageException : JavaScriptException
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | /// The error code returned.
15 | public JavaScriptUsageException(JavaScriptErrorCode code) :
16 | this(code, "A fatal exception has occurred in a JavaScript runtime")
17 | {
18 | }
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// The error code returned.
24 | /// The error message.
25 | public JavaScriptUsageException(JavaScriptErrorCode code, string message) :
26 | base(code, message)
27 | {
28 | }
29 |
30 | ///
31 | /// Initializes a new instance of the class.
32 | ///
33 | /// The serialization info.
34 | /// The streaming context.
35 | private JavaScriptUsageException(string message, Exception innerException) :
36 | base(message, innerException)
37 | {
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Hosting/JavaScriptValueType.cs:
--------------------------------------------------------------------------------
1 | namespace ChakraHost.Hosting
2 | {
3 | ///
4 | /// The JavaScript type of a JavaScriptValue.
5 | ///
6 | public enum JavaScriptValueType
7 | {
8 | ///
9 | /// The value is the undefined value.
10 | ///
11 | Undefined = 0,
12 |
13 | ///
14 | /// The value is the null value.
15 | ///
16 | Null = 1,
17 |
18 | ///
19 | /// The value is a JavaScript number value.
20 | ///
21 | Number = 2,
22 |
23 | ///
24 | /// The value is a JavaScript string value.
25 | ///
26 | String = 3,
27 |
28 | ///
29 | /// The value is a JavaScript Boolean value.
30 | ///
31 | Boolean = 4,
32 |
33 | ///
34 | /// The value is a JavaScript object value.
35 | ///
36 | Object = 5,
37 |
38 | ///
39 | /// The value is a JavaScript function object value.
40 | ///
41 | Function = 6,
42 |
43 | ///
44 | /// The value is a JavaScript error object value.
45 | ///
46 | Error = 7,
47 |
48 | ///
49 | /// The value is a JavaScript array object value.
50 | ///
51 | Array = 8,
52 |
53 | ///
54 | /// The value is a JavaScript array object value.
55 | ///
56 | Symbol = 9,
57 |
58 | ///
59 | /// The value is a JavaScript ArrayBuffer object value.
60 | ///
61 | ArrayBuffer = 10,
62 |
63 | ///
64 | /// The value is a JavaScript typed array object value.
65 | ///
66 | TypedArray = 11,
67 |
68 | ///
69 | /// The value is a JavaScript DataView object value.
70 | ///
71 | DataView = 12,
72 | }
73 | }
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSApp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | 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;
8 |
9 | namespace Electrino.JS
10 | {
11 | class JSApp : AbstractJSModule
12 | {
13 | private Dictionary>> listeners = new Dictionary>>();
14 | private static JSApp instance;
15 | public JSApp() : base("app")
16 | {
17 | instance = this;
18 | AttachMethod(On, "on");
19 | AttachMethod(Quit, "quit");
20 | }
21 |
22 | public static JSApp GetInstance()
23 | {
24 | return instance;
25 | }
26 |
27 | private JavaScriptValue On(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
28 | {
29 | string key = JSValToString(arguments[1]);
30 | List> eventListeners;
31 | if (listeners.ContainsKey(key))
32 | {
33 | listeners.TryGetValue(key, out eventListeners);
34 | }
35 | else
36 | {
37 | eventListeners = new List>();
38 | listeners.Add(key, eventListeners);
39 | }
40 | eventListeners.Add(Tuple.Create(arguments[2], arguments[0]));
41 | arguments[2].AddRef();
42 | return JavaScriptValue.Undefined;
43 | }
44 |
45 | public void Call(string key)
46 | {
47 | List> eventListeners;
48 | listeners.TryGetValue(key, out eventListeners);
49 | if (eventListeners != null)
50 | {
51 | foreach (Tuple listener in eventListeners)
52 | {
53 | listener.Item1.CallFunction(new JavaScriptValue[] { listener.Item2 });
54 | }
55 | }
56 | }
57 |
58 | private JavaScriptValue Quit(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
59 | {
60 | Windows.UI.Xaml.Application.Current.Exit();
61 | return JavaScriptValue.Undefined;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSBrowserWindow.cs:
--------------------------------------------------------------------------------
1 | using ChakraHost.Hosting;
2 | using Newtonsoft.Json.Linq;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | namespace Electrino.JS
7 | {
8 | class JSBrowserWindow : AbstractJSModule
9 | {
10 | private static JSBrowserWindow instance;
11 | private static List windows;
12 |
13 | public JSBrowserWindow() : base("BrowserWindow", true)
14 | {
15 | instance = this;
16 | windows = new List();
17 | }
18 |
19 | public static JSBrowserWindow GetInstance()
20 | {
21 | return instance;
22 | }
23 |
24 | // TODO support sending event to specific browser window
25 | public void CallAll(string key)
26 | {
27 | foreach (JSBrowserWindowInstance window in windows)
28 | {
29 | window.Call(key);
30 | }
31 | }
32 |
33 | protected override JavaScriptValue Main(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
34 | {
35 | if (!isConstructCall)
36 | {
37 | return JavaScriptValue.CreateTypeError(JavaScriptValue.FromString("BrowserWindow must be constructed"));
38 | }
39 |
40 | JToken options;
41 | try
42 | {
43 | options = JavaScriptValueToJTokenConverter.Convert(arguments[1]);
44 | }
45 | catch (Exception)
46 | {
47 | // If no object is passed to the BrowserWindow constructor we'll provide a default one
48 | options = JObject.Parse("{ width: 800, height: 600 }");
49 | }
50 |
51 | JSBrowserWindowInstance instance = new JSBrowserWindowInstance(options);
52 | windows.Add(instance);
53 | return instance.GetModule();
54 | }
55 | }
56 |
57 | class JSBrowserWindowInstance : AbstractJSModule
58 | {
59 | private JToken options;
60 | private Dictionary>> listeners = new Dictionary>>();
61 |
62 | public JSBrowserWindowInstance(JToken options) : base("BrowserWindowInstance")
63 | {
64 | const int defaultWindowWidth = 800, defaultWindowHeight = 600;
65 | int width = 0, height = 0;
66 | this.options = options;
67 |
68 | AttachMethod(LoadURL, "loadURL");
69 | AttachMethod(On, "on");
70 |
71 | Int32.TryParse(options["width"].ToString(), out width);
72 | Int32.TryParse(options["height"].ToString(), out height);
73 |
74 | if (width <= 0) width = defaultWindowWidth;
75 | if (height <= 0) height = defaultWindowHeight;
76 |
77 | App.NewWindow(width, height);
78 | }
79 | protected JavaScriptValue LoadURL(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
80 | {
81 | string url = JSValToString(arguments[1]);
82 | if (!MainPage.LoadURL(url))
83 | {
84 | App.Log("Failed to load url " + url);
85 | }
86 | return JavaScriptValue.Undefined;
87 | }
88 |
89 | private JavaScriptValue On(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
90 | {
91 | string key = JSValToString(arguments[1]);
92 | List> eventListeners;
93 | if (listeners.ContainsKey(key))
94 | {
95 | listeners.TryGetValue(key, out eventListeners);
96 | }
97 | else
98 | {
99 | eventListeners = new List>();
100 | listeners.Add(key, eventListeners);
101 | }
102 | eventListeners.Add(Tuple.Create(arguments[2], arguments[0]));
103 | arguments[2].AddRef();
104 | return JavaScriptValue.Undefined;
105 | }
106 |
107 | public void Call(string key)
108 | {
109 | List> eventListeners;
110 | listeners.TryGetValue(key, out eventListeners);
111 | if (eventListeners != null)
112 | {
113 | foreach (Tuple listener in eventListeners)
114 | {
115 | listener.Item1.CallFunction(new JavaScriptValue[] { listener.Item2 });
116 | }
117 | }
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSConsole.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Diagnostics;
7 | using ChakraHost.Hosting;
8 |
9 | namespace Electrino.JS
10 | {
11 | class JSConsole : AbstractJSModule
12 | {
13 | public JSConsole() : base("console")
14 | {
15 | AttachMethod(Log, "log");
16 | }
17 |
18 | private static JavaScriptValue Log(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
19 | {
20 | string[] args = new string[arguments.Length - 1];
21 | for (int i = 1; i < arguments.Length; i++)
22 | {
23 | args[i - 1] = JSValToString(arguments[i]);
24 | }
25 | App.Log(String.Join(", ", args));
26 | return JavaScriptValue.Undefined;
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSElectrino.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using ChakraHost.Hosting;
7 |
8 | namespace Electrino.JS
9 | {
10 | class JSElectrino : AbstractJSModule
11 | {
12 | public JSElectrino() : base("electrino")
13 | {
14 | AttachModule(new JSApp());
15 | AttachModule(new JSBrowserWindow());
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSModule.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | 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;
8 | using System.Runtime.InteropServices;
9 |
10 | namespace Electrino.JS
11 | {
12 | abstract class AbstractJSModule
13 | {
14 | private JavaScriptValue module;
15 | private string id;
16 | private bool asFunction;
17 |
18 | public static void AttachModule(JavaScriptValue module, AbstractJSModule subModule)
19 | {
20 | if (Native.JsSetProperty(module, JavaScriptPropertyId.FromString(subModule.GetId()),
21 | subModule.GetModule(), false) != JavaScriptErrorCode.NoError)
22 | {
23 | throw new Exception("Failed to attach module");
24 | }
25 | }
26 |
27 | public static void AttachModule(AbstractJSModule module, AbstractJSModule subModule)
28 | {
29 | AttachModule(module.GetModule(), subModule);
30 | }
31 |
32 |
33 | public static void AttachMethod(JavaScriptValue module, JavaScriptNativeFunction method, string id)
34 | {
35 | JavaScriptValue requireToString;
36 | if (Native.JsCreateFunction(method, IntPtr.Zero, out requireToString) != JavaScriptErrorCode.NoError)
37 | {
38 | throw new Exception("Failed to create method");
39 | }
40 | if (Native.JsSetProperty(module, JavaScriptPropertyId.FromString(id), requireToString, false)
41 | != JavaScriptErrorCode.NoError)
42 | {
43 | throw new Exception("Failed to define tostring on require");
44 | }
45 | }
46 |
47 | public static void AttachMethod(AbstractJSModule module, JavaScriptNativeFunction method, string id)
48 | {
49 | AttachMethod(module.GetModule(), method, id);
50 | }
51 |
52 |
53 | public static void AttachProperty(JavaScriptValue module, JavaScriptValue property, string id)
54 | {
55 | if (Native.JsSetProperty(module, JavaScriptPropertyId.FromString(id),
56 | property, false) != JavaScriptErrorCode.NoError)
57 | {
58 | throw new Exception("Failed to attach property");
59 | }
60 | }
61 |
62 | public static void AttachProperty(AbstractJSModule module, JavaScriptValue method, string id)
63 | {
64 | AttachProperty(module.GetModule(), method, id);
65 | }
66 |
67 | public static string JSValToString(JavaScriptValue val)
68 | {
69 | val = val.ConvertToString();
70 | IntPtr returnValue = IntPtr.Zero;
71 | UIntPtr stringLength;
72 | if (Native.JsStringToPointer(val, out returnValue, out stringLength) != JavaScriptErrorCode.NoError)
73 | {
74 | throw new Exception("Failed to convert return value.");
75 | }
76 | return Marshal.PtrToStringUni(returnValue);
77 | }
78 |
79 | ///
80 | /// Construct a module either as an Object or function
81 | /// If function is used then the class must override the Main method
82 | ///
83 | ///
84 | ///
85 | public AbstractJSModule(string id, bool asFunction = false)
86 | {
87 | this.id = id;
88 | this.asFunction = asFunction;
89 |
90 | if (asFunction)
91 | {
92 | if (Native.JsCreateFunction(Main, IntPtr.Zero, out module) != JavaScriptErrorCode.NoError)
93 | {
94 | throw new Exception("Failed to create function");
95 | }
96 | }
97 | else
98 | {
99 | if (Native.JsCreateObject(out module) != JavaScriptErrorCode.NoError)
100 | {
101 | throw new Exception("Failed to create module");
102 | }
103 | }
104 |
105 | AttachMethod(ToString, "toString");
106 | }
107 |
108 | public void AttachModule(AbstractJSModule subModule)
109 | {
110 | AttachModule(this, subModule);
111 | }
112 |
113 | public void AttachMethod(JavaScriptNativeFunction method, string id)
114 | {
115 | AttachMethod(this, method, id);
116 | }
117 |
118 | public void AttachProperty(JavaScriptValue property, string id)
119 | {
120 | AttachProperty(this, property, id);
121 | }
122 |
123 | public JavaScriptValue GetModule()
124 | {
125 | return module;
126 | }
127 |
128 | public string GetId()
129 | {
130 | return id;
131 | }
132 |
133 | protected JavaScriptValue ToString(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
134 | {
135 | // TODO: Track members and list recursively
136 | return JavaScriptValue.FromString("[" + (asFunction ? "Function" : "Module") + ": " + id + "]");
137 | }
138 |
139 | protected virtual JavaScriptValue Main(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
140 | {
141 | return JavaScriptValue.Undefined;
142 | }
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSPath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using ChakraHost.Hosting;
7 |
8 | namespace Electrino.JS
9 | {
10 | class JSPath : AbstractJSModule
11 | {
12 | public JSPath() : base("path")
13 | {
14 | AttachMethod(Join, "join");
15 | }
16 |
17 | private static JavaScriptValue Join(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
18 | {
19 | string[] args = new string[arguments.Length - 1];
20 | for (int i = 1; i < arguments.Length; i++)
21 | {
22 | args[i - 1] = JSValToString(arguments[i]);
23 | }
24 | return JavaScriptValue.FromString(String.Join("\\", args));
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSProcess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using ChakraHost.Hosting;
7 | using Windows.ApplicationModel;
8 |
9 | namespace Electrino.JS
10 | {
11 | class JSProcess : AbstractJSModule
12 | {
13 | private Dictionary modules = new Dictionary();
14 |
15 | public JSProcess() : base("process")
16 | {
17 | AttachProperty(JavaScriptValue.FromString("win32"), "platform");
18 | AttachProperty(JavaScriptValue.FromString(Package.Current.Id.Architecture.ToString()), "arch");
19 | AttachModule(new JSProcessVersions());
20 | }
21 | }
22 |
23 | class JSProcessVersions : AbstractJSModule
24 | {
25 | private Dictionary modules = new Dictionary();
26 |
27 | public JSProcessVersions() : base("versions")
28 | {
29 | AttachProperty(JavaScriptValue.FromString("electrino"), "0.1.0");
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSRequire.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using ChakraHost.Hosting;
7 |
8 | namespace Electrino.JS
9 | {
10 | class JSRequire : AbstractJSModule
11 | {
12 | private Dictionary modules = new Dictionary();
13 |
14 | public JSRequire() : base("require", true)
15 | {
16 | AddModule(new JSPath());
17 | AddModule(new JSUrl());
18 | AddModule(new JSElectrino());
19 | }
20 |
21 | private void AddModule(AbstractJSModule module)
22 | {
23 | modules.Add(module.GetId(), module);
24 | }
25 |
26 | protected override JavaScriptValue Main(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
27 | {
28 | string moduleKey = AbstractJSModule.JSValToString(arguments[1]);
29 | AbstractJSModule module;
30 | if (!modules.TryGetValue(moduleKey, out module))
31 | {
32 | return JavaScriptValue.Undefined;
33 | }
34 | return module.GetModule();
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JSUrl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using ChakraHost.Hosting;
7 |
8 | namespace Electrino.JS
9 | {
10 | class JSUrl : AbstractJSModule
11 | {
12 | public JSUrl() : base("url")
13 | {
14 | AttachMethod(Format, "format");
15 | }
16 |
17 | private static JavaScriptValue Format(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData)
18 | {
19 | JavaScriptValue obj = arguments[1];
20 | string pathName = JSValToString(obj.GetProperty(JavaScriptPropertyId.FromString("pathname"))).Replace("\\", "/");
21 | string protocol = JSValToString(obj.GetProperty(JavaScriptPropertyId.FromString("protocol")));
22 | return JavaScriptValue.FromString(protocol + "//" + pathName);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JTokenToJavaScriptValueConverter.cs:
--------------------------------------------------------------------------------
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()
65 | ? JavaScriptValue.True
66 | : JavaScriptValue.False;
67 | }
68 |
69 | private JavaScriptValue VisitFloat(JValue token)
70 | {
71 | return AddRef(JavaScriptValue.FromDouble(token.Value()));
72 | }
73 |
74 | private JavaScriptValue VisitInteger(JValue token)
75 | {
76 | return AddRef(JavaScriptValue.FromDouble(token.Value()));
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()));
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 | }
115 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JS/JavaScriptValueToJTokenConverter.cs:
--------------------------------------------------------------------------------
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();
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 | }
109 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/JavaScriptApp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Collections;
7 | using System.Runtime.InteropServices;
8 | using ChakraHost.Hosting;
9 |
10 | namespace Electrino
11 | {
12 | class JavaScriptApp
13 | {
14 | private JavaScriptSourceContext currentSourceContext = JavaScriptSourceContext.FromIntPtr(IntPtr.Zero);
15 | private JavaScriptRuntime runtime;
16 | private JavaScriptContext context;
17 | private JS.AbstractJSModule console;
18 | private JS.AbstractJSModule require;
19 | private JS.AbstractJSModule process;
20 | private JavaScriptValue jsAppGlobalObject;
21 | private static Queue taskQueue = new Queue();
22 | private static readonly JavaScriptPromiseContinuationCallback promiseContinuationDelegate = PromiseContinuationCallback;
23 |
24 | private static void PromiseContinuationCallback(JavaScriptValue task, IntPtr callbackState)
25 | {
26 | taskQueue.Enqueue(task);
27 | task.AddRef();
28 | }
29 |
30 | public string Init()
31 | {
32 |
33 | if (Native.JsCreateRuntime(JavaScriptRuntimeAttributes.EnableIdleProcessing, null, out runtime) != JavaScriptErrorCode.NoError)
34 | return "failed to create runtime.";
35 |
36 | if (Native.JsCreateContext(runtime, out context) != JavaScriptErrorCode.NoError)
37 | return "failed to create execution context.";
38 |
39 | if (Native.JsSetCurrentContext(context) != JavaScriptErrorCode.NoError)
40 | return "failed to set current context.";
41 |
42 |
43 | if (Native.JsSetPromiseContinuationCallback(promiseContinuationDelegate, IntPtr.Zero) != JavaScriptErrorCode.NoError)
44 | return "failed to setup callback for ES6 Promise";
45 |
46 | if (Native.JsProjectWinRTNamespace("Windows") != JavaScriptErrorCode.NoError)
47 | return "failed to project windows namespace.";
48 |
49 | if (Native.JsStartDebugging() != JavaScriptErrorCode.NoError)
50 | return "failed to start debugging.";
51 |
52 |
53 | if (Native.JsGetGlobalObject(out jsAppGlobalObject) != JavaScriptErrorCode.NoError)
54 | return "failed to get global object";
55 |
56 | console = new JS.JSConsole();
57 | require = new JS.JSRequire();
58 | process = new JS.JSProcess();
59 | JS.AbstractJSModule.AttachModule(jsAppGlobalObject, require);
60 | JS.AbstractJSModule.AttachModule(jsAppGlobalObject, console);
61 | JS.AbstractJSModule.AttachModule(jsAppGlobalObject, process);
62 |
63 | return "NoError";
64 | }
65 |
66 | public string RunScript(string script)
67 | {
68 | IntPtr returnValue;
69 |
70 | try
71 | {
72 | JavaScriptValue result;
73 | // failing because of "no context"
74 | if (Native.JsRunScript(script, currentSourceContext++, "", out result) != JavaScriptErrorCode.NoError)
75 | {
76 | // Get error message and clear exception
77 | JavaScriptValue exception;
78 | if (Native.JsGetAndClearException(out exception) != JavaScriptErrorCode.NoError)
79 | return "failed to get and clear exception";
80 |
81 | JavaScriptPropertyId messageName;
82 | if (Native.JsGetPropertyIdFromName("message",
83 | out messageName) != JavaScriptErrorCode.NoError)
84 | return "failed to get error message id";
85 |
86 | JavaScriptValue messageValue;
87 | if (Native.JsGetProperty(exception, messageName, out messageValue)
88 | != JavaScriptErrorCode.NoError)
89 | return "failed to get error message";
90 |
91 | IntPtr message;
92 | UIntPtr length;
93 | if (Native.JsStringToPointer(messageValue, out message, out length) != JavaScriptErrorCode.NoError)
94 | return "failed to convert error message";
95 |
96 | return Marshal.PtrToStringUni(message);
97 | }
98 |
99 | // Execute promise tasks stored in taskQueue
100 | while (taskQueue.Count != 0)
101 | {
102 | JavaScriptValue task = (JavaScriptValue)taskQueue.Dequeue();
103 | JavaScriptValue promiseResult;
104 | JavaScriptValue[] args = new JavaScriptValue[1] { jsAppGlobalObject };
105 | Native.JsCallFunction(task, args, 1, out promiseResult);
106 | task.Release();
107 | }
108 |
109 | // Convert the return value.
110 | JavaScriptValue stringResult;
111 | UIntPtr stringLength;
112 | if (Native.JsConvertValueToString(result, out stringResult) != JavaScriptErrorCode.NoError)
113 | return "failed to convert value to string.";
114 | if (Native.JsStringToPointer(stringResult, out returnValue, out stringLength) != JavaScriptErrorCode.NoError)
115 | return "failed to convert return value.";
116 | }
117 | catch (Exception e)
118 | {
119 | return "chakrahost: fatal error: internal error: " + e.Message;
120 | }
121 |
122 | return Marshal.PtrToStringUni(returnValue);
123 | }
124 |
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices.WindowsRuntime;
6 | using Windows.Foundation;
7 | using Windows.Foundation.Collections;
8 | using Windows.UI.ViewManagement;
9 | using Windows.UI.Xaml;
10 | using Windows.UI.Xaml.Controls;
11 | using Windows.UI.Xaml.Controls.Primitives;
12 | using Windows.UI.Xaml.Data;
13 | using Windows.UI.Xaml.Input;
14 | using Windows.UI.Xaml.Media;
15 | using Windows.UI.Xaml.Navigation;
16 |
17 | // The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
18 |
19 | namespace Electrino
20 | {
21 | ///
22 | /// An empty page that can be used on its own or navigated to within a Frame.
23 | ///
24 | public sealed partial class MainPage : Page
25 | {
26 | private static MainPage instance = null;
27 | public MainPage()
28 | {
29 | instance = this;
30 | InitializeComponent();
31 | webView1.ScriptNotify += ScriptNotify;
32 | webView1.ContainsFullScreenElementChanged += webView1_ContainsFullScreenElementChanged;
33 |
34 | //webView1.Navigate(new Uri("ms-appx-web:///test-app/index.html"));
35 | }
36 |
37 | public static bool LoadURL(string url)
38 | {
39 | if (instance == null)
40 | {
41 | return false;
42 | }
43 | instance.webView1.Navigate(new Uri(url));
44 | return true;
45 | }
46 |
47 | private void WebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
48 | {
49 | AddRenderApis();
50 | }
51 |
52 | void ScriptNotify(object sender, NotifyEventArgs e)
53 | {
54 | App.Log($"Event received from {e.CallingUri}: \"{e.Value}\"");
55 | }
56 |
57 | private void AddRenderApis()
58 | {
59 | webView1.AddWebAllowedObject("process", new RenderAPI.JSProcess());
60 | webView1.AddWebAllowedObject("require", new RenderAPI.JSRequire().Main);
61 | }
62 |
63 | private void webView1_ContainsFullScreenElementChanged(WebView sender, object args)
64 | {
65 | var applicationView = ApplicationView.GetForCurrentView();
66 |
67 | if (sender.ContainsFullScreenElement)
68 | {
69 | applicationView.TryEnterFullScreenMode();
70 | }
71 | else if (applicationView.IsFullScreenMode)
72 | {
73 | applicationView.ExitFullScreenMode();
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Electrino
7 | Thomas
8 | Assets\StoreLogo.png
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Electrino")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Electrino")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/Properties/Default.rd.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/test-app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello World!
6 |
12 |
13 |
14 | Hello World!
15 | We are using Electrino:
16 |
21 |
22 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/test-app/main.js:
--------------------------------------------------------------------------------
1 | const electrino = require('electrino')
2 | const app = electrino.app
3 | const BrowserWindow = electrino.BrowserWindow
4 | const path = require('path');
5 | const url = require('url');
6 |
7 | // Keep a global reference of the window object, if you don't, the window will
8 | // be closed automatically when the JavaScript object is garbage collected.
9 | var win = null;
10 |
11 | console.log("hello world starting, app is: ", app);
12 |
13 | function createWindow() {
14 | // Create the browser window.
15 | win = new BrowserWindow({ width: 800, height: 600 });
16 |
17 | console.log("createWindow", BrowserWindow, win);
18 | // and load the index.html of the app.
19 | win.loadURL(url.format({
20 | pathname: path.join("/test-app", 'index.html'),
21 | protocol: 'ms-appx-web:',
22 | slashes: true
23 | }));
24 | // Emitted when the window is closed.
25 | win.on('closed', function () {
26 | // Dereference the window object, usually you would store windows
27 | // in an array if your app supports multi windows, this is the time
28 | // when you should delete the corresponding element.
29 | win = null;
30 | });
31 | }
32 |
33 |
34 | // This method will be called when Electron has finished
35 | // initialization and is ready to create browser windows.
36 | // Some APIs can only be used after this event occurs.
37 | app.on('ready', createWindow);
38 |
39 | // // Quit when all windows are closed.
40 | app.on('window-all-closed', function () {
41 | // On macOS it is common for applications and their menu bar
42 | // to stay active until the user quits explicitly with Cmd + Q
43 | if (process.platform !== 'darwin') {
44 | app.quit()
45 | }
46 | });
47 |
48 | app.on('activate', function () {
49 | // On macOS it's common to re-create a window in the app when the
50 | // dock icon is clicked and there are no other windows open.
51 | if (win === null) {
52 | createWindow()
53 | }
54 | });
55 |
--------------------------------------------------------------------------------
/Electrino/win10/Electrino/test-app/test.js:
--------------------------------------------------------------------------------
1 |
2 | const path = require("path");
3 | const url = require("url");
4 | console.log(path);
5 | console.log(require.toString());
6 | const fooPath = path.join('blah', 'foo');
7 | console.log(fooPath);
8 | console.log(url.format({ pathname: fooPath, protocol: "file:" }));
9 | console.log(path.toString());
10 | const electrino = require("electrino");
11 | const BrowserWindow = electrino.BrowserWindow;
12 | const app = electrino.app;
13 |
14 | function ready() {
15 | const win = new BrowserWindow();
16 | win.loadURL("ms-appx-web:///test-app/index.html");
17 | }
18 |
19 | console.log(app.toString());
20 | console.log(app.on("ready", ready));
21 | /*app.on("ready", );*/
22 |
--------------------------------------------------------------------------------
/Electrino/win10/RenderAPI/JSOs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Windows.ApplicationModel;
7 | using Windows.Foundation.Metadata;
8 | using Windows.System.Profile;
9 |
10 | namespace RenderAPI
11 | {
12 | [AllowForWeb]
13 | public sealed class JSOs
14 | {
15 | public string Platform()
16 | {
17 | return "win32";
18 | }
19 |
20 | public string Release()
21 | {
22 | string deviceFamilyVersion = AnalyticsInfo.VersionInfo.DeviceFamilyVersion;
23 | ulong version = ulong.Parse(deviceFamilyVersion);
24 | ulong major = (version & 0xFFFF000000000000L) >> 48;
25 | ulong minor = (version & 0x0000FFFF00000000L) >> 32;
26 | ulong build = (version & 0x00000000FFFF0000L) >> 16;
27 | ulong revision = (version & 0x000000000000FFFFL);
28 | return $"{major}.{minor}.{build}.{revision}";
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Electrino/win10/RenderAPI/JSProcess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Windows.ApplicationModel;
7 | using Windows.Foundation.Metadata;
8 |
9 | namespace RenderAPI
10 | {
11 | [AllowForWeb]
12 | public sealed class JSProcess
13 | {
14 | public string Platform
15 | {
16 | get
17 | {
18 | return "win32";
19 | }
20 | }
21 |
22 | public string Arch
23 | {
24 | get
25 | {
26 | return Package.Current.Id.Architecture.ToString();
27 | }
28 | }
29 |
30 | private AppVersions _versions = new AppVersions();
31 |
32 | public AppVersions Versions
33 | {
34 | get
35 | {
36 | return _versions;
37 | }
38 | }
39 |
40 | }
41 |
42 | [AllowForWeb]
43 | public sealed class AppVersions
44 | {
45 | public string Electrino
46 | {
47 | get
48 | {
49 | return "0.1.0";
50 | }
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Electrino/win10/RenderAPI/JSRequire.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Windows.Foundation.Metadata;
7 |
8 | namespace RenderAPI
9 | {
10 | public delegate object RequireFunc(string name);
11 |
12 | [AllowForWeb]
13 | public sealed class JSRequire
14 | {
15 | private Dictionary modules = new Dictionary();
16 |
17 | public RequireFunc Main
18 | {
19 | get
20 | {
21 | RequireFunc del = (string name) =>
22 | {
23 | modules.TryGetValue(name, out object module);
24 | return module;
25 | };
26 | return del;
27 | }
28 | }
29 |
30 | public JSRequire()
31 | {
32 | modules.Add("os", new JSOs());
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Electrino/win10/RenderAPI/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("RenderAPI")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("RenderAPI")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Version information for an assembly consists of the following four values:
18 | //
19 | // Major Version
20 | // Minor Version
21 | // Build Number
22 | // Revision
23 | //
24 | // You can specify all the values or you can default the Build and Revision Numbers
25 | // by using the '*' as shown below:
26 | // [assembly: AssemblyVersion("1.0.*")]
27 | [assembly: AssemblyVersion("1.0.0.0")]
28 | [assembly: AssemblyFileVersion("1.0.0.0")]
29 | [assembly: ComVisible(false)]
--------------------------------------------------------------------------------
/Electrino/win10/RenderAPI/RenderAPI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {77B6E3D3-17E6-46CB-B699-C118776F54DE}
8 | winmdobj
9 | Properties
10 | RenderAPI
11 | RenderAPI
12 | en-US
13 | UAP
14 | 10.0.15063.0
15 | 10.0.10586.0
16 | 14
17 | 512
18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
19 | false
20 |
21 |
22 | AnyCPU
23 | true
24 | full
25 | false
26 | bin\Debug\
27 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
28 | prompt
29 | 4
30 |
31 |
32 | AnyCPU
33 | pdbonly
34 | true
35 | bin\Release\
36 | TRACE;NETFX_CORE;WINDOWS_UWP
37 | prompt
38 | 4
39 |
40 |
41 | x86
42 | true
43 | bin\x86\Debug\
44 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
45 | ;2008
46 | full
47 | x86
48 | false
49 | prompt
50 |
51 |
52 | x86
53 | bin\x86\Release\
54 | TRACE;NETFX_CORE;WINDOWS_UWP
55 | true
56 | ;2008
57 | pdbonly
58 | x86
59 | false
60 | prompt
61 |
62 |
63 | ARM
64 | true
65 | bin\ARM\Debug\
66 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
67 | ;2008
68 | full
69 | ARM
70 | false
71 | prompt
72 |
73 |
74 | ARM
75 | bin\ARM\Release\
76 | TRACE;NETFX_CORE;WINDOWS_UWP
77 | true
78 | ;2008
79 | pdbonly
80 | ARM
81 | false
82 | prompt
83 |
84 |
85 | x64
86 | true
87 | bin\x64\Debug\
88 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
89 | ;2008
90 | full
91 | x64
92 | false
93 | prompt
94 |
95 |
96 | x64
97 | bin\x64\Release\
98 | TRACE;NETFX_CORE;WINDOWS_UWP
99 | true
100 | ;2008
101 | pdbonly
102 | x64
103 | false
104 | prompt
105 |
106 |
107 | PackageReference
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | 5.2.4
118 |
119 |
120 |
121 | 14.0
122 |
123 |
124 |
131 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Pauli Ojala
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # electrino
2 |
3 | An experimental desktop runtime for apps built on web technologies, using the system's own web browser engine. The project is still young and accepting contributions.
4 |
5 | Electrino aims to be a featherweight alternative to the popular and powerful [Electron](https://github.com/electron/electron). It implements a minuscule portion of the APIs available in Electron, but the output app size is much smaller.
6 |
7 | A "Hello World" app takes 115 MB using Electron, but only 167 kB using Electrino:
8 |
9 | 
10 |
11 | Read more about Electrino in [this post on DailyJS](https://medium.com/dailyjs/put-your-electron-app-on-a-diet-with-electrino-c7ffdf1d6297)
12 |
13 | ### Comparison
14 |
15 | Feature | Electron | Electrino
16 | --- | --- | ---
17 | Comprehensive API | Yes | No
18 | Small output size | No | Yes
19 | Cross-platform support | Yes | Limited to macOS and Windows 10 at this time
20 |
21 | ### Contribute
22 |
23 | - [x] Integrate `WebView`
24 | - [ ] Support `require()` calls
25 | - [ ] Add Node.js backend
26 |
27 | ### API
28 |
29 | Electrino currently supports the following API implementations:
30 |
31 | * app
32 | * BrowserWindow
33 | * ipcMain
34 | * Tray
35 | * nativeImage
36 |
37 | ### Roadmap
38 |
39 | The plan is to examine API usage of real-world apps that use Electron but don't really need the full capabilities. Good candidates are desktop utilities, menu bar apps and other small apps that users typically leave open. (For large productivity-style apps, Electron is a better choice.)
40 |
41 | Jan Hovancik offered his [Stretchly](https://github.com/hovancik/stretchly) app as a candidate, so I'm going to start by mapping out the APIs used by Stretchly and see what it would take to implement it with Electrino.
42 |
43 | If you have a small Electron-based Mac app and you'd like to try putting it on an Electrino diet, let's give it a try! My contact info is below.
44 |
45 | ### Contact
46 |
47 | * Pauli Olavi Ojala / @pauliooj / pauli @ lacquer.fi
48 | * Amila Welihinda / @amilajack / amilajack @ gmail.com
49 |
--------------------------------------------------------------------------------
/docs/electron-and-electrino-helloworld-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pojala/electrino/0bf75954b56440f0a0ec6aa83f2ce50d56ab52e2/docs/electron-and-electrino-helloworld-screenshot.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electrino",
3 | "version": "0.0.0",
4 | "description": "A desktop runtime for apps built on web technologies, using the system's own web browser engine.",
5 | "main": "index.js",
6 | "directories": {
7 | "doc": "docs"
8 | },
9 | "scripts": {
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/pojala/electrino.git"
15 | },
16 | "keywords": [],
17 | "contributors": [
18 | "Amila Welihinda (http://amilajack.com/)"
19 | ],
20 | "license": "MIT",
21 | "bugs": {
22 | "url": "https://github.com/pojala/electrino/issues"
23 | },
24 | "homepage": "https://github.com/pojala/electrino#readme"
25 | }
26 |
--------------------------------------------------------------------------------
/test-app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello World!
6 |
7 |
8 | Hello World!
9 | We are using Electrino .
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test-app/main.js:
--------------------------------------------------------------------------------
1 | const {app, BrowserWindow} = require('electrino')
2 | const path = require('path')
3 | const url = require('url')
4 |
5 | // Keep a global reference of the window object, if you don't, the window will
6 | // be closed automatically when the JavaScript object is garbage collected.
7 | let win
8 |
9 | function createWindow () {
10 | // Create the browser window.
11 | win = new BrowserWindow({width: 800, height: 600})
12 |
13 | // and load the index.html of the app.
14 | win.loadURL(url.format({
15 | pathname: path.join(__dirname, 'index.html'),
16 | protocol: 'file:',
17 | slashes: true
18 | }))
19 |
20 | // Open the DevTools.
21 | win.webContents.openDevTools()
22 |
23 | // Emitted when the window is closed.
24 | win.on('closed', () => {
25 | // Dereference the window object, usually you would store windows
26 | // in an array if your app supports multi windows, this is the time
27 | // when you should delete the corresponding element.
28 | win = null
29 | })
30 | }
31 |
32 | // This method will be called when Electron has finished
33 | // initialization and is ready to create browser windows.
34 | // Some APIs can only be used after this event occurs.
35 | app.on('ready', createWindow)
36 |
37 | // Quit when all windows are closed.
38 | app.on('window-all-closed', () => {
39 | // On macOS it is common for applications and their menu bar
40 | // to stay active until the user quits explicitly with Cmd + Q
41 | if (process.platform !== 'darwin') {
42 | app.quit()
43 | }
44 | })
45 |
46 | app.on('activate', () => {
47 | // On macOS it's common to re-create a window in the app when the
48 | // dock icon is clicked and there are no other windows open.
49 | if (win === null) {
50 | createWindow()
51 | }
52 | })
53 |
--------------------------------------------------------------------------------
/test-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "your-app",
3 | "version" : "0.1.0",
4 | "main" : "main.js"
5 | }
--------------------------------------------------------------------------------