From 96f3c6439234fe33a5d1a30b8cba98b50a0d7a03 Mon Sep 17 00:00:00 2001 From: Ninjaprawn Date: Sun, 7 May 2017 20:01:36 +1000 Subject: [PATCH 1/4] Added support to import js files via `require` --- Electrino/Electrino.xcodeproj/project.pbxproj | 11 ++++++-- Electrino/Electrino/ENOJavaScriptApp.m | 28 +++++++++++++++++-- Electrino/test-app/main.js | 6 +++- Electrino/test-app/module.js | 5 ++++ 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 Electrino/test-app/module.js diff --git a/Electrino/Electrino.xcodeproj/project.pbxproj b/Electrino/Electrino.xcodeproj/project.pbxproj index 78d8e21..58dbb2e 100644 --- a/Electrino/Electrino.xcodeproj/project.pbxproj +++ b/Electrino/Electrino.xcodeproj/project.pbxproj @@ -14,7 +14,6 @@ 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 */; }; @@ -23,6 +22,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 */; }; + BC2FA6DD1EBF17E100016A52 /* module.js in Resources */ = {isa = PBXBuildFile; fileRef = BC2FA6DC1EBF17E100016A52 /* module.js */; }; + BC2FA6DE1EBF197C00016A52 /* module.js in CopyFiles */ = {isa = PBXBuildFile; fileRef = BC2FA6DC1EBF17E100016A52 /* module.js */; }; + BC2FA6DF1EBF198A00016A52 /* package.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5AA9DBCA1EBA0BDD00EF7CC9 /* package.json */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -32,9 +34,10 @@ dstPath = app; dstSubfolderSpec = 7; files = ( + BC2FA6DF1EBF198A00016A52 /* package.json in CopyFiles */, + BC2FA6DE1EBF197C00016A52 /* module.js in CopyFiles */, 5AA9DBCF1EBA0BFC00EF7CC9 /* index.html in CopyFiles */, 5AA9DBD01EBA0BFC00EF7CC9 /* main.js in CopyFiles */, - 5AA9DBD11EBA0BFC00EF7CC9 /* package.json in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -68,6 +71,7 @@ 5AA9DBEE1EBA564600EF7CC9 /* ENOJSConsole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOJSConsole.h; sourceTree = ""; }; 5AA9DBEF1EBA564600EF7CC9 /* ENOJSConsole.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ENOJSConsole.m; sourceTree = ""; }; 5AA9DBF11EBA7C0700EF7CC9 /* ENOBrowserWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ENOBrowserWindowController.xib; sourceTree = ""; }; + BC2FA6DC1EBF17E100016A52 /* module.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = module.js; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -131,6 +135,7 @@ 5AA9DBC81EBA0BDD00EF7CC9 /* index.html */, 5AA9DBC91EBA0BDD00EF7CC9 /* main.js */, 5AA9DBCA1EBA0BDD00EF7CC9 /* package.json */, + BC2FA6DC1EBF17E100016A52 /* module.js */, ); path = "test-app"; sourceTree = ""; @@ -215,6 +220,7 @@ files = ( 5AA9DBB81EB9F58B00EF7CC9 /* Assets.xcassets in Resources */, 5AA9DBF21EBA7C0700EF7CC9 /* ENOBrowserWindowController.xib in Resources */, + BC2FA6DD1EBF17E100016A52 /* module.js in Resources */, 5AA9DBBB1EB9F58B00EF7CC9 /* MainMenu.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -385,6 +391,7 @@ 5AA9DBC11EB9F58B00EF7CC9 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/Electrino/Electrino/ENOJavaScriptApp.m b/Electrino/Electrino/ENOJavaScriptApp.m index ffc3604..feaf788 100644 --- a/Electrino/Electrino/ENOJavaScriptApp.m +++ b/Electrino/Electrino/ENOJavaScriptApp.m @@ -78,8 +78,18 @@ - (id)init }; self.jsContext[@"require"] = ^(NSString *arg) { - id module = weakSelf.jsModules[arg]; - return module; + + if ([arg hasSuffix:@".js"]) { // If a javascript file is being directly referenced + NSString *appDir = [[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"app"] stringByAppendingString:@"/"]; + JSContext *tmpContext = [weakSelf newContextForEvaluation]; + + [tmpContext evaluateScript:[NSString stringWithContentsOfURL:[NSURL fileURLWithPath:[appDir stringByAppendingString:arg]] encoding:NSUTF8StringEncoding error:NULL]]; + return (id)[tmpContext objectForKeyedSubscript:@"exports"]; // Casted to id as the compile doesn't like multiple types of return values when no return value is specified + } else { + id module = weakSelf.jsModules[arg]; + return module; + } + }; self.jsContext[@"process"] = [[ENOJSProcess alloc] init]; @@ -88,6 +98,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 = {};"]; // Evaluated so the developer doesnt have to + return newContext; +} + - (void)dealloc { self.jsContext.exceptionHandler = NULL; @@ -129,7 +151,7 @@ - (BOOL)loadMainJS:(NSString *)js error:(NSError **)outError } return NO; // -- } - + NSLog(@"%s done", __func__); return YES; diff --git a/Electrino/test-app/main.js b/Electrino/test-app/main.js index e70cabb..b312501 100644 --- a/Electrino/test-app/main.js +++ b/Electrino/test-app/main.js @@ -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. @@ -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 @@ -53,3 +54,6 @@ app.on('activate', function(){ createWindow() } }) + +const module = require('module.js') +module.custom_function(); diff --git a/Electrino/test-app/module.js b/Electrino/test-app/module.js new file mode 100644 index 0000000..9410927 --- /dev/null +++ b/Electrino/test-app/module.js @@ -0,0 +1,5 @@ +function custom_function() { + console.log("Function from a module!"); +} + +exports.custom_function = custom_function; From 0f2a79ad1c3f63eb911da71730b51a9526d36129 Mon Sep 17 00:00:00 2001 From: Ninjaprawn Date: Sun, 7 May 2017 20:31:07 +1000 Subject: [PATCH 2/4] Added support for modules within a folder --- Electrino/Electrino.xcodeproj/project.pbxproj | 43 ++----------------- Electrino/Electrino/ENOJavaScriptApp.m | 36 ++++++++++++++-- Electrino/{test-app => app}/index.html | 0 Electrino/{test-app => app}/main.js | 3 ++ Electrino/{test-app => app}/module.js | 0 Electrino/app/module_folder/main.js | 5 +++ Electrino/app/module_folder/package.json | 6 +++ Electrino/{test-app => app}/package.json | 0 8 files changed, 51 insertions(+), 42 deletions(-) rename Electrino/{test-app => app}/index.html (100%) rename Electrino/{test-app => app}/main.js (95%) rename Electrino/{test-app => app}/module.js (100%) create mode 100644 Electrino/app/module_folder/main.js create mode 100644 Electrino/app/module_folder/package.json rename Electrino/{test-app => app}/package.json (100%) diff --git a/Electrino/Electrino.xcodeproj/project.pbxproj b/Electrino/Electrino.xcodeproj/project.pbxproj index 58dbb2e..9a3167d 100644 --- a/Electrino/Electrino.xcodeproj/project.pbxproj +++ b/Electrino/Electrino.xcodeproj/project.pbxproj @@ -12,8 +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 */; }; 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 */; }; @@ -22,27 +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 */; }; - BC2FA6DD1EBF17E100016A52 /* module.js in Resources */ = {isa = PBXBuildFile; fileRef = BC2FA6DC1EBF17E100016A52 /* module.js */; }; - BC2FA6DE1EBF197C00016A52 /* module.js in CopyFiles */ = {isa = PBXBuildFile; fileRef = BC2FA6DC1EBF17E100016A52 /* module.js */; }; - BC2FA6DF1EBF198A00016A52 /* package.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5AA9DBCA1EBA0BDD00EF7CC9 /* package.json */; }; + 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 = ( - BC2FA6DF1EBF198A00016A52 /* package.json in CopyFiles */, - BC2FA6DE1EBF197C00016A52 /* module.js in CopyFiles */, - 5AA9DBCF1EBA0BFC00EF7CC9 /* index.html in CopyFiles */, - 5AA9DBD01EBA0BFC00EF7CC9 /* main.js 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 = ""; }; @@ -53,9 +33,6 @@ 5AA9DBBC1EB9F58B00EF7CC9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5AA9DBC21EBA08BE00EF7CC9 /* ENOBrowserWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOBrowserWindowController.h; sourceTree = ""; }; 5AA9DBC31EBA08BF00EF7CC9 /* ENOBrowserWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ENOBrowserWindowController.m; sourceTree = ""; }; - 5AA9DBC81EBA0BDD00EF7CC9 /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = ""; }; - 5AA9DBC91EBA0BDD00EF7CC9 /* main.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = main.js; sourceTree = ""; }; - 5AA9DBCA1EBA0BDD00EF7CC9 /* package.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = package.json; sourceTree = ""; }; 5AA9DBD21EBA0D1200EF7CC9 /* ENOJavaScriptApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOJavaScriptApp.h; sourceTree = ""; }; 5AA9DBD31EBA0D1200EF7CC9 /* ENOJavaScriptApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ENOJavaScriptApp.m; sourceTree = ""; }; 5AA9DBDC1EBA4F7B00EF7CC9 /* ENOJSPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOJSPath.h; sourceTree = ""; }; @@ -71,7 +48,7 @@ 5AA9DBEE1EBA564600EF7CC9 /* ENOJSConsole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ENOJSConsole.h; sourceTree = ""; }; 5AA9DBEF1EBA564600EF7CC9 /* ENOJSConsole.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ENOJSConsole.m; sourceTree = ""; }; 5AA9DBF11EBA7C0700EF7CC9 /* ENOBrowserWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ENOBrowserWindowController.xib; sourceTree = ""; }; - BC2FA6DC1EBF17E100016A52 /* module.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = module.js; sourceTree = ""; }; + BC44C7CF1EBF2D0E008C569A /* app */ = {isa = PBXFileReference; lastKnownFileType = folder; path = app; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,7 +65,7 @@ 5AA9DBA51EB9F58A00EF7CC9 = { isa = PBXGroup; children = ( - 5AA9DBC71EBA0BDD00EF7CC9 /* test-app */, + BC44C7CF1EBF2D0E008C569A /* app */, 5AA9DBB01EB9F58A00EF7CC9 /* Electrino */, 5AA9DBAF1EB9F58A00EF7CC9 /* Products */, ); @@ -129,17 +106,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 5AA9DBC71EBA0BDD00EF7CC9 /* test-app */ = { - isa = PBXGroup; - children = ( - 5AA9DBC81EBA0BDD00EF7CC9 /* index.html */, - 5AA9DBC91EBA0BDD00EF7CC9 /* main.js */, - 5AA9DBCA1EBA0BDD00EF7CC9 /* package.json */, - BC2FA6DC1EBF17E100016A52 /* module.js */, - ); - path = "test-app"; - sourceTree = ""; - }; 5AA9DBD51EBA4D8500EF7CC9 /* JS API implementations */ = { isa = PBXGroup; children = ( @@ -169,7 +135,6 @@ 5AA9DBAA1EB9F58A00EF7CC9 /* Sources */, 5AA9DBAB1EB9F58A00EF7CC9 /* Frameworks */, 5AA9DBAC1EB9F58A00EF7CC9 /* Resources */, - 5AA9DBCE1EBA0BEA00EF7CC9 /* CopyFiles */, ); buildRules = ( ); @@ -218,9 +183,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + BC44C7D01EBF2D0E008C569A /* app in Resources */, 5AA9DBB81EB9F58B00EF7CC9 /* Assets.xcassets in Resources */, 5AA9DBF21EBA7C0700EF7CC9 /* ENOBrowserWindowController.xib in Resources */, - BC2FA6DD1EBF17E100016A52 /* module.js in Resources */, 5AA9DBBB1EB9F58B00EF7CC9 /* MainMenu.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Electrino/Electrino/ENOJavaScriptApp.m b/Electrino/Electrino/ENOJavaScriptApp.m index feaf788..12bac9b 100644 --- a/Electrino/Electrino/ENOJavaScriptApp.m +++ b/Electrino/Electrino/ENOJavaScriptApp.m @@ -77,19 +77,49 @@ - (id)init [weakSelf _jsException:exception]; }; - self.jsContext[@"require"] = ^(NSString *arg) { + 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 - NSString *appDir = [[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"app"] stringByAppendingString:@"/"]; JSContext *tmpContext = [weakSelf newContextForEvaluation]; [tmpContext evaluateScript:[NSString stringWithContentsOfURL:[NSURL fileURLWithPath:[appDir stringByAppendingString:arg]] encoding:NSUTF8StringEncoding error:NULL]]; return (id)[tmpContext objectForKeyedSubscript:@"exports"]; // Casted to id as the compile doesn't like multiple types of return values when no return value is specified - } else { + } 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"]; + if ([mainJSFile hasPrefix:@"./"]) { + mainJSFile = [packageDictionary[@"main"] substringFromIndex:2]; + } + mainJSFile = [@"/" stringByAppendingString:mainJSFile]; + NSString *jsFileContents = [NSString stringWithContentsOfURL:[NSURL fileURLWithPath:[[appDir stringByAppendingString:arg] stringByAppendingString:mainJSFile]] encoding:NSUTF8StringEncoding error:NULL]; + + JSContext *tmpContext = [weakSelf newContextForEvaluation]; + + [tmpContext evaluateScript:jsFileContents]; + return (id)[tmpContext objectForKeyedSubscript:@"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]; diff --git a/Electrino/test-app/index.html b/Electrino/app/index.html similarity index 100% rename from Electrino/test-app/index.html rename to Electrino/app/index.html diff --git a/Electrino/test-app/main.js b/Electrino/app/main.js similarity index 95% rename from Electrino/test-app/main.js rename to Electrino/app/main.js index b312501..cf2ed24 100644 --- a/Electrino/test-app/main.js +++ b/Electrino/app/main.js @@ -57,3 +57,6 @@ app.on('activate', function(){ const module = require('module.js') module.custom_function(); + +const module_folder = require('module_folder') +module_folder.custom_function(); diff --git a/Electrino/test-app/module.js b/Electrino/app/module.js similarity index 100% rename from Electrino/test-app/module.js rename to Electrino/app/module.js diff --git a/Electrino/app/module_folder/main.js b/Electrino/app/module_folder/main.js new file mode 100644 index 0000000..1916274 --- /dev/null +++ b/Electrino/app/module_folder/main.js @@ -0,0 +1,5 @@ +function custom_function() { + console.log("Function from a module within a folder!"); +} + +exports.custom_function = custom_function; diff --git a/Electrino/app/module_folder/package.json b/Electrino/app/module_folder/package.json new file mode 100644 index 0000000..b6eec9f --- /dev/null +++ b/Electrino/app/module_folder/package.json @@ -0,0 +1,6 @@ +{ + "name": "module_folder", + "version": "0.0.1", + "description": "Testing modules in folders!", + "main": "./main.js" +} diff --git a/Electrino/test-app/package.json b/Electrino/app/package.json similarity index 100% rename from Electrino/test-app/package.json rename to Electrino/app/package.json From 696e4cb3e074aa4c2a5469fafba0100ed370fdf0 Mon Sep 17 00:00:00 2001 From: Ninjaprawn Date: Mon, 8 May 2017 15:53:48 +1000 Subject: [PATCH 3/4] Properly resolve file URL, rather than manually doing so --- Electrino/Electrino/ENOJavaScriptApp.m | 6 ++---- Electrino/app/module_folder/{ => lib}/main.js | 0 Electrino/app/module_folder/package.json | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) rename Electrino/app/module_folder/{ => lib}/main.js (100%) diff --git a/Electrino/Electrino/ENOJavaScriptApp.m b/Electrino/Electrino/ENOJavaScriptApp.m index 12bac9b..6af96fd 100644 --- a/Electrino/Electrino/ENOJavaScriptApp.m +++ b/Electrino/Electrino/ENOJavaScriptApp.m @@ -104,11 +104,9 @@ - (id)init return (id)nil; } NSString *mainJSFile = packageDictionary[@"main"]; - if ([mainJSFile hasPrefix:@"./"]) { - mainJSFile = [packageDictionary[@"main"] substringFromIndex:2]; - } + NSURL *fileURL = [NSURL fileURLWithPath:packageDictionary[@"main"] relativeToURL:[NSURL fileURLWithPath:[appDir stringByAppendingString:arg]]]; mainJSFile = [@"/" stringByAppendingString:mainJSFile]; - NSString *jsFileContents = [NSString stringWithContentsOfURL:[NSURL fileURLWithPath:[[appDir stringByAppendingString:arg] stringByAppendingString:mainJSFile]] encoding:NSUTF8StringEncoding error:NULL]; + NSString *jsFileContents = [NSString stringWithContentsOfURL:fileURL encoding:NSUTF8StringEncoding error:NULL]; JSContext *tmpContext = [weakSelf newContextForEvaluation]; diff --git a/Electrino/app/module_folder/main.js b/Electrino/app/module_folder/lib/main.js similarity index 100% rename from Electrino/app/module_folder/main.js rename to Electrino/app/module_folder/lib/main.js diff --git a/Electrino/app/module_folder/package.json b/Electrino/app/module_folder/package.json index b6eec9f..18e13fd 100644 --- a/Electrino/app/module_folder/package.json +++ b/Electrino/app/module_folder/package.json @@ -2,5 +2,5 @@ "name": "module_folder", "version": "0.0.1", "description": "Testing modules in folders!", - "main": "./main.js" + "main": "./lib/main.js" } From 3720f498e715f416d7ae7c8ca4689aae2102391c Mon Sep 17 00:00:00 2001 From: Alberto Gimeno Date: Tue, 9 May 2017 13:12:44 +0200 Subject: [PATCH 4/4] Better support for "module" and "exports" --- Electrino/Electrino/ENOJavaScriptApp.m | 9 +++++---- Electrino/app/main.js | 6 ++++-- Electrino/app/module_exports.js | 3 +++ 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 Electrino/app/module_exports.js diff --git a/Electrino/Electrino/ENOJavaScriptApp.m b/Electrino/Electrino/ENOJavaScriptApp.m index 6af96fd..934b7f4 100644 --- a/Electrino/Electrino/ENOJavaScriptApp.m +++ b/Electrino/Electrino/ENOJavaScriptApp.m @@ -85,7 +85,8 @@ - (id)init JSContext *tmpContext = [weakSelf newContextForEvaluation]; [tmpContext evaluateScript:[NSString stringWithContentsOfURL:[NSURL fileURLWithPath:[appDir stringByAppendingString:arg]] encoding:NSUTF8StringEncoding error:NULL]]; - return (id)[tmpContext objectForKeyedSubscript:@"exports"]; // Casted to id as the compile doesn't like multiple types of return values when no return value is specified + 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; @@ -111,8 +112,8 @@ - (id)init JSContext *tmpContext = [weakSelf newContextForEvaluation]; [tmpContext evaluateScript:jsFileContents]; - return (id)[tmpContext objectForKeyedSubscript:@"exports"]; // Casted to id as the compile doesn't like multiple types of return values when no return value is specified - + 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! } @@ -134,7 +135,7 @@ -(JSContext*)newContextForEvaluation newContext[@"require"] = self.jsContext[@"require"]; newContext[@"process"] = self.jsContext[@"process"]; newContext[@"console"] = self.jsContext[@"console"]; - [newContext evaluateScript:@"var exports = {};"]; // Evaluated so the developer doesnt have to + [newContext evaluateScript:@"var exports = {}; var module = { exports }"]; // Evaluated so the developer doesnt have to return newContext; } diff --git a/Electrino/app/main.js b/Electrino/app/main.js index cf2ed24..36c2686 100644 --- a/Electrino/app/main.js +++ b/Electrino/app/main.js @@ -55,8 +55,10 @@ app.on('activate', function(){ } }) -const module = require('module.js') -module.custom_function(); +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')(); diff --git a/Electrino/app/module_exports.js b/Electrino/app/module_exports.js new file mode 100644 index 0000000..a085dd5 --- /dev/null +++ b/Electrino/app/module_exports.js @@ -0,0 +1,3 @@ +module.exports = function () { + console.log("Function from a module overwriting module.exports!"); +}