diff --git a/Atom.xcodeproj/project.pbxproj b/Atom.xcodeproj/project.pbxproj index 0ce3e21bf..139e5252f 100644 --- a/Atom.xcodeproj/project.pbxproj +++ b/Atom.xcodeproj/project.pbxproj @@ -323,6 +323,7 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; @@ -345,6 +346,7 @@ GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; diff --git a/Atom/Classes/AtomApp.h b/Atom/Classes/AtomApp.h index 7fd2e8550..3aa222d09 100644 --- a/Atom/Classes/AtomApp.h +++ b/Atom/Classes/AtomApp.h @@ -6,9 +6,6 @@ @property (nonatomic, retain) NSMutableArray *controllers; -- (AtomController *)createController:(NSString *)path; -- (AtomController *)createController:(NSString *)path; - (void)removeController:(AtomController *)controller; -- (void)reloadController:(AtomController *)controller; @end diff --git a/Atom/Classes/AtomApp.m b/Atom/Classes/AtomApp.m index 294befd79..da421be4e 100644 --- a/Atom/Classes/AtomApp.m +++ b/Atom/Classes/AtomApp.m @@ -11,46 +11,31 @@ @synthesize controllers = _controllers; -- (AtomController *)createController:(NSString *)path { - AtomController *controller = [[AtomController alloc] initWithURL:path]; - [self.controllers addObject:controller]; - return controller; -} - - (AtomController *)createSpecController { AtomController *controller = [[AtomController alloc] initForSpecs]; - [self.controllers addObject:controller]; return controller; } - (void)removeController:(AtomController *)controller { [self.controllers removeObject:controller]; - [controller.jscocoa callJSFunctionNamed:@"triggerEvent" withArguments:@"window:close", nil, false, nil]; -} - -- (void)reloadController:(AtomController *)controller { - [controller createWebView]; } - (void)open:(NSString *)path { - if (!path) { - NSOpenPanel *panel =[NSOpenPanel openPanel]; - panel.canChooseDirectories = YES; - if (panel.runModal != NSFileHandlingPanelOKButton) return; - - path = [[[panel URLs] lastObject] path]; - } - - [self createController:path]; + AtomController *controller = [[AtomController alloc] initWithURL:path]; + [self.controllers addObject:controller]; } // Events in the "app:*" namespace get sent to all controllers -- (void)triggerGlobalEvent:(NSString *)name data:(id)data { +- (void)triggerGlobalAtomEvent:(NSString *)name data:(id)data { for (AtomController *controller in self.controllers) { - [controller.jscocoa callJSFunctionNamed:@"triggerEvent" withArguments:name, data, false, nil]; + [controller triggerAtomEventWithName:name data:data]; } } +- (BOOL)shouldRunSpecsOnEvent:(NSEvent *)event { + return [event modifierFlags] & (NSAlternateKeyMask | NSControlKeyMask | NSCommandKeyMask) && [[event charactersIgnoringModifiers] hasPrefix:@"s"]; +} + // Overridden - (void)sendEvent:(NSEvent *)event { if ([event type] != NSKeyDown) { @@ -58,32 +43,22 @@ return; } - BOOL handeled = NO; - AtomController *controller = [[self keyWindow] windowController]; + if ([self shouldRunSpecsOnEvent:event]) { + [self createSpecController]; + return; + } - // The keyWindow could be a Cocoa Dialog or something, ignore those. - if ([controller isKindOfClass:[AtomController class]]) { - // cmd-r should always reload the current controller, so it needs to be here - if ([event modifierFlags] & NSCommandKeyMask && [[event charactersIgnoringModifiers] hasPrefix:@"r"]) { - [self reloadController:controller]; - handeled = YES; - } - else if ([event modifierFlags] & (NSAlternateKeyMask | NSControlKeyMask | NSCommandKeyMask) && [[event charactersIgnoringModifiers] hasPrefix:@"s"]) { - [self createSpecController]; - handeled = YES; - } - else { - JSValueRef value = [controller.jscocoa callJSFunctionNamed:@"handleKeyEvent" withArguments:event, nil]; - handeled = [controller.jscocoa toBool:value]; - } + AtomController *controller = [[self keyWindow] windowController]; + if ([controller isKindOfClass:[AtomController class]]) { // ensure its not a dialog + if ([controller handleInputEvent:event]) return; } - if (!handeled) [super sendEvent:event]; + [super sendEvent:event]; } - (void)terminate:(id)sender { - for (AtomController *controller in self.controllers) { - [controller.jscocoa callJSFunctionNamed:@"shutdown" withArguments:nil]; + for (AtomController *controller in self.controllers) { + [controller close]; } [super terminate:sender]; @@ -98,7 +73,6 @@ } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - [self createController:nil]; } @end diff --git a/Atom/Classes/AtomController.h b/Atom/Classes/AtomController.h index f0347d2ad..7575f322c 100644 --- a/Atom/Classes/AtomController.h +++ b/Atom/Classes/AtomController.h @@ -1,13 +1,15 @@ #import +#import "JSCocoa.h" @class JSCocoa; @class WebView; +struct JSGlobalContextRef; + @interface AtomController : NSWindowController { } @property (assign) WebView *webView; -@property (nonatomic, retain) JSCocoa *jscocoa; @property (nonatomic, retain, readonly) NSString *url; @property (nonatomic, retain, readonly) NSString *bootstrapScript; @@ -15,6 +17,9 @@ - (id)initForSpecs; - (id)initWithURL:(NSString *)url; -- (void)createWebView; +- (BOOL)handleInputEvent:(NSEvent *)event; +- (void)triggerAtomEventWithName:(NSString *)name data:(id)data; +- (void)reload; +- (JSValueRefAndContextRef)jsWindow; @end diff --git a/Atom/Classes/AtomController.m b/Atom/Classes/AtomController.m index 5710a7e48..1339ecc55 100644 --- a/Atom/Classes/AtomController.m +++ b/Atom/Classes/AtomController.m @@ -11,6 +11,19 @@ @end +@interface WebView (Atom) +- (id)inspector; +- (void)showConsole:(id)sender; +- (void)startDebuggingJavaScript:(id)sender; +@end + +@interface AtomController () +- (void)createWebView; + +@property (nonatomic, retain) JSCocoa *jscocoa; + +@end + @implementation AtomController @synthesize @@ -47,10 +60,31 @@ return [self initWithBootstrapScript:@"bootstrap" url:url]; } -- (void)createWebView { - [self.webView removeFromSuperview]; +- (BOOL)shouldReloadOnEvent:(NSEvent *)event { + return [event modifierFlags] & NSCommandKeyMask && [[event charactersIgnoringModifiers] hasPrefix:@"r"]; +} + +- (BOOL)handleInputEvent:(NSEvent *)event { + if ([self shouldReloadOnEvent:event]) { + [self reload]; + return YES; + } + if ([self.jscocoa hasJSFunctionNamed:@"handleKeyEvent"]) { + JSValueRef handled = [self.jscocoa callJSFunctionNamed:@"handleKeyEvent" withArguments:event, nil]; + return [self.jscocoa toBool:handled]; + } + + return NO; +} + +- (void)triggerAtomEventWithName:(NSString *)name data:(id)data { + [self.jscocoa callJSFunctionNamed:@"triggerEvent" withArguments:name, data, false, nil]; +} + +- (void)createWebView { self.webView = [[WebView alloc] initWithFrame:[self.window.contentView frame]]; + [self.webView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; [self.window.contentView addSubview:self.webView]; [self.webView setUIDelegate:self]; @@ -64,6 +98,19 @@ NSURLRequest *request = [NSURLRequest requestWithURL:indexURL]; [[self.webView mainFrame] loadRequest:request]; + + [[self.webView inspector] showConsole:self]; +} + +- (JSValueRefAndContextRef)jsWindow { + JSValueRef window = [self.jscocoa evalJSString:@"window"]; + JSValueRefAndContextRef windowWithContext = {window, self.jscocoa.ctx}; + return windowWithContext; +} + +- (void)reload { + [self.webView removeFromSuperview]; + [self createWebView]; } - (void)windowDidLoad { @@ -79,7 +126,8 @@ } - (void)close { - [(AtomApp *)NSApp removeController:self]; + [(AtomApp *)NSApp removeController:self]; + [self.jscocoa callJSFunctionNamed:@"triggerEvent" withArguments:@"window:close", nil, false, nil]; [super close]; } @@ -87,7 +135,13 @@ return PROJECT_DIR; } -// WebUIDelegate +#pragma mark NSWindowDelegate +- (BOOL)windowShouldClose:(id)sender { + [self close]; + return YES; +} + +#pragma mark WebUIDelegate - (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems { return defaultMenuItems; } diff --git a/spec-suite.html b/spec-suite.html index 7ddb5969a..3523ce735 100644 --- a/spec-suite.html +++ b/spec-suite.html @@ -4,9 +4,6 @@ Jasmine suite - - - -
-
+
diff --git a/spec/atom/app-spec.coffee b/spec/atom/app-spec.coffee index 03e5bc06a..83870a453 100644 --- a/spec/atom/app-spec.coffee +++ b/spec/atom/app-spec.coffee @@ -1,11 +1,24 @@ -App = require 'views/app' +App = require 'app' describe "App", -> - view = null + app = null beforeEach -> - view = App.buildView() + app = new App() + afterEach -> + window.x = app.windows()[0] + setTimeout (-> window.x.close()), 1 + #w.close() for w in app.windows() + describe "open", -> + it "loads a buffer based on the given path and displays it in a new window", -> + 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.editor.buffer.url).toEqual filePath diff --git a/spec/fixtures/sample.txt b/spec/fixtures/sample.txt new file mode 100644 index 000000000..3e715502b --- /dev/null +++ b/spec/fixtures/sample.txt @@ -0,0 +1 @@ +Some text. diff --git a/spec/spec-bootstrap.coffee b/spec/spec-bootstrap.coffee new file mode 100644 index 000000000..ae61f6015 --- /dev/null +++ b/spec/spec-bootstrap.coffee @@ -0,0 +1,24 @@ +nakedLoad 'jasmine' +nakedLoad 'jasmine-html' + +$ = require 'jquery' +coffeekup = require 'coffeekup' + +$('head').append coffeekup.render -> + link rel: "stylesheet", type: "text/css", href: "static/jasmine.css" + +$('body').append coffeekup.render -> + div id: 'jasmine_runner' + div id: 'jasmine_content' + +jasmineEnv = jasmine.getEnv() +trivialReporter = new jasmine.TrivialReporter(document, 'jasmine_runner') + +jasmineEnv.addReporter(trivialReporter) + +jasmineEnv.specFilter = (spec) -> + return trivialReporter.specFilter(spec) + +require 'spec-suite' +jasmineEnv.execute() + diff --git a/spec/spec-suite.coffee b/spec/spec-suite.coffee index 4e5e11efa..08b0ac5fb 100644 --- a/spec/spec-suite.coffee +++ b/spec/spec-suite.coffee @@ -1,2 +1,4 @@ -require 'template-spec' +require 'atom/app-spec' + +require 'stdlib/template-spec' diff --git a/src/atom/app.coffee b/src/atom/app.coffee index 2ba899ebc..b56dde6b3 100644 --- a/src/atom/app.coffee +++ b/src/atom/app.coffee @@ -5,3 +5,6 @@ class App quit: -> OSX.NSApp.terminate null + + windows: -> + controller.jsWindow for controller in OSX.NSApp.controllers diff --git a/src/stdlib/event.coffee b/src/stdlib/event.coffee index 1103d8231..adf761d97 100644 --- a/src/stdlib/event.coffee +++ b/src/stdlib/event.coffee @@ -13,7 +13,7 @@ class Event trigger: (name, data...) -> if name.match /^app:/ - OSX.NSApp.triggerGlobalEvent_data name, data + OSX.NSApp.triggerGlobalAtomEvent_data name, data return _.each @events[name], (callback) => callback data... diff --git a/src/stdlib/require.coffee b/src/stdlib/require.coffee index 153521ef4..2842b0de7 100644 --- a/src/stdlib/require.coffee +++ b/src/stdlib/require.coffee @@ -12,6 +12,11 @@ paths = [ window.__filename = null +nakedLoad = (file) -> + file = resolve file + code = __read file + __jsc__.evalJSString_withScriptPath code, file + require = (file, cb) -> return cb require file if cb? @@ -110,8 +115,8 @@ __read = (path) -> __modules = { loaded : {} } __defines = [] - this.require = require +this.nakedLoad = nakedLoad this.define = define this.require.resourcePath = resourcePath diff --git a/static/jasmine-html.js b/vendor/jasmine-html.js similarity index 100% rename from static/jasmine-html.js rename to vendor/jasmine-html.js diff --git a/static/jasmine.js b/vendor/jasmine.js similarity index 99% rename from static/jasmine.js rename to vendor/jasmine.js index c3d2dc7d2..9ca6f5b9c 100644 --- a/static/jasmine.js +++ b/vendor/jasmine.js @@ -41,7 +41,7 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; jasmine.getGlobal = function() { function getGlobal() { - return this; + return window; } return getGlobal();