Skip to content

Support for importing js files and modules via require #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 5 additions & 33 deletions Electrino/Electrino.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
5AA9DBB81EB9F58B00EF7CC9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5AA9DBB71EB9F58B00EF7CC9 /* Assets.xcassets */; };
5AA9DBBB1EB9F58B00EF7CC9 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5AA9DBB91EB9F58B00EF7CC9 /* MainMenu.xib */; };
5AA9DBC51EBA08BF00EF7CC9 /* ENOBrowserWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AA9DBC31EBA08BF00EF7CC9 /* ENOBrowserWindowController.m */; };
5AA9DBCF1EBA0BFC00EF7CC9 /* index.html in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5AA9DBC81EBA0BDD00EF7CC9 /* index.html */; };
5AA9DBD01EBA0BFC00EF7CC9 /* main.js in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5AA9DBC91EBA0BDD00EF7CC9 /* main.js */; };
5AA9DBD11EBA0BFC00EF7CC9 /* package.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5AA9DBCA1EBA0BDD00EF7CC9 /* package.json */; };
5AA9DBD41EBA0D1200EF7CC9 /* ENOJavaScriptApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AA9DBD31EBA0D1200EF7CC9 /* ENOJavaScriptApp.m */; };
5AA9DBDE1EBA4F7B00EF7CC9 /* ENOJSPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AA9DBDD1EBA4F7B00EF7CC9 /* ENOJSPath.m */; };
5AA9DBE41EBA4F9B00EF7CC9 /* ENOJSUrl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AA9DBE31EBA4F9B00EF7CC9 /* ENOJSUrl.m */; };
Expand All @@ -23,23 +20,9 @@
5AA9DBED1EBA55B700EF7CC9 /* ENOJSProcess.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AA9DBEC1EBA55B700EF7CC9 /* ENOJSProcess.m */; };
5AA9DBF01EBA564600EF7CC9 /* ENOJSConsole.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AA9DBEF1EBA564600EF7CC9 /* ENOJSConsole.m */; };
5AA9DBF21EBA7C0700EF7CC9 /* ENOBrowserWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5AA9DBF11EBA7C0700EF7CC9 /* ENOBrowserWindowController.xib */; };
BC44C7D01EBF2D0E008C569A /* app in Resources */ = {isa = PBXBuildFile; fileRef = BC44C7CF1EBF2D0E008C569A /* app */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
5AA9DBCE1EBA0BEA00EF7CC9 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = app;
dstSubfolderSpec = 7;
files = (
5AA9DBCF1EBA0BFC00EF7CC9 /* index.html in CopyFiles */,
5AA9DBD01EBA0BFC00EF7CC9 /* main.js in CopyFiles */,
5AA9DBD11EBA0BFC00EF7CC9 /* package.json in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
5AA9DBAE1EB9F58A00EF7CC9 /* ElectrinoTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ElectrinoTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
5AA9DBB11EB9F58B00EF7CC9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
Expand All @@ -50,9 +33,6 @@
5AA9DBBC1EB9F58B00EF7CC9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5AA9DBC21EBA08BE00EF7CC9 /* ENOBrowserWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOBrowserWindowController.h; sourceTree = "<group>"; };
5AA9DBC31EBA08BF00EF7CC9 /* ENOBrowserWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ENOBrowserWindowController.m; sourceTree = "<group>"; };
5AA9DBC81EBA0BDD00EF7CC9 /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
5AA9DBC91EBA0BDD00EF7CC9 /* main.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = "<group>"; };
5AA9DBCA1EBA0BDD00EF7CC9 /* package.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = package.json; sourceTree = "<group>"; };
5AA9DBD21EBA0D1200EF7CC9 /* ENOJavaScriptApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOJavaScriptApp.h; sourceTree = "<group>"; };
5AA9DBD31EBA0D1200EF7CC9 /* ENOJavaScriptApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ENOJavaScriptApp.m; sourceTree = "<group>"; };
5AA9DBDC1EBA4F7B00EF7CC9 /* ENOJSPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOJSPath.h; sourceTree = "<group>"; };
Expand All @@ -68,6 +48,7 @@
5AA9DBEE1EBA564600EF7CC9 /* ENOJSConsole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOJSConsole.h; sourceTree = "<group>"; };
5AA9DBEF1EBA564600EF7CC9 /* ENOJSConsole.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ENOJSConsole.m; sourceTree = "<group>"; };
5AA9DBF11EBA7C0700EF7CC9 /* ENOBrowserWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ENOBrowserWindowController.xib; sourceTree = "<group>"; };
BC44C7CF1EBF2D0E008C569A /* app */ = {isa = PBXFileReference; lastKnownFileType = folder; path = app; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -84,7 +65,7 @@
5AA9DBA51EB9F58A00EF7CC9 = {
isa = PBXGroup;
children = (
5AA9DBC71EBA0BDD00EF7CC9 /* test-app */,
BC44C7CF1EBF2D0E008C569A /* app */,
5AA9DBB01EB9F58A00EF7CC9 /* Electrino */,
5AA9DBAF1EB9F58A00EF7CC9 /* Products */,
);
Expand Down Expand Up @@ -125,16 +106,6 @@
name = "Supporting Files";
sourceTree = "<group>";
};
5AA9DBC71EBA0BDD00EF7CC9 /* test-app */ = {
isa = PBXGroup;
children = (
5AA9DBC81EBA0BDD00EF7CC9 /* index.html */,
5AA9DBC91EBA0BDD00EF7CC9 /* main.js */,
5AA9DBCA1EBA0BDD00EF7CC9 /* package.json */,
);
path = "test-app";
sourceTree = "<group>";
};
5AA9DBD51EBA4D8500EF7CC9 /* JS API implementations */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -164,7 +135,6 @@
5AA9DBAA1EB9F58A00EF7CC9 /* Sources */,
5AA9DBAB1EB9F58A00EF7CC9 /* Frameworks */,
5AA9DBAC1EB9F58A00EF7CC9 /* Resources */,
5AA9DBCE1EBA0BEA00EF7CC9 /* CopyFiles */,
);
buildRules = (
);
Expand Down Expand Up @@ -213,6 +183,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BC44C7D01EBF2D0E008C569A /* app in Resources */,
5AA9DBB81EB9F58B00EF7CC9 /* Assets.xcassets in Resources */,
5AA9DBF21EBA7C0700EF7CC9 /* ENOBrowserWindowController.xib in Resources */,
5AA9DBBB1EB9F58B00EF7CC9 /* MainMenu.xib in Resources */,
Expand Down Expand Up @@ -385,6 +356,7 @@
5AA9DBC11EB9F58B00EF7CC9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
Expand Down
59 changes: 55 additions & 4 deletions Electrino/Electrino/ENOJavaScriptApp.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,48 @@ - (id)init
[weakSelf _jsException:exception];
};

self.jsContext[@"require"] = ^(NSString *arg) {
id module = weakSelf.jsModules[arg];
return module;
self.jsContext[@"require"] = ^(NSString *arg) {

NSString *appDir = [[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"app"] stringByAppendingString:@"/"];

if ([arg hasSuffix:@".js"]) { // If a javascript file is being directly referenced
JSContext *tmpContext = [weakSelf newContextForEvaluation];

[tmpContext evaluateScript:[NSString stringWithContentsOfURL:[NSURL fileURLWithPath:[appDir stringByAppendingString:arg]] encoding:NSUTF8StringEncoding error:NULL]];
JSValue *module = tmpContext[@"module"];
return (id)[module valueForProperty:@"exports"]; // Casted to id as the compile doesn't like multiple types of return values when no return value is specified
} else if (weakSelf.jsModules[arg] != nil) {
id module = weakSelf.jsModules[arg];
return module;
}

BOOL isDirectory;
BOOL doesExist = [[NSFileManager defaultManager] fileExistsAtPath:[appDir stringByAppendingString:arg] isDirectory:&isDirectory];
if (doesExist && isDirectory) {
// Find where the starting point is within package.json
NSData *packageJSON = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[[appDir stringByAppendingString:arg] stringByAppendingString:@"/package.json"]]];
if (packageJSON == nil) {
return (id)nil;
}
NSDictionary *packageDictionary = [NSJSONSerialization JSONObjectWithData:packageJSON options:0 error:NULL];
if (packageDictionary == nil || packageDictionary[@"main"] == nil) {
return (id)nil;
}
NSString *mainJSFile = packageDictionary[@"main"];
NSURL *fileURL = [NSURL fileURLWithPath:packageDictionary[@"main"] relativeToURL:[NSURL fileURLWithPath:[appDir stringByAppendingString:arg]]];
mainJSFile = [@"/" stringByAppendingString:mainJSFile];
NSString *jsFileContents = [NSString stringWithContentsOfURL:fileURL encoding:NSUTF8StringEncoding error:NULL];

JSContext *tmpContext = [weakSelf newContextForEvaluation];

[tmpContext evaluateScript:jsFileContents];
JSValue *module = tmpContext[@"module"];
return (id)[module valueForProperty:@"exports"]; // Casted to id as the compile doesn't like multiple types of return values when no return value is specified
} else {
// Module doesn't exist!
}
return (id)nil;

};

