Move fs support methods out of AtomController into FileSystemHelper

This commit is contained in:
Nathan Sobo 2012-01-04 18:01:31 -07:00
parent ee53616d82
commit be0fa84f1f
8 changed files with 154 additions and 70 deletions

View File

@ -27,6 +27,7 @@
047F26021457978C006DC904 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 047F26011457978C006DC904 /* JavaScriptCore.framework */; };
047F260414579792006DC904 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 047F260314579792006DC904 /* WebKit.framework */; };
047F260E145883B9006DC904 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 047F260D145883B9006DC904 /* Icon.icns */; };
EC846C4114B529120021AF1F /* FileSystemHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = EC846C4014B529120021AF1F /* FileSystemHelper.m */; };
ECBB172814A4F92400ACAAC1 /* AtomMenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = ECBB172714A4F92400ACAAC1 /* AtomMenuItem.m */; };
/* End PBXBuildFile section */
@ -70,6 +71,8 @@
047F26011457978C006DC904 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
047F260314579792006DC904 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
047F260D145883B9006DC904 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = "<group>"; };
EC846C3F14B529120021AF1F /* FileSystemHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileSystemHelper.h; path = Classes/FileSystemHelper.h; sourceTree = "<group>"; };
EC846C4014B529120021AF1F /* FileSystemHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FileSystemHelper.m; path = Classes/FileSystemHelper.m; sourceTree = "<group>"; };
ECBB172614A4F92400ACAAC1 /* AtomMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomMenuItem.h; path = Classes/AtomMenuItem.h; sourceTree = "<group>"; };
ECBB172714A4F92400ACAAC1 /* AtomMenuItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AtomMenuItem.m; path = Classes/AtomMenuItem.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -135,6 +138,8 @@
043D7E93145795B70078D710 /* AtomController.m */,
ECBB172614A4F92400ACAAC1 /* AtomMenuItem.h */,
ECBB172714A4F92400ACAAC1 /* AtomMenuItem.m */,
EC846C3F14B529120021AF1F /* FileSystemHelper.h */,
EC846C4014B529120021AF1F /* FileSystemHelper.m */,
043D7E6B145795B20078D710 /* JSCocoa */,
043D7E79145795B20078D710 /* UKKQueue */,
043D7E52145794990078D710 /* Supporting Files */,
@ -287,6 +292,7 @@
043D7E94145795B70078D710 /* AtomApp.m in Sources */,
043D7E95145795B70078D710 /* AtomController.m in Sources */,
ECBB172814A4F92400ACAAC1 /* AtomMenuItem.m in Sources */,
EC846C4114B529120021AF1F /* FileSystemHelper.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -1,8 +1,7 @@
#import <Cocoa/Cocoa.h>
#import "JSCocoa.h"
@class JSCocoa;
@class WebView;
@class JSCocoa, WebView, FileSystemHelper;
struct JSGlobalContextRef;
@ -11,6 +10,7 @@ struct JSGlobalContextRef;
@property (assign) WebView *webView;
@property (nonatomic, retain, readonly) NSString *url;
@property (nonatomic, retain, readonly) NSString *bootstrapScript;
@property (nonatomic, retain, readonly) FileSystemHelper *fs;
- (id)initForSpecs;
- (id)initWithURL:(NSString *)url;
@ -20,7 +20,4 @@ struct JSGlobalContextRef;
- (JSValueRefAndContextRef)jsWindow;
- (void)performActionForMenuItemPath:(NSString *)menuItemPath;
- (void)contentsOfDirectoryAtPath:(NSString *)path recursive:(BOOL)recursive onComplete:(JSValueRefAndContextRef)jsFunction;
@end

View File

@ -1,17 +1,21 @@
#import "AtomController.h"
#import "AtomApp.h"
#import "JSCocoa.h"
#import <WebKit/WebKit.h>
#import <dispatch/dispatch.h>
#import "AtomApp.h"
#import "FileSystemHelper.h"
@interface AtomController ()
@property (nonatomic, retain) JSCocoa *jscocoa;
@property (nonatomic, retain, readwrite) NSString *url;
@property (nonatomic, retain, readwrite) NSString *bootstrapScript;
@property (nonatomic, retain, readwrite) FileSystemHelper *fs;
- (void)createWebView;
- (void)blockUntilWebViewLoads;
@end
@interface WebView (Atom)
@ -26,12 +30,14 @@
@synthesize jscocoa = _jscocoa;
@synthesize url = _url;
@synthesize bootstrapScript = _bootstrapScript;
@synthesize fs = _fs;
- (void)dealloc {
self.webView = nil;
self.bootstrapScript = nil;
self.url = nil;
self.jscocoa = nil;
self.fs = nil;
[super dealloc];
}
@ -108,8 +114,7 @@
return PROJECT_DIR;
}
- (void)performActionForMenuItemPath:(NSString *)menuItemPath {
- (void)performActionForMenuItemPath:(NSString *)menuItemPath {
NSString *jsCode = [NSString stringWithFormat:@"window.performActionForMenuItemPath('%@')", menuItemPath];
[self.jscocoa evalJSString:jsCode];
}
@ -120,67 +125,6 @@
return windowWithContext;
}
- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path recursive:(BOOL)recursive {
NSFileManager *fm = [NSFileManager defaultManager];
NSMutableArray *paths = [NSMutableArray array];
if (recursive) {
NSDirectoryEnumerator *enumerator = [fm enumeratorAtPath:path];
NSString *subpath;
while (subpath = [enumerator nextObject]) {
[paths addObject:[path stringByAppendingPathComponent:subpath]];
}
} else {
NSError *error = nil;
NSArray *subpaths = [fm contentsOfDirectoryAtPath:path error:&error];
if (error) {
NSLog(@"ERROR %@", error.localizedDescription);
return nil;
}
for (NSString *subpath in subpaths) {
[paths addObject:[path stringByAppendingPathComponent:subpath]];
}
}
return paths;
}
- (JSContextRef)ctx {
return self.jscocoa.ctx;
}
- (JSValueRef)convertToJSArrayOfStrings:(NSArray *)nsArray {
JSValueRef *cArray = malloc(sizeof(JSValueRef) * nsArray.count);
for (int i = 0; i < nsArray.count; i++) {
JSStringRef jsString = JSStringCreateWithCFString((CFStringRef)[nsArray objectAtIndex:i]);
cArray[i] = JSValueMakeString(self.ctx, jsString);
JSStringRelease(jsString);
}
JSValueRef jsArray = (JSValueRef)JSObjectMakeArray(self.ctx, nsArray.count, cArray, NULL);
free(cArray);
return jsArray;
}
- (void)contentsOfDirectoryAtPath:(NSString *)path recursive:(BOOL)recursive onComplete:(JSValueRefAndContextRef)onComplete {
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(0, 0);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
JSValueRef onCompleteFn = onComplete.value;
JSValueProtect(self.ctx, onCompleteFn);
dispatch_async(backgroundQueue, ^{
NSArray *paths = [self contentsOfDirectoryAtPath:path recursive:recursive];
JSValueRef jsPaths = [self convertToJSArrayOfStrings:paths];
dispatch_sync(mainQueue, ^{
JSValueRef args[] = { jsPaths };
JSObjectCallAsFunction(self.ctx, JSValueToObject(self.ctx, onCompleteFn, NULL), NULL, 1, args, NULL);
JSValueUnprotect(self.ctx, onCompleteFn);
});
});
}
- (BOOL)isFile:(NSString *)path {
BOOL isDir;
BOOL exists;
@ -226,6 +170,7 @@
self.jscocoa = [[JSCocoa alloc] initWithGlobalContext:[frame globalContext]];
[self.jscocoa setObject:self withName:@"$atomController"];
[self.jscocoa setObject:self.bootstrapScript withName:@"$bootstrapScript"];
self.fs = [[[FileSystemHelper alloc] initWithJSContextRef:(JSContextRef)self.jscocoa.ctx] autorelease];
}
@end

View File

@ -0,0 +1,12 @@
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
#import "JSCocoa.h"
@interface FileSystemHelper : NSObject {
JSContextRef _ctx;
}
- (id)initWithJSContextRef:(JSContextRef)ctx;
- (void)contentsOfDirectoryAtPath:(NSString *)path recursive:(BOOL)recursive onComplete:(JSValueRefAndContextRef)jsFunction;
@end

View File

@ -0,0 +1,74 @@
#import "FileSystemHelper.h"
@interface FileSystemHelper ()
- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path recursive:(BOOL)recursive;
- (JSValueRef)convertToJSArrayOfStrings:(NSArray *)nsArray;
@end
@implementation FileSystemHelper
- (id)initWithJSContextRef:(JSContextRef)ctx {
self = [super init];
_ctx = ctx;
return self;
}
- (void)contentsOfDirectoryAtPath:(NSString *)path recursive:(BOOL)recursive onComplete:(JSValueRefAndContextRef)onComplete {
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(0, 0);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
JSValueRef onCompleteFn = onComplete.value;
JSValueProtect(_ctx, onCompleteFn);
dispatch_async(backgroundQueue, ^{
NSArray *paths = [self contentsOfDirectoryAtPath:path recursive:recursive];
JSValueRef jsPaths = [self convertToJSArrayOfStrings:paths];
dispatch_sync(mainQueue, ^{
JSValueRef args[] = { jsPaths };
JSObjectCallAsFunction(_ctx, JSValueToObject(_ctx, onCompleteFn, NULL), NULL, 1, args, NULL);
JSValueUnprotect(_ctx, onCompleteFn);
});
});
}
- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path recursive:(BOOL)recursive {
NSFileManager *fm = [NSFileManager defaultManager];
NSMutableArray *paths = [NSMutableArray array];
if (recursive) {
NSDirectoryEnumerator *enumerator = [fm enumeratorAtPath:path];
NSString *subpath;
while (subpath = [enumerator nextObject]) {
[paths addObject:[path stringByAppendingPathComponent:subpath]];
}
} else {
NSError *error = nil;
NSArray *subpaths = [fm contentsOfDirectoryAtPath:path error:&error];
if (error) {
NSLog(@"ERROR %@", error.localizedDescription);
return nil;
}
for (NSString *subpath in subpaths) {
[paths addObject:[path stringByAppendingPathComponent:subpath]];
}
}
return paths;
}
- (JSValueRef)convertToJSArrayOfStrings:(NSArray *)nsArray {
JSValueRef *cArray = malloc(sizeof(JSValueRef) * nsArray.count);
for (int i = 0; i < nsArray.count; i++) {
JSStringRef jsString = JSStringCreateWithCFString((CFStringRef)[nsArray objectAtIndex:i]);
cArray[i] = JSValueMakeString(_ctx, jsString);
JSStringRelease(jsString);
}
JSValueRef jsArray = (JSValueRef)JSObjectMakeArray(_ctx, nsArray.count, cArray, NULL);
free(cArray);
return jsArray;
}
@end

View File

@ -38,3 +38,4 @@ describe "App", ->
expect(newWindow.rootView.editor.buffer.url).toBeUndefined
expect(newWindow.rootView.editor.buffer.getText()).toBe ""

49
spec/atom/app-spec.js Normal file
View File

@ -0,0 +1,49 @@
(function() {
var App, fs;
App = require('app');
fs = require('fs');
describe("App", function() {
var app;
app = null;
beforeEach(function() {
return app = new App();
});
afterEach(function() {
var window, _i, _len, _ref;
_ref = app.windows();
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
window = _ref[_i];
window.close();
}
return waitsFor(function() {
return app.windows().length === 0;
});
});
return describe("open", function() {
describe("when opening a filePath", function() {
return it("loads a buffer with filePath contents and displays it in a new window", function() {
var filePath, newWindow;
filePath = require.resolve('fixtures/sample.txt');
expect(app.windows().length).toBe(0);
app.open(filePath);
expect(app.windows().length).toBe(1);
newWindow = app.windows()[0];
expect(newWindow.rootView.editor.buffer.url).toEqual(filePath);
return expect(newWindow.rootView.editor.buffer.getText()).toEqual(fs.read(filePath));
});
});
return describe("when opening a dirPath", function() {
return it("loads an empty buffer", function() {
var dirPath, newWindow;
dirPath = require.resolve('fixtures');
expect(app.windows().length).toBe(0);
app.open(dirPath);
expect(app.windows().length).toBe(1);
newWindow = app.windows()[0];
expect(newWindow.rootView.editor.buffer.url).toBeUndefined;
return expect(newWindow.rootView.editor.buffer.getText()).toBe("");
});
});
});
});
}).call(this);

View File

@ -89,7 +89,7 @@ module.exports =
async:
list: (path, recursive) ->
deferred = $.Deferred()
$atomController.contentsOfDirectoryAtPath_recursive_onComplete path, recursive, (subpaths) ->
$atomController.fs.contentsOfDirectoryAtPath_recursive_onComplete path, recursive, (subpaths) ->
deferred.resolve subpaths
deferred