self.jsContext[@"process"] = [[ENOJSProcess alloc] init];
Expand All @@ -88,6 +127,18 @@ - (id)init
return self;
}

// Create a new context for just evaluating the file
// ISSUE: JSContext does not include -copyWithZone: method, so we have to manually copy the required methods.
-(JSContext*)newContextForEvaluation
{
JSContext* newContext = [[JSContext alloc] initWithVirtualMachine:self.jsVM];
newContext[@"require"] = self.jsContext[@"require"];
newContext[@"process"] = self.jsContext[@"process"];
newContext[@"console"] = self.jsContext[@"console"];
[newContext evaluateScript:@"var exports = {}; var module = { exports }"]; // Evaluated so the developer doesnt have to
return newContext;
}

- (void)dealloc
{
self.jsContext.exceptionHandler = NULL;
Expand Down Expand Up @@ -129,7 +180,7 @@ - (BOOL)loadMainJS:(NSString *)js error:(NSError **)outError
}
return NO; // --
}
NSLog(@"%s done", __func__);

return YES;
Expand Down
File renamed without changes.
11 changes: 10 additions & 1 deletion Electrino/test-app/main.js → Electrino/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ console.log("hello world starting, app is: ", app);
function createWindow () {
// Create the browser window.
win = new BrowserWindow({width: 800, height: 600})

console.log("createWindow", BrowserWindow, win);

// and load the index.html of the app.
Expand All @@ -23,6 +23,7 @@ function createWindow () {
slashes: true
}))


// Emitted when the window is closed.
win.on('closed', function(){
// Dereference the window object, usually you would store windows
Expand Down Expand Up @@ -53,3 +54,11 @@ app.on('activate', function(){
createWindow()
}
})

const module_simple = require('module.js')
module_simple.custom_function();

const module_folder = require('module_folder')
module_folder.custom_function();

const module_exports = require('module_exports.js')();
5 changes: 5 additions & 0 deletions Electrino/app/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function custom_function() {
console.log("Function from a module!");
}

exports.custom_function = custom_function;
3 changes: 3 additions & 0 deletions Electrino/app/module_exports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function () {
console.log("Function from a module overwriting module.exports!");
}
5 changes: 5 additions & 0 deletions Electrino/app/module_folder/lib/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function custom_function() {
console.log("Function from a module within a folder!");
}

exports.custom_function = custom_function;
6 changes: 6 additions & 0 deletions Electrino/app/module_folder/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "module_folder",
"version": "0.0.1",
"description": "Testing modules in folders!",
"main": "./lib/main.js"
}
File renamed without changes.