Merge branch 'chrome'

This commit is contained in:
Corey Johnson & Nathan Sobo
2012-03-01 16:24:01 -08:00
2647 changed files with 32546 additions and 325808 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
//
// Prefix header for all source files of the 'Atom' target in the 'Atom' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

BIN
Atom/Atom.icns Executable file

Binary file not shown.

View File

@@ -1,17 +0,0 @@
#import <Cocoa/Cocoa.h>
@class AtomController, AtomMenuItem;
@interface AtomApp : NSApplication <NSApplicationDelegate>
@property (nonatomic, retain) NSMutableArray *controllers;
- (void)removeController:(AtomController *)controller;
- (IBAction)runSpecs:(id)sender;
- (void)performActionForMenuItem:(AtomMenuItem *)item;
- (void)resetMainMenu;
- (NSString *)getCachedScript:(NSString *)filePath;
- (void)setCachedScript:(NSString *)filePath contents:(NSString *)contents;
@end

View File

@@ -1,144 +0,0 @@
#import "AtomApp.h"
#import "JSCocoa.h"
#import <WebKit/WebKit.h>
#import "AtomController.h"
#import "AtomMenuItem.h"
#define ATOM_USER_PATH ([[NSString stringWithString:@"~/.atom/"] stringByStandardizingPath])
#define ATOM_STORAGE_PATH ([ATOM_USER_PATH stringByAppendingPathComponent:@".app-storage"])
@interface AtomApp () {
NSMutableDictionary *_coffeeCache;
}
@end
@implementation AtomApp
@synthesize controllers = _controllers;
- (void)open:(NSString *)path {
AtomController *controller = [[AtomController alloc] initWithURL:path];
[self.controllers addObject:controller];
}
- (void)removeController:(AtomController *)controller {
[self.controllers removeObject:controller];
}
// Events in the "app:*" namespace are sent to all controllers
- (void)triggerGlobalAtomEvent:(NSString *)name data:(id)data {
for (AtomController *controller in self.controllers) {
[controller triggerAtomEventWithName:name data:data];
}
}
#pragma mark Overrides
- (void) sendEvent: (NSEvent *)event {
// Default implementation for key down tries key equivalents first
// We want to wait until the web view handles the event, then allow key equivalents to be tried
if (([event type] != NSKeyDown) || !event.window) {
[super sendEvent:event];
return;
}
[event.window sendEvent:event];
}
#pragma mark Actions
- (IBAction)openNewWindow:(id)sender {
[self open:nil];
}
- (IBAction)openPathInNewWindow:(id)sender {
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:YES];
if ([panel runModal] == NSFileHandlingPanelOKButton) {
[self open:[panel.URLs.lastObject path]];
}
}
- (IBAction)runSpecs:(id)sender {
[[AtomController alloc] initForSpecs];
}
- (void)terminate:(id)sender {
for (AtomController *controller in self.controllers) {
[controller close];
}
[super terminate:sender];
}
#pragma mark NSAppDelegate
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification {
self.controllers = [NSMutableArray array];
NSDictionary *defaults = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"WebKitDeveloperExtras", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
_coffeeCache = [[NSMutableDictionary alloc] init];
if ([[[NSProcessInfo processInfo] environment] objectForKey:@"AUTO-TEST"]) {
[self runSpecs:self];
}
}
- (void)performActionForMenuItem:(AtomMenuItem *)item {
AtomController *atomController = self.keyWindow.windowController;
[atomController performActionForMenuItemPath:item.itemPath];
}
- (void)resetMenu:(NSMenu *)menu {
for (AtomMenuItem *item in menu.itemArray) {
if (![item isKindOfClass:[AtomMenuItem class]]) continue;
if (item.submenu) {
[self resetMenu:item.submenu];
if (item.submenu.numberOfItems == 0) {
[menu removeItem:item];
}
}
else if (!item.global) {
[menu removeItem:item];
}
}
}
- (void)resetMainMenu {
[self resetMenu:self.mainMenu];
}
- (NSString *)getCachedScript:(NSString *)filePath {
NSDictionary *cachedObject = [_coffeeCache objectForKey:filePath];
if (!cachedObject) return nil;
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
NSDictionary *attributes = [fm attributesOfItemAtPath:filePath error:&error];
if (error) {
NSLog(@"Error reading cached scripts: %@", [error localizedDescription]);
return nil;
}
NSDate *cachedAt = [cachedObject objectForKey:@"cachedAt"];
NSDate *modifedAt = [attributes objectForKey:NSFileModificationDate];
if (modifedAt && [modifedAt compare:cachedAt] == NSOrderedAscending) {
return [cachedObject objectForKey:@"script"];
}
else {
return nil;
}
}
- (void)setCachedScript:(NSString *)filePath contents:(NSString *)contents {
NSMutableDictionary *cachedObject = [NSMutableDictionary dictionary];
[cachedObject setObject:[NSDate date] forKey:@"cachedAt"];
[cachedObject setObject:contents forKey:@"script"];
[_coffeeCache setObject:cachedObject forKey:filePath];
}
@end

View File

@@ -1,23 +0,0 @@
#import <Cocoa/Cocoa.h>
#import "JSCocoa.h"
@class JSCocoa, WebView, FileSystemHelper;
struct JSGlobalContextRef;
@interface AtomController : NSWindowController <NSWindowDelegate>
@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;
- (void)triggerAtomEventWithName:(NSString *)name data:(id)data;
- (void)reload;
- (JSValueRefAndContextRef)jsWindow;
- (void)performActionForMenuItemPath:(NSString *)menuItemPath;
@end

View File

@@ -1,167 +0,0 @@
#import "AtomController.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)
- (id)inspector;
- (void)showConsole:(id)sender;
- (void)startDebuggingJavaScript:(id)sender;
@end
@implementation AtomController
@synthesize webView = _webView;
@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];
}
- (id)initWithBootstrapScript:(NSString *)bootstrapScript url:(NSString *)url {
self = [super initWithWindowNibName:@"AtomWindow"];
self.bootstrapScript = bootstrapScript;
self.url = url;
[self.window makeKeyWindow];
return self;
}
- (id)initForSpecs {
return [self initWithBootstrapScript:@"spec-bootstrap" url:nil];
}
- (id)initWithURL:(NSString *)url {
return [self initWithBootstrapScript:@"bootstrap" url:url];
}
- (void)windowDidLoad {
[super windowDidLoad];
[self.window setDelegate:self];
[self.window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
[self setShouldCascadeWindows:YES];
[self setWindowFrameAutosaveName:@"atomController"];
[self createWebView];
}
- (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];
[self.webView setFrameLoadDelegate:self];
NSURL *resourceDirURL = [[NSBundle mainBundle] resourceURL];
NSURL *indexURL = [resourceDirURL URLByAppendingPathComponent:@"index.html"];
NSURLRequest *request = [NSURLRequest requestWithURL:indexURL];
[[self.webView mainFrame] loadRequest:request];
[self blockUntilWebViewLoads];
}
- (void)blockUntilWebViewLoads {
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
while (self.webView.isLoading) {
[runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
- (void)reload {
[self.webView reload:self];
}
- (void)close {
[(AtomApp *)NSApp removeController:self];
[super close];
}
- (NSString *)projectPath {
return PROJECT_DIR;
}
- (void)performActionForMenuItemPath:(NSString *)menuItemPath {
NSString *jsCode = [NSString stringWithFormat:@"window.performActionForMenuItemPath('%@')", menuItemPath];
[self.jscocoa evalJSString:jsCode];
}
- (JSValueRefAndContextRef)jsWindow {
JSValueRef window = [self.jscocoa evalJSString:@"window"];
JSValueRefAndContextRef windowWithContext = {window, self.jscocoa.ctx};
return windowWithContext;
}
- (NSString *)absolute:(NSString *)path {
path = [path stringByStandardizingPath];
if ([path characterAtIndex:0] == '/') {
return path;
}
NSString *resolvedPath = [[NSFileManager defaultManager] currentDirectoryPath];
resolvedPath = [[resolvedPath stringByAppendingPathComponent:path] stringByStandardizingPath];
return resolvedPath;
}
#pragma mark NSWindowDelegate
- (BOOL)windowShouldClose:(id)sender {
[self close];
return YES;
}
- (void)keyDown:(NSEvent *)event {
if ([event modifierFlags] & NSCommandKeyMask && [[event charactersIgnoringModifiers] hasPrefix:@"r"]) {
[self reload];
}
}
#pragma mark WebUIDelegate
- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems {
return defaultMenuItems;
}
- (void)webViewClose:(WebView *)sender { // Triggered when closed from javascript
[self close];
}
#pragma mark WebFrameLoadDelegate
- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame {
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

@@ -1,10 +0,0 @@
#import <AppKit/AppKit.h>
@interface AtomMenuItem : NSMenuItem
@property BOOL global;
@property (nonatomic, retain) NSString *itemPath;
- initWithTitle:(NSString *)title itemPath:(NSString *)itemPath;
@end

View File

@@ -1,14 +0,0 @@
#import "AtomMenuItem.h"
@implementation AtomMenuItem
@synthesize global = global_, itemPath = path_;
- initWithTitle:(NSString *)title itemPath:(NSString *)itemPath {
self = [super initWithTitle:title action:@selector(performActionForMenuItem:) keyEquivalent:@""];
self.itemPath = itemPath;
return self;
}
@end

View File

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

View File

@@ -1,81 +0,0 @@
#import "FileSystemHelper.h"
@interface FileSystemHelper ()
- (NSArray *)listFilesAtPath:(NSString *)path recursive:(BOOL)recursive;
- (JSValueRef)convertToJSArrayOfStrings:(NSArray *)nsArray;
@end
@implementation FileSystemHelper
- (id)initWithJSContextRef:(JSContextRef)ctx {
self = [super init];
_ctx = ctx;
return self;
}
- (void)listFilesAtPath:(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 listFilesAtPath: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);
});
});
}
- (BOOL)isFile:(NSString *)path {
BOOL isDir, exists;
exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir];
return exists && !isDir;
}
- (NSArray *)listFilesAtPath:(NSString *)path recursive:(BOOL)recursive {
NSFileManager *fm = [NSFileManager defaultManager];
NSMutableArray *paths = [NSMutableArray array];
if (recursive) {
for (NSString *subpath in [fm enumeratorAtPath:path]) {
[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]];
}
}
NSMutableArray *filePaths = [NSMutableArray array];
for (NSString *path in paths) {
if ([self isFile:path]) [filePaths addObject:path];
}
return filePaths;
}
- (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

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1070</int>
<int key="IBDocument.SystemTarget">1060</int>
<string key="IBDocument.SystemVersion">11C74</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
<string key="IBDocument.AppKitVersion">1138.23</string>
@@ -35,26 +35,24 @@
<object class="NSCustomObject" id="1004">
<string key="NSClassName">NSApplication</string>
</object>
<object class="NSWindowTemplate" id="773759719">
<object class="NSWindowTemplate" id="1005">
<int key="NSWindowStyleMask">15</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{288, 20}, {725, 723}}</string>
<int key="NSWTFlags">1954021376</int>
<string key="NSWindowTitle">untitled</string>
<string key="NSWindowRect">{{196, 240}, {637, 578}}</string>
<int key="NSWTFlags">544735232</int>
<string key="NSWindowTitle">Window</string>
<string key="NSWindowClass">NSWindow</string>
<nil key="NSViewClass"/>
<nil key="NSUserInterfaceItemIdentifier"/>
<object class="NSView" key="NSWindowView" id="610964987">
<object class="NSView" key="NSWindowView" id="1006">
<reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<string key="NSFrameSize">{725, 723}</string>
<string key="NSFrameSize">{637, 578}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSScreenRect">{{0, 0}, {2560, 1418}}</string>
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
<string key="NSFrameAutosaveName">Atomicity</string>
<bool key="NSWindowIsRestorable">YES</bool>
</object>
</object>
@@ -65,9 +63,17 @@
<object class="IBOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="773759719"/>
<reference key="destination" ref="1005"/>
</object>
<int key="connectionID">7</int>
<int key="connectionID">3</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">webView</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="1006"/>
</object>
<int key="connectionID">4</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
@@ -75,7 +81,7 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="0">
<object class="NSArray" key="object" id="1002">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
@@ -84,37 +90,34 @@
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1001"/>
<reference key="parent" ref="0"/>
<reference key="parent" ref="1002"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1003"/>
<reference key="parent" ref="0"/>
<reference key="parent" ref="1002"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1004"/>
<reference key="parent" ref="0"/>
<reference key="parent" ref="1002"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="773759719"/>
<int key="objectID">1</int>
<reference key="object" ref="1005"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="610964987"/>
<reference ref="1006"/>
</object>
<reference key="parent" ref="0"/>
<reference key="parent" ref="1002"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="610964987"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="parent" ref="773759719"/>
<int key="objectID">2</int>
<reference key="object" ref="1006"/>
<reference key="parent" ref="1005"/>
</object>
</object>
</object>
@@ -125,10 +128,10 @@
<string>-1.IBPluginDependency</string>
<string>-2.IBPluginDependency</string>
<string>-3.IBPluginDependency</string>
<string>3.IBPluginDependency</string>
<string>3.IBWindowTemplateEditedContentRect</string>
<string>3.NSWindowTemplate.visibleAtLaunch</string>
<string>4.IBPluginDependency</string>
<string>1.IBPluginDependency</string>
<string>1.IBWindowTemplateEditedContentRect</string>
<string>1.NSWindowTemplate.visibleAtLaunch</string>
<string>2.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -136,24 +139,24 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{324, 121}, {725, 723}}</string>
<string>{{357, 418}, {480, 270}}</string>
<integer value="1"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
<reference key="dict.sortedKeys" ref="1002"/>
<reference key="dict.values" ref="1002"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="0"/>
<reference key="dict.values" ref="0"/>
<reference key="dict.sortedKeys" ref="1002"/>
<reference key="dict.values" ref="1002"/>
</object>
<nil key="sourceID"/>
<int key="maxID">7</int>
<int key="maxID">4</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -161,6 +164,17 @@
<object class="IBPartialClassDescription">
<string key="className">AtomController</string>
<string key="superclassName">NSWindowController</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">webView</string>
<string key="NS.object.0">NSView</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">webView</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">webView</string>
<string key="candidateClassName">NSView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/AtomController.h</string>
@@ -170,6 +184,10 @@
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<real value="1060" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>

Binary file not shown.

16
Atom/Atom-Info.plist → Atom/Info.plist Normal file → Executable file
View File

@@ -3,32 +3,26 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>Icon.icns</string>
<string>Atom</string>
<key>CFBundleIdentifier</key>
<string>GitHub.${PRODUCT_NAME:rfc1034identifier}</string>
<string>org.cef.cefclient</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2011 __MyCompanyName__. All rights reserved.</string>
<string>1.0</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>AtomApp</string>
<string>Atom</string>
</dict>
</plist>

View File

@@ -1,43 +0,0 @@
//
// BridgeSupportController.h
// JSCocoa
//
// Created by Patrick Geiller on 08/07/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#if !TARGET_IPHONE_SIMULATOR && !TARGET_OS_IPHONE
#import <Cocoa/Cocoa.h>
#endif
@interface BridgeSupportController : NSObject {
NSMutableArray* paths;
NSMutableArray* xmlDocuments;
NSMutableDictionary* hash;
NSMutableDictionary* variadicSelectors;
NSMutableDictionary* variadicFunctions;
}
+ (id)sharedController;
- (BOOL)loadBridgeSupport:(NSString*)path;
- (BOOL)isBridgeSupportLoaded:(NSString*)path;
- (NSUInteger)bridgeSupportIndexForString:(NSString*)string;
- (NSMutableDictionary*)variadicSelectors;
- (NSMutableDictionary*)variadicFunctions;
/*
- (NSString*)query:(NSString*)name withType:(NSString*)type;
- (NSString*)query:(NSString*)name withType:(NSString*)type inBridgeSupportFile:(NSString*)file;
*/
- (NSString*)queryName:(NSString*)name;
- (NSString*)queryName:(NSString*)name type:(NSString*)type;
- (NSArray*)keys;
@end

View File

@@ -1,254 +0,0 @@
//
// BridgeSupportController.m
// JSCocoa
//
// Created by Patrick Geiller on 08/07/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "BridgeSupportController.h"
@implementation BridgeSupportController
+ (id)sharedController
{
static id singleton;
@synchronized(self)
{
if (!singleton)
singleton = [[BridgeSupportController alloc] init];
return singleton;
}
return singleton;
}
- (id)init
{
self = [super init];
paths = [[NSMutableArray alloc] init];
xmlDocuments = [[NSMutableArray alloc] init];
hash = [[NSMutableDictionary alloc] init];
variadicSelectors = [[NSMutableDictionary alloc] init];
variadicFunctions = [[NSMutableDictionary alloc] init];
return self;
}
- (void)dealloc
{
[variadicFunctions release];
[variadicSelectors release];
[hash release];
[paths release];
[xmlDocuments release];
[super dealloc];
}
//
// Load a bridgeSupport file into a hash as { name : xmlTagString }
//
- (BOOL)loadBridgeSupport:(NSString*)path
{
NSError* error = nil;
/*
Adhoc parser
NSXMLDocument is too slow
loading xml document as string then querying on-demand is too slow
can't get CFXMLParserRef to work
don't wan't to delve into expat
-> ad hoc : load file, build a hash of { name : xmlTagString }
*/
NSString* xmlDocument = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (error) return NSLog(@"loadBridgeSupport : %@", error), NO;
char* c = (char*)[xmlDocument UTF8String];
#ifdef __OBJC_GC__
char* originalC = c;
[[NSGarbageCollector defaultCollector] disableCollectorForPointer:originalC];
#endif
// double t0 = CFAbsoluteTimeGetCurrent();
// Start parsing
for (; *c; c++)
{
if (*c == '<')
{
char startTagChar = c[1];
if (startTagChar == 0) return NO;
// 'co' constant
// 'cl' class
// 'e' enum
// 'fu' function
// 'st' struct
if ((c[1] == 'c' && (c[2] == 'o' || c[2] == 'l')) || c[1] == 'e' || (c[1] == 'f' && c[2] == 'u') || (c[1] == 's' && c[2] == 't'))
{
// Extract name
char* tagStart = c;
for (; *c && *c != '\''; c++);
c++;
char* c0 = c;
for (; *c && *c != '\''; c++);
id name = [[NSString alloc] initWithBytes:c0 length:c-c0 encoding:NSUTF8StringEncoding];
// Move to tag end
BOOL foundEndTag = NO;
BOOL foundOpenTag = NO;
c++;
for (; *c && !foundEndTag; c++)
{
if (*c == '<') foundOpenTag = YES;
else
if (*c == '/')
{
if (!foundOpenTag)
{
if(c[1] == '>') foundEndTag = YES, c++;
}
else
{
if (startTagChar == c[1])
{
foundEndTag = YES;
// Skip to end of tag
for (; *c && *c != '>'; c++);
}
}
}
else
// Variadic parsing
if (c[0] == 'v' && c[1] == 'a' && c[2] == 'r')
{
if (strncmp(c, "variadic", 8) == 0)
{
// Skip back to tag start
c0 = c;
for (; *c0 != '<'; c0--);
// Tag name starts with 'm' : variadic method
// <method variadic='true' selector='alertWithMessageText:defaultButton:alternateButton:otherButton:informativeTextWithFormat:' class_method='true'>
if (c0[1] == 'm')
{
c = c0;
id variadicMethodName = nil;
// Extract selector name
for (; *c != '>'; c++)
{
if (c[0] == ' ' && c[1] == 's' && c[2] == 'e' && c[3] == 'l')
{
for (; *c && *c != '\''; c++);
c++;
c0 = c;
for (; *c && *c != '\''; c++);
variadicMethodName = [[[NSString alloc] initWithBytes:c0 length:c-c0 encoding:NSUTF8StringEncoding] autorelease];
}
}
[variadicSelectors setValue:@"true" forKey:variadicMethodName];
// NSLog(@"SELECTOR %@", name);
}
else
// Variadic function
// <function name='NSBeginAlertSheet' variadic='true'>
{
[variadicFunctions setValue:@"true" forKey:name];
// NSLog(@"function %@", name);
}
}
}
}
c0 = tagStart;
id value = [[NSString alloc] initWithBytes:c0 length:c-c0 encoding:NSUTF8StringEncoding];
[hash setValue:value forKey:name];
[value release];
[name release];
}
}
}
// double t1 = CFAbsoluteTimeGetCurrent();
// NSLog(@"BridgeSupport %@ parsed in %f", [[path lastPathComponent] stringByDeletingPathExtension], t1-t0);
#ifdef __OBJC_GC__
[[NSGarbageCollector defaultCollector] enableCollectorForPointer:originalC];
#endif
[paths addObject:path];
[xmlDocuments addObject:xmlDocument];
return YES;
}
- (BOOL)isBridgeSupportLoaded:(NSString*)path
{
NSUInteger idx = [self bridgeSupportIndexForString:path];
return idx == NSNotFound ? NO : YES;
}
//
// bridgeSupportIndexForString
// given 'AppKit', return index of '/System/Library/Frameworks/AppKit.framework/Versions/C/Resources/BridgeSupport/AppKitFull.bridgesupport'
//
- (NSUInteger)bridgeSupportIndexForString:(NSString*)string
{
NSUInteger i, l = [paths count];
for (i=0; i<l; i++)
{
NSString* path = [paths objectAtIndex:i];
NSRange range = [path rangeOfString:string];
if (range.location != NSNotFound) return range.location;
}
return NSNotFound;
}
- (NSMutableDictionary*)variadicSelectors
{
return variadicSelectors;
}
- (NSMutableDictionary*)variadicFunctions
{
return variadicFunctions;
}
- (NSArray*)keys
{
[hash removeObjectForKey:@"NSProxy"];
[hash removeObjectForKey:@"NSProtocolChecker"];
[hash removeObjectForKey:@"NSDistantObject"];
return [hash allKeys];
}
- (NSString*)queryName:(NSString*)name
{
return [hash valueForKey:name];
}
- (NSString*)queryName:(NSString*)name type:(NSString*)type
{
id v = [self queryName:name];
if (!v) return nil;
char* c = (char*)[v UTF8String];
// Skip tag start
c++;
char* c0 = c;
for (; *c && *c != ' '; c++);
id extractedType = [[NSString alloc] initWithBytes:c0 length:c-c0 encoding:NSUTF8StringEncoding];
[extractedType autorelease];
// NSLog(@"extractedType=%@", extractedType);
if (![extractedType isEqualToString:type]) return nil;
return v;
}
@end

View File

@@ -1,11 +0,0 @@
//
// JSCocoa.h
// JSCocoa
//
// Created by Patrick Geiller on 16/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#define JSCOCOA
#import "JSCocoaController.h"

View File

@@ -1,359 +0,0 @@
//
// JSCocoa.h
// JSCocoa
//
// Created by Patrick Geiller on 09/07/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#if !TARGET_IPHONE_SIMULATOR && !TARGET_OS_IPHONE
#import <Cocoa/Cocoa.h>
#import <JavaScriptCore/JavaScriptCore.h>
#define MACOSX
#import <ffi/ffi.h>
#endif
#import "BridgeSupportController.h"
#import "JSCocoaPrivateObject.h"
#import "JSCocoaFFIArgument.h"
#import "JSCocoaFFIClosure.h"
// JS value container, used by methods wanting a straight JSValue and not a converted JS->ObjC value.
struct JSValueRefAndContextRef
{
JSValueRef value;
JSContextRef ctx;
};
typedef struct JSValueRefAndContextRef JSValueRefAndContextRef;
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
#import "iPhone/libffi/ffi.h"
#import "iPhone/BurksPool.h"
#endif
//
// JSCocoaController
//
@interface JSCocoaController : NSObject {
JSGlobalContextRef ctx;
BOOL ownsContext;
id _delegate;
//
// Split call
// Allows calling multi param ObjC messages with a jQuery-like syntax.
//
// obj.do({ this : 'hello', andThat : 'world' })
// instead of
// obj.dothis_andThat_('hello', 'world')
//
BOOL useSplitCall;
// JSLint : used for ObjJ syntax, class syntax, return if
BOOL useJSLint;
// Auto call zero arg methods : allow NSWorkspace.sharedWorkspace instead of NSWorkspace.sharedWorkspace()
BOOL useAutoCall;
// Allow setting javascript values on boxed objects (which are collected after nulling all references to them)
BOOL canSetOnBoxedObjects;
// Allow calling obj.method(...) instead of obj.method_(...)
BOOL callSelectorsMissingTrailingSemicolon;
// Log all exceptions to NSLog, even if they're caught later by downstream Javascript (in f(g()), log even if f catches after g threw)
BOOL logAllExceptions;
//
// Safe dealloc (For ObjC classes written in Javascript)
// - (void)dealloc cannot be overloaded as it is called during JS GC, which forbids new JS code execution.
// As the js dealloc method cannot be called, safe dealloc allows it to be executed during the next run loop cycle
// NOTE : upon destroying a JSCocoaController, safe dealloc is disabled
//
BOOL useSafeDealloc;
NSMutableDictionary* boxedObjects;
}
@property (assign) id delegate;
@property BOOL useSafeDealloc, useSplitCall, useJSLint, useAutoCall, callSelectorsMissingTrailingSemicolon, canSetOnBoxedObjects, logAllExceptions;
- (id)init;
- (id)initWithGlobalContext:(JSGlobalContextRef)ctx;
+ (id)sharedController;
+ (id)controllerFromContext:(JSContextRef)ctx;
+ (BOOL)hasSharedController;
- (JSGlobalContextRef)ctx;
+ (void)hazardReport;
+ (NSString*)runningArchitecture;
+ (void)updateCustomCallPaths;
- (void)accomodateWebKitInspector;
//
// Evaluation
//
- (id)eval:(NSString*)script;
- (id)callFunction:(NSString*)name;
- (id)callFunction:(NSString*)name withArguments:(NSArray*)arguments;
- (BOOL)hasFunction:(NSString*)name;
- (BOOL)isSyntaxValid:(NSString*)script;
- (BOOL)evalJSFile:(NSString*)path;
- (BOOL)evalJSFile:(NSString*)path toJSValueRef:(JSValueRef*)returnValue;
- (JSValueRef)evalJSString:(NSString*)script;
- (JSValueRef)evalJSString:(NSString*)script withScriptPath:(NSString*)path;
- (JSValueRef)callJSFunction:(JSValueRef)function withArguments:(NSArray*)arguments;
- (JSValueRef)callJSFunctionNamed:(NSString*)functionName withArguments:arguments, ... NS_REQUIRES_NIL_TERMINATION;
- (JSValueRef)callJSFunctionNamed:(NSString*)functionName withArgumentsArray:(NSArray*)arguments;
- (JSObjectRef)JSFunctionNamed:(NSString*)functionName;
- (BOOL)hasJSFunctionNamed:(NSString*)functionName;
- (NSString*)expandJSMacros:(NSString*)script path:(NSString*)path;
- (NSString*)expandJSMacros:(NSString*)script path:(NSString*)path errors:(NSMutableArray*)array;
- (BOOL)isSyntaxValid:(NSString*)script error:(NSString**)error;
- (BOOL)setObject:(id)object withName:(NSString*)name;
- (BOOL)setObject:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes;
- (BOOL)setObjectNoRetain:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes;
- (id)objectWithName:(NSString*)name;
- (BOOL)removeObjectWithName:(NSString*)name;
// Get ObjC and raw values from Javascript
- (id)unboxJSValueRef:(JSValueRef)jsValue;
- (BOOL)toBool:(JSValueRef)value;
- (double)toDouble:(JSValueRef)value;
- (int)toInt:(JSValueRef)value;
- (NSString*)toString:(JSValueRef)value;
// Wrapper for unboxJSValueRef
- (id)toObject:(JSValueRef)value;
//
// Framework
//
- (BOOL)loadFrameworkWithName:(NSString*)name;
- (BOOL)loadFrameworkWithName:(NSString*)frameworkName inPath:(NSString*)path;
//
// Garbage collection
//
+ (void)garbageCollect;
- (void)garbageCollect;
- (void)unlinkAllReferences;
+ (void)upJSCocoaPrivateObjectCount;
+ (void)downJSCocoaPrivateObjectCount;
+ (int)JSCocoaPrivateObjectCount;
+ (void)upJSValueProtectCount;
+ (void)downJSValueProtectCount;
+ (int)JSValueProtectCount;
+ (void)logInstanceStats;
- (id)instanceStats;
- (void)logBoxedObjects;
//
// Class inspection (shortcuts to JSCocoaLib)
//
+ (id)rootclasses;
+ (id)classes;
+ (id)protocols;
+ (id)imageNames;
+ (id)methods;
+ (id)runtimeReport;
+ (id)explainMethodEncoding:(id)encoding;
//
// Class handling
//
+ (BOOL)overloadInstanceMethod:(NSString*)methodName class:(Class)class jsFunction:(JSValueRefAndContextRef)valueAndContext;
+ (BOOL)overloadClassMethod:(NSString*)methodName class:(Class)class jsFunction:(JSValueRefAndContextRef)valueAndContext;
+ (BOOL)addClassMethod:(NSString*)methodName class:(Class)class jsFunction:(JSValueRefAndContextRef)valueAndContext encoding:(char*)encoding;
+ (BOOL)addInstanceMethod:(NSString*)methodName class:(Class)class jsFunction:(JSValueRefAndContextRef)valueAndContext encoding:(char*)encoding;
// Tests
- (int)runTests:(NSString*)path;
- (int)runTests:(NSString*)path withSelector:(SEL)sel;
//
// Autorelease pool
//
+ (void)allocAutoreleasePool;
+ (void)deallocAutoreleasePool;
//
// Boxing : each object gets only one box, stored in boxedObjects
//
//+ (JSObjectRef)boxedJSObject:(id)o inContext:(JSContextRef)ctx;
- (JSObjectRef)boxObject:(id)o;
- (BOOL)isObjectBoxed:(id)o;
- (void)deleteBoxOfObject:(id)o;
//+ (void)downBoxedJSObjectCount:(id)o;
//
// Various internals
//
//+ (JSObjectRef)jsCocoaPrivateObjectInContext:(JSContextRef)ctx;
- (JSObjectRef)newPrivateObject;
- (JSObjectRef)newPrivateFunction;
+ (NSMutableArray*)parseObjCMethodEncoding:(const char*)typeEncoding;
+ (NSMutableArray*)parseCFunctionEncoding:(NSString*)xml functionName:(NSString**)functionNamePlaceHolder;
//+ (void)ensureJSValueIsObjectAfterInstanceAutocall:(JSValueRef)value inContext:(JSContextRef)ctx;
- (NSString*)formatJSException:(JSValueRef)exception;
- (id)selectorForJSFunction:(JSObjectRef)function;
- (const char*)typeEncodingOfMethod:(NSString*)methodName class:(NSString*)className;
+ (const char*)typeEncodingOfMethod:(NSString*)methodName class:(NSString*)className;
@end
//
// JSCocoa delegate methods
//
//
// Error reporting
//
@interface NSObject (JSCocoaControllerDelegateMethods)
- (void) JSCocoa:(JSCocoaController*)controller hadError:(NSString*)error onLineNumber:(NSInteger)lineNumber atSourceURL:(id)url;
- (void) safeDealloc;
//
// Getting
//
// Check if getting property is allowed
- (BOOL) JSCocoa:(JSCocoaController*)controller canGetProperty:(NSString*)propertyName ofObject:(id)object inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
// Custom handler for getting properties
// Return a custom JSValueRef to bypass JSCocoa
// Return NULL to let JSCocoa handle getProperty
// Return JSValueMakeNull() to return a Javascript null
- (JSValueRef) JSCocoa:(JSCocoaController*)controller getProperty:(NSString*)propertyName ofObject:(id)object inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
//
// Setting
//
// Check if setting property is allowed
- (BOOL) JSCocoa:(JSCocoaController*)controller canSetProperty:(NSString*)propertyName ofObject:(id)object toValue:(JSValueRef)value inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
// Custom handler for setting properties
// Return YES to indicate you handled setting
// Return NO to let JSCocoa handle setProperty
- (BOOL) JSCocoa:(JSCocoaController*)controller setProperty:(NSString*)propertyName ofObject:(id)object toValue:(JSValueRef)value inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
//
// Calling
//
// Check if calling a C function is allowed
- (BOOL) JSCocoa:(JSCocoaController*)controller canCallFunction:(NSString*)functionName argumentCount:(size_t)argumentCount arguments:(JSValueRef*)arguments inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
// Check if calling an ObjC method is allowed
- (BOOL) JSCocoa:(JSCocoaController*)controller canCallMethod:(NSString*)methodName ofObject:(id)object argumentCount:(size_t)argumentCount arguments:(JSValueRef*)arguments inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
// Custom handler for calling
// Return YES to indicate you handled calling
// Return NO to let JSCocoa handle calling
- (JSValueRef) JSCocoa:(JSCocoaController*)controller callMethod:(NSString*)methodName ofObject:(id)callee privateObject:(JSCocoaPrivateObject*)thisPrivateObject argumentCount:(size_t)argumentCount arguments:(JSValueRef*)arguments inContext:(JSContextRef)localCtx exception:(JSValueRef*)exception;
//
// Getting global properties (classes, structures, C function names, enums via OSXObject_getProperty)
//
// Check if getting property is allowed
- (BOOL) JSCocoa:(JSCocoaController*)controller canGetGlobalProperty:(NSString*)propertyName inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
// Custom handler for getting properties
// Return a custom JSValueRef to bypass JSCocoa
// Return NULL to let JSCocoa handle getProperty
// Return JSValueMakeNull() to return a Javascript null
- (JSValueRef) JSCocoa:(JSCocoaController*)controller getGlobalProperty:(NSString*)propertyName inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
//
// Returning values to Javascript
//
// Called before returning any value to Javascript : return a new value or the original one
//- (JSValueRef) JSCocoa:(JSCocoaController*)controller willReturnValue:(JSValueRef)value inContext:(JSContextRef)ctx exception:(JSValueRef*)exception;
//
// Evaling
//
// Check if file can be loaded
- (BOOL)JSCocoa:(JSCocoaController*)controller canLoadJSFile:(NSString*)path;
// Check if script can be evaluated
- (BOOL)JSCocoa:(JSCocoaController*)controller canEvaluateScript:(NSString*)script;
// Called before evalJSString, used to modify script about to be evaluated
// Return a custom NSString (eg a macro expanded version of the source)
// Return NULL to let JSCocoa handle evaluation
- (NSString*)JSCocoa:(JSCocoaController*)controller willEvaluateScript:(NSString*)script;
@end
//
// JSCocoa shorthand
//
@interface JSCocoa : JSCocoaController
@end
//
// Boxed object cache : holds one JSObjectRef for each reference to a pointer to an ObjC object
//
@interface BoxedJSObject : NSObject {
JSObjectRef jsObject;
}
- (void)setJSObject:(JSObjectRef)o;
- (JSObjectRef)jsObject;
@end
//
// Helpers
//
id NSStringFromJSValue(JSContextRef ctx, JSValueRef value);
//void* malloc_autorelease(size_t size);
// Convert values between contexts (eg user context and webkit page context)
JSValueRef valueToExternalContext(JSContextRef ctx, JSValueRef value, JSContextRef externalCtx);
// valueOf() is called by Javascript on objects, eg someObject + ' someString'
JSValueRef valueOfCallback(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception);
//
// From PyObjC : when to call objc_msgSend_stret, for structure return
// Depending on structure size & architecture, structures are returned as function first argument (done transparently by ffi) or via registers
//
#if defined(__ppc__)
# define SMALL_STRUCT_LIMIT 4
#elif defined(__ppc64__)
# define SMALL_STRUCT_LIMIT 8
#elif defined(__i386__)
# define SMALL_STRUCT_LIMIT 8
#elif defined(__x86_64__)
# define SMALL_STRUCT_LIMIT 16
#elif TARGET_OS_IPHONE
// TOCHECK
# define SMALL_STRUCT_LIMIT 4
#else
# error "Unsupported MACOSX platform"
#endif
// Stored in boxedobjects to access a list of methods, properties, ...
#define RuntimeInformationPropertyName "info"
/*
Some more doc
__jsHash
__jsCocoaController
Instance variables set on ObjC classes written in Javascript.
These variables enable classes to store Javascript values in them.
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,97 +0,0 @@
//
// JSCocoaFFIArgument.h
// JSCocoa
//
// Created by Patrick Geiller on 14/07/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#if !TARGET_IPHONE_SIMULATOR && !TARGET_OS_IPHONE
#import <Cocoa/Cocoa.h>
#import <JavaScriptCore/JavaScriptCore.h>
#define MACOSX
#include <ffi/ffi.h>
#endif
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
#import "iPhone/libffi/ffi.h"
#endif
@interface JSCocoaFFIArgument : NSObject {
char typeEncoding;
NSString* structureTypeEncoding;
NSString* pointerTypeEncoding;
void* ptr;
ffi_type structureType;
id customData;
BOOL isReturnValue;
BOOL ownsStorage;
BOOL isOutArgument;
}
- (NSString*)typeDescription;
- (BOOL)setTypeEncoding:(char)encoding;
- (BOOL)setTypeEncoding:(char)encoding withCustomStorage:(void*)storagePtr;
- (void)setStructureTypeEncoding:(NSString*)encoding;
- (void)setStructureTypeEncoding:(NSString*)encoding withCustomStorage:(void*)storagePtr;
- (void)setPointerTypeEncoding:(NSString*)encoding;
+ (int)sizeOfTypeEncoding:(char)encoding;
+ (int)alignmentOfTypeEncoding:(char)encoding;
+ (ffi_type*)ffi_typeForTypeEncoding:(char)encoding;
+ (int)sizeOfStructure:(NSString*)encoding;
+ (NSArray*)typeEncodingsFromStructureTypeEncoding:(NSString*)structureTypeEncoding;
+ (NSArray*)typeEncodingsFromStructureTypeEncoding:(NSString*)structureTypeEncoding parsedCount:(NSInteger*)count;
+ (NSString*)structureNameFromStructureTypeEncoding:(NSString*)structureTypeEncoding;
+ (NSString*)structureFullTypeEncodingFromStructureTypeEncoding:(NSString*)structureTypeEncoding;
+ (NSString*)structureFullTypeEncodingFromStructureName:(NSString*)structureName;
+ (NSString*)structureTypeEncodingDescription:(NSString*)structureTypeEncoding;
+ (BOOL)fromJSValueRef:(JSValueRef)value inContext:(JSContextRef)ctx typeEncoding:(char)typeEncoding fullTypeEncoding:(NSString*)fullTypeEncoding fromStorage:(void*)ptr;
+ (BOOL)toJSValueRef:(JSValueRef*)value inContext:(JSContextRef)ctx typeEncoding:(char)typeEncoding fullTypeEncoding:(NSString*)fullTypeEncoding fromStorage:(void*)ptr;
+ (NSInteger)structureToJSValueRef:(JSValueRef*)value inContext:(JSContextRef)ctx fromCString:(char*)c fromStorage:(void**)storage;
+ (NSInteger)structureToJSValueRef:(JSValueRef*)value inContext:(JSContextRef)ctx fromCString:(char*)c fromStorage:(void**)ptr initialValues:(JSValueRef*)initialValues initialValueCount:(NSInteger)initialValueCount convertedValueCount:(NSInteger*)convertedValueCount;
+ (NSInteger)structureFromJSObjectRef:(JSObjectRef)value inContext:(JSContextRef)ctx inParentJSValueRef:(JSValueRef)parentValue fromCString:(char*)c fromStorage:(void**)ptr;
+ (void)alignPtr:(void**)ptr accordingToEncoding:(char)encoding;
+ (void)advancePtr:(void**)ptr accordingToEncoding:(char)encoding;
- (void*)allocateStorage;
- (void*)allocatePointerStorage;
- (void**)storage;
- (void**)rawStoragePointer;
- (char)typeEncoding;
- (NSString*)structureTypeEncoding;
- (id)pointerTypeEncoding;
- (void)setIsReturnValue:(BOOL)v;
- (BOOL)isReturnValue;
- (void)setIsOutArgument:(BOOL)v;
- (BOOL)isOutArgument;
- (BOOL)fromJSValueRef:(JSValueRef)value inContext:(JSContextRef)ctx;
- (BOOL)toJSValueRef:(JSValueRef*)value inContext:(JSContextRef)ctx;
+ (BOOL)boxObject:(id)o toJSValueRef:(JSValueRef*)value inContext:(JSContextRef)ctx;
+ (BOOL)unboxJSValueRef:(JSValueRef)value toObject:(id*)o inContext:(JSContextRef)ctx;
+ (BOOL)unboxJSArray:(JSObjectRef)value toObject:(id*)o inContext:(JSContextRef)ctx;
+ (BOOL)unboxJSHash:(JSObjectRef)value toObject:(id*)o inContext:(JSContextRef)ctx;
- (ffi_type*)ffi_type;
@end

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +0,0 @@
//
// JSCocoaFFIClosure.h
// JSCocoa
//
// Created by Patrick Geiller on 29/07/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#if !TARGET_IPHONE_SIMULATOR && !TARGET_OS_IPHONE
#import <Cocoa/Cocoa.h>
#import <JavaScriptCore/JavaScriptCore.h>
#define MACOSX
#import <ffi/ffi.h>
#endif
#import "JSCocoaFFIArgument.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
#import "iPhone/libffi/ffi.h"
#endif
@interface JSCocoaFFIClosure : NSObject {
JSValueRef jsFunction;
// ##UNSURE This might cause a crash if we're registered in a non global context that will have been destroyed when we JSValueUnprotect the function
JSContextRef ctx;
ffi_cif cif;
#if !TARGET_OS_IPHONE
ffi_closure* closure;
#endif
ffi_type** argTypes;
NSMutableArray* encodings;
JSObjectRef jsThisObject;
BOOL isObjC;
}
- (IMP)setJSFunction:(JSValueRef)fn inContext:(JSContextRef)ctx argumentEncodings:(NSMutableArray*)argumentEncodings objC:(BOOL)objC;
- (void*)functionPointer;
- (void)calledByClosureWithArgs:(void**)args returnValue:(void*)returnValue;
@end

View File

@@ -1,215 +0,0 @@
//
// JSCocoaFFIClosure.m
// JSCocoa
//
// Created by Patrick Geiller on 29/07/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "JSCocoaFFIClosure.h"
#import "JSCocoaController.h"
#include <sys/mman.h> // for mmap()
void closure_function(ffi_cif* cif, void* resp, void** args, void* userdata);
@implementation JSCocoaFFIClosure
//
// Common closure function, calling back closure object
//
void closure_function(ffi_cif* cif, void* resp, void** args, void* userdata)
{
[(id)userdata calledByClosureWithArgs:args returnValue:resp];
}
- (id)init
{
self = [super init];
argTypes = NULL;
encodings = NULL;
jsFunction = NULL;
return self;
}
//
// Cleanup : called by dealloc and finalize
//
- (void)cleanUp
{
if (encodings) [encodings release];
if (argTypes) free(argTypes);
if (jsFunction)
{
JSValueUnprotect(ctx, jsFunction);
[JSCocoaController downJSValueProtectCount];
}
#if !TARGET_OS_IPHONE
if (munmap(closure, sizeof(closure)) == -1) NSLog(@"ffi closure munmap failed");
#endif
}
- (void)dealloc
{
// NSLog(@"deallocing closure %p IMP=%p", self, closure);
[self cleanUp];
[super dealloc];
}
- (void)finalize
{
[self cleanUp];
[super finalize];
}
- (void*)functionPointer
{
#if !TARGET_OS_IPHONE
return closure;
#else
return NULL;
#endif
}
//
// Bind a js function to closure. We'll jsValueProtect that function from GC.
//
- (IMP)setJSFunction:(JSValueRef)fn inContext:(JSContextRef)context argumentEncodings:(NSMutableArray*)argumentEncodings objC:(BOOL)objC
{
#if !TARGET_OS_IPHONE
if ([argumentEncodings count] == 0) return NULL;
encodings = argumentEncodings;
[encodings retain];
isObjC = objC;
unsigned int i, argumentCount = (unsigned int)([argumentEncodings count]-1);
argTypes = malloc(sizeof(ffi_type*)*argumentCount);
for (i=0; i<argumentCount; i++)
{
JSCocoaFFIArgument* arg = [argumentEncodings objectAtIndex:i+1];
argTypes[i] = [arg ffi_type];
}
if ((closure = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0)) == (void*)-1)
{
NSLog(@"ffi closure mmap failed");
return NULL;
}
id returnValue = [argumentEncodings objectAtIndex:0];
ffi_status prep_status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, argumentCount, [returnValue ffi_type], argTypes);
if (prep_status != FFI_OK)
{
NSLog(@"ffi_prep_cif failed");
return NULL;
}
if (ffi_prep_closure(closure, &cif, closure_function, (void *)self) != FFI_OK)
{
NSLog(@"ffi_prep_closure failed");
return NULL;
}
if (mprotect(closure, sizeof(closure), PROT_READ | PROT_EXEC) == -1)
{
NSLog(@"ffi closure mprotect failed");
return NULL;
}
jsFunction = fn;
ctx = context;
// Protect function from GC
JSValueProtect(ctx, jsFunction);
[JSCocoaController upJSValueProtectCount];
return (IMP)closure;
#else
return NULL;
#endif
}
//
// Called by ffi
//
- (void)calledByClosureWithArgs:(void**)closureArgs returnValue:(void*)returnValue
{
JSObjectRef jsFunctionObject = JSValueToObject(ctx, jsFunction, NULL);
JSValueRef exception = NULL;
// ## Only objC for now. Need to test C function pointers.
// Argument count is encodings count minus return value
NSUInteger i, idx = 0, effectiveArgumentCount = [encodings count]-1;
// Skip self and selector
if (isObjC)
{
effectiveArgumentCount -= 2;
idx = 2;
}
// Convert arguments
JSValueRef* args = NULL;
if (effectiveArgumentCount)
{
args = malloc(effectiveArgumentCount*sizeof(JSValueRef));
for (i=0; i<effectiveArgumentCount; i++, idx++)
{
// +1 to skip return value
id encodingObject = [encodings objectAtIndex:idx+1];
id arg = [[JSCocoaFFIArgument alloc] init];
char encoding = [encodingObject typeEncoding];
if (encoding == '{') [arg setStructureTypeEncoding:[encodingObject structureTypeEncoding] withCustomStorage:*(void**)&closureArgs[idx]];
else [arg setTypeEncoding:[encodingObject typeEncoding] withCustomStorage:closureArgs[idx]];
args[i] = NULL;
[arg toJSValueRef:&args[i] inContext:ctx];
[arg release];
}
}
JSObjectRef jsThis = NULL;
// Create 'this'
if (isObjC)
jsThis = [[JSCocoa controllerFromContext:ctx] boxObject:*(void**)closureArgs[0]];
// Call !
JSValueRef jsReturnValue = JSObjectCallAsFunction(ctx, jsFunctionObject, jsThis, effectiveArgumentCount, args, &exception);
// Convert return value if it's not void
char encoding = [[encodings objectAtIndex:0] typeEncoding];
if (jsReturnValue && encoding != 'v')
{
[JSCocoaFFIArgument fromJSValueRef:jsReturnValue inContext:ctx typeEncoding:encoding fullTypeEncoding:[[encodings objectAtIndex:0] structureTypeEncoding] fromStorage:returnValue];
#ifdef __BIG_ENDIAN__
// As ffi always uses a sizeof(long) return value (even for chars and shorts), do some shifting
int size = [JSCocoaFFIArgument sizeOfTypeEncoding:encoding];
int paddedSize = sizeof(long);
long v;
if (size > 0 && size < paddedSize && paddedSize == 4)
{
v = *(long*)returnValue;
v = CFSwapInt32(v);
*(long*)returnValue = v;
}
#endif
}
if (effectiveArgumentCount) free(args);
if (exception)
{
@throw [NSException exceptionWithName:@"JSCocoa exception"
reason:[[JSCocoaController controllerFromContext:ctx] formatJSException:exception]
userInfo:nil];
}
}
@end

View File

@@ -1,98 +0,0 @@
//
// JSCocoaLib.h
// JSCocoa
//
// Created by Patrick Geiller on 21/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#if !TARGET_IPHONE_SIMULATOR && !TARGET_OS_IPHONE
#import <Cocoa/Cocoa.h>
#endif
#import "JSCocoa.h"
@class JSCocoaMemoryBuffer;
@interface JSCocoaOutArgument : NSObject
{
JSCocoaFFIArgument* arg;
JSCocoaMemoryBuffer* buffer;
int bufferIndex;
}
- (BOOL)mateWithJSCocoaFFIArgument:(JSCocoaFFIArgument*)arg;
- (JSValueRef)outJSValueRefInContext:(JSContextRef)ctx;
@end
@interface JSCocoaMemoryBuffer : NSObject
{
void* buffer;
int bufferSize;
// NSString holding types
id typeString;
// Indicates whether types are aligned.
// types not aligned (DEFAULT)
// size('fcf') = 4 + 1 + 4 = 9
// types aligned
// size('fcf') = 4 + 4(align) + 4 = 12
BOOL alignTypes;
}
+ (id)bufferWithTypes:(id)types;
- (id)initWithTypes:(id)types;
//- (id)initWithTypes:(id)types andValues:(id)values;
//- (id)initWithMemoryBuffers:(id)buffers;
- (void*)pointerForIndex:(NSUInteger)index;
- (char)typeAtIndex:(NSUInteger)index;
- (JSValueRef)valueAtIndex:(NSUInteger)index inContext:(JSContextRef)ctx;
- (BOOL)setValue:(JSValueRef)jsValue atIndex:(NSUInteger)index inContext:(JSContextRef)ctx;
- (NSUInteger)typeCount;
@end
@interface JSCocoaLib : NSObject
+ (id)rootclasses;
+ (id)classes;
+ (id)protocols;
+ (id)imageNames;
+ (id)methods;
+ (id)runtimeReport;
@end
@interface NSObject(ClassWalker)
+ (id)__classImage;
- (id)__classImage;
+ (id)__derivationPath;
- (id)__derivationPath;
+ (NSUInteger)__derivationLevel;
- (NSUInteger)__derivationLevel;
+ (id)__ownMethods;
- (id)__ownMethods;
+ (id)__methods;
- (id)__methods;
+ (id)__subclasses;
- (id)__subclasses;
+ (id)__subclassTree;
- (id)__subclassTree;
+ (id)__ownIvars;
- (id)__ownIvars;
+ (id)__ivars;
- (id)__ivars;
+ (id)__ownProperties;
- (id)__ownProperties;
+ (id)__properties;
- (id)__properties;
+ (id)__ownProtocols;
- (id)__ownProtocols;
+ (id)__protocols;
- (id)__protocols;
@end

View File

@@ -1,830 +0,0 @@
//
// JSCocoaLib.m
// JSCocoa
//
// Created by Patrick Geiller on 21/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "JSCocoaLib.h"
//
// Handles out arguments of functions and methods.
// eg NSOpenGLGetVersion(int*, int*) asks for two pointers to int.
// JSCocoaOutArgument will alloc the memory through JSCocoaFFIArgument and get the result back to Javascript (check out value in JSCocoaController)
//
@implementation JSCocoaOutArgument
- (id)init
{
self = [super init];
arg = nil;
buffer = nil;
return self;
}
- (void)cleanUp
{
[arg release];
[buffer release];
}
- (void)dealloc
{
[self cleanUp];
[super dealloc];
}
- (void)finalize
{
[self cleanUp];
[super finalize];
}
//
// convert the out value to a JSValue
//
- (JSValueRef)outJSValueRefInContext:(JSContextRef)ctx
{
JSValueRef jsValue = NULL;
[arg toJSValueRef:&jsValue inContext:ctx];
return jsValue;
}
// Called from Javascript to extract the resulting value as an object (valueOfCallback returns a string)
- (JSValueRefAndContextRef)outValue
{
JSValueRefAndContextRef r;
id jsc = nil;
object_getInstanceVariable(self, "__jsCocoaController", (void**)&jsc);
if (!jsc) return r;
r.ctx = [jsc ctx];
r.value = [self outJSValueRefInContext:r.ctx];
return r;
}
//
// JSCocoaOutArgument holds a JSCocoaFFIArgument around.
// it stays alive after ffi_call and can be queried by Javascript for type modifier values.
//
- (BOOL)mateWithJSCocoaFFIArgument:(JSCocoaFFIArgument*)_arg
{
// If holding a memory buffer, use its pointer
if (buffer)
{
arg = _arg;
[arg retain];
void* ptr = [buffer pointerForIndex:bufferIndex];
if (!ptr) return NO;
[arg setTypeEncoding:[arg typeEncoding] withCustomStorage:ptr];
return YES;
}
// Standard pointer
void* p = [_arg allocatePointerStorage];
if (!p) return NO;
// Zero out storage
*(void**)p = NULL;
arg = _arg;
[arg retain];
return YES;
}
- (BOOL)mateWithMemoryBuffer:(id)b atIndex:(int)idx
{
if (!b || ![b isKindOfClass:[JSCocoaMemoryBuffer class]]) return NSLog(@"mateWithMemoryBuffer called without a memory buffer (%@)", b), NO;
buffer = b;
[buffer retain];
bufferIndex = idx;
return YES;
}
@end
//
// Instead of malloc(sizeof(float)*4), JSCocoaMemoryBuffer expects 'ffff' as an init string.
// The buffer can be manipulated like an array (buffer[2] = 0.5)
// * it can be filled, calling methods to copy data in it
// - (NSBezierPathElement)elementAtIndex:(NSInteger)index associatedPoints:(NSPointArray)points;
// * it can be used as data source, calling methods to copy data from it
// - (void)setAssociatedPoints:(NSPointArray)points atIndex:(NSInteger)index;
//
@implementation JSCocoaMemoryBuffer
+ (id)bufferWithTypes:(id)types
{
return [[[JSCocoaMemoryBuffer alloc] initWithTypes:types] autorelease];
}
- (id)initWithTypes:(id)_types
{
self = [super init];
buffer = NULL;
// Copy types string
typeString = [NSString stringWithString:_types];
[typeString retain];
// Compute buffer size
const char* types = [typeString UTF8String];
NSUInteger l = [typeString length];
bufferSize = 0;
for (int i=0; i<l; i++)
{
int size = [JSCocoaFFIArgument sizeOfTypeEncoding:types[i]];
if (size == -1) return NSLog(@"JSCocoaMemoryBuffer initWithTypes : unknown type %c", types[i]), self;
bufferSize += size;
}
if (bufferSize == 0) {
NSLog(@"initWithTypes has no types");
return NULL;
}
// Malloc
// NSLog(@"mallocing %d bytes for %@", bufferSize, typeString);
buffer = malloc(bufferSize);
memset(buffer, bufferSize, 1);
return self;
}
- (void)dealloc
{
if (buffer) free(buffer);
[typeString release];
[super dealloc];
}
- (void)finalize
{
if (buffer) free(buffer);
[super finalize];
}
//
// Returns pointer for index without any padding
//
- (void*)pointerForIndex:(NSUInteger)idx
{
const char* types = [typeString UTF8String];
if (idx >= [typeString length]) return NULL;
void* pointedValue = buffer;
for (int i=0; i<idx; i++)
{
// NSLog(@"advancing %c", types[i]);
[JSCocoaFFIArgument advancePtr:&pointedValue accordingToEncoding:types[i]];
}
return pointedValue;
}
- (char)typeAtIndex:(NSUInteger)idx
{
if (idx >= [typeString length]) return '\0';
return [typeString UTF8String][idx];
}
- (NSUInteger)typeCount
{
return [typeString length];
}
-(BOOL)referenceObject:(id)o usingPointerAtIndex:(NSUInteger)idx
{
if ([self typeAtIndex:idx] != '^') return NO;
void* v = *(void**)[self pointerForIndex:idx];
if (!v) return NO;
*(id*)v = o;
return YES;
}
- (id)dereferenceObjectAtIndex:(NSUInteger)idx
{
if ([self typeAtIndex:idx] != '^') return nil;
void* v = *(void**)[self pointerForIndex:idx];
if (!v) return NULL;
id o = *(id*)v;
return o;
return *(id*)v;
}
//
// Using JSValueRefAndContextRef as input to get the current context in which to create the return value
//
- (JSValueRef)valueAtIndex:(NSUInteger)idx inContext:(JSContextRef)ctx
{
char typeEncoding = [self typeAtIndex:idx];
void* pointedValue = [self pointerForIndex:idx];
if (!pointedValue) return JSValueMakeUndefined(ctx);
JSValueRef returnValue;
[JSCocoaFFIArgument toJSValueRef:&returnValue inContext:ctx typeEncoding:typeEncoding fullTypeEncoding:nil fromStorage:pointedValue];
return returnValue;
}
- (BOOL)setValue:(JSValueRef)jsValue atIndex:(NSUInteger)idx inContext:(JSContextRef)ctx
{
char typeEncoding = [self typeAtIndex:idx];
void* pointedValue = [self pointerForIndex:idx];
if (!pointedValue) return NO;
[JSCocoaFFIArgument fromJSValueRef:jsValue inContext:ctx typeEncoding:typeEncoding fullTypeEncoding:nil fromStorage:pointedValue];
return YES;
}
@end
@implementation JSCocoaLib
//
// Class list
// Some classes are skipped as adding them to an array crashes (Zombie, classes derived from Object or NSProxy)
//
+ (NSArray*)classes
{
int classCount = objc_getClassList(nil, 0);
Class* classList = malloc(sizeof(Class)*classCount);
objc_getClassList(classList, classCount);
NSMutableArray* classArray = [NSMutableArray array];
for (int i=0; i<classCount; i++)
{
id class = classList[i];
const char* name= class_getName(class);
if (!name) continue;
id className = [NSString stringWithUTF8String:name];
id superclass = class_getSuperclass(class);
id superclassName = superclass ? [NSString stringWithUTF8String:class_getName(superclass)] : @"";
// Check if this class inherits from NSProxy. isKindOfClass crashes, so use raw ObjC api.
BOOL isKindOfNSProxy = NO;
id c = class;
while (c)
{
if ([[NSString stringWithUTF8String:class_getName(c)] isEqualToString:@"NSProxy"]) isKindOfNSProxy = YES;
c = class_getSuperclass(c);
}
// Skip classes crashing when added to an NSArray
if ([className hasPrefix:@"_NSZombie_"]
|| [className isEqualToString:@"Object"]
|| [superclassName isEqualToString:@"Object"]
|| [className isEqualToString:@"NSMessageBuilder"]
|| [className isEqualToString:@"NSLeafProxy"]
|| [className isEqualToString:@"__NSGenericDeallocHandler"]
|| isKindOfNSProxy
)
{
continue;
}
[classArray addObject:class];
}
free(classList);
return classArray;
}
+ (NSArray*)rootclasses
{
id classes = [self classes];
NSMutableArray* classArray = [NSMutableArray array];
for (id class in classes)
{
id superclass = class_getSuperclass(class);
if (superclass) continue;
[classArray addObject:class];
}
return classArray;
}
//
// Return an array of { name : imageName, classNames : [className, className, ...] }
//
+ (id)imageNames
{
id array = [NSMutableArray array];
unsigned int imageCount;
const char** imageNames = objc_copyImageNames(&imageCount);
for (int i=0; i<imageCount; i++)
{
const char* cname = imageNames[i];
// Gather image class names
id array2 = [NSMutableArray array];
unsigned int classCount;
const char** classNames = objc_copyClassNamesForImage(cname, &classCount);
for (int j=0; j<classCount; j++)
[array2 addObject:[NSString stringWithUTF8String:classNames[j]]];
free(classNames);
// Hash of name and classNames
id name = [NSString stringWithUTF8String:cname];
id hash = [NSDictionary dictionaryWithObjectsAndKeys:
name, @"name",
array2, @"classNames",
nil];
[array addObject:hash];
}
free(imageNames);
return array;
}
//
// Return protocols and their associated methods
//
+ (id)protocols
{
#if NS_BLOCKS_AVAILABLE
id array = [NSMutableArray array];
unsigned int protocolCount;
Protocol** protocols = objc_copyProtocolList(&protocolCount);
for (int i=0; i<protocolCount; i++)
{
// array2 is modified by the following block
__block id array2 = [NSMutableArray array];
Protocol* p = protocols[i];
// Common block for copying protocol method descriptions
void (^b)(BOOL, BOOL) = ^(BOOL isRequiredMethod, BOOL isInstanceMethod) {
unsigned int descriptionCount;
struct objc_method_description* methodDescriptions = protocol_copyMethodDescriptionList(p, isRequiredMethod, isInstanceMethod, &descriptionCount);
for (int j=0; j<descriptionCount; j++)
{
struct objc_method_description d = methodDescriptions[j];
id name = NSStringFromSelector(d.name);
id encoding = [NSString stringWithUTF8String:d.types];
id isRequired = [NSNumber numberWithBool:isRequiredMethod];
id type = isInstanceMethod ? @"instance" : @"class";
id hash = [NSDictionary dictionaryWithObjectsAndKeys:
name, @"name",
encoding, @"encoding",
isRequired, @"isRequired",
type, @"type",
nil];
[array2 addObject:hash];
}
if (methodDescriptions) free(methodDescriptions);
};
// Copy all methods, going through required, non-required, class, instance methods
b(YES, YES);
b(YES, NO);
b(NO, YES);
b(NO, NO);
// Main object : { name : protocolName, methods : [{ name, encoding, isRequired, type }, ...]
id name = [NSString stringWithUTF8String:protocol_getName(p)];
id hash = [NSDictionary dictionaryWithObjectsAndKeys:
name, @"name",
array2, @"methods",
nil];
[array addObject:hash];
}
free(protocols);
return array;
#else
return nil;
#endif
}
+ (id)methods
{
id classes = [self classes];
id methods = [NSMutableArray array];
for (id class in classes)
[methods addObjectsFromArray:[class __ownMethods]];
return methods;
}
//
// Runtime report
// Report EVERYTHING
// classes
// { className : { name
// superclassName
// derivationPath
// subclasses
// methods
// protocols
// ivars
// properties
// }
// protocols
// { protocolName : { name
// methods
// }
// imageNames
// { imageName : { name
// classNames : [className1, className2, ...]
// }
//
+ (id)runtimeReport
{
/*
id classList = [self classes];
id protocols = [self protocols];
id imageNames = [self imageNames];
id classes = [NSMutableDictionary dictionary];
int classCount = [classList count];
// for (id class in classList)
for (int i=0; i<classCount; i++)
{
id class = [classList objectAtIndex:i];
id className = [class description];
NSLog(@"%d/%d %@", i, (classCount-1), className);
id superclass = [class superclass];
id superclassName = superclass ? [NSString stringWithUTF8String:class_getName(superclass)] : nil;
//NSLog(@"%@ (%d/%d)", className, i, classCount-1);
id hash = [NSDictionary dictionaryWithObjectsAndKeys:
className, @"name",
superclassName, @"superclassName",
[class __derivationPath], @"derivationPath",
[class __methods], @"methods",
[class __protocols], @"protocols",
[class __ivars], @"ivars",
[class __properties], @"properties",
nil];
[classes setObject:hash forKey:className];
}
id dict = [NSDictionary dictionaryWithObjectsAndKeys:
classes, @"classes",
protocols, @"protocols",
imageNames, @"imageNames",
nil];
*/
// This happens on the ObjC side, NOT in jsc.
// There are 2500 classes to dump, this takes a while.
// The memory hog is also on the ObjC side, happening during [dict description]
return @"Disabled for now, as the resulting hash hangs the app while goring memory";
}
@end
//
// Runtime information
//
@implementation NSObject(ClassWalker)
//
// Class name (description might have been overriden, and classes don't seem to travel well over NSDistantObject)
//
- (id)__className
{
return [[self class] description];
}
//
// Returns which framework containing the class
//
+ (id)__classImage
{
const char* name = class_getImageName(self);
if (!name) return nil;
return [NSString stringWithUTF8String:name];
}
- (id)__classImage
{
return [[self class] __classImage];
}
//
// Derivation path
// derivationPath(NSButton) = NSObject, NSResponder, NSView, NSControl, NSButton
//
+ (id)__derivationPath
{
int level = -1;
id class = self;
id classes = [NSMutableArray array];
while (class)
{
[classes insertObject:class atIndex:0];
level++;
class = [class superclass];
}
return classes;
}
- (id)__derivationPath
{
return [[self class] __derivationPath];
}
//
// Derivation level
//
+ (NSUInteger)__derivationLevel
{
return [[self __derivationPath] count]-1;
}
- (NSUInteger)__derivationLevel
{
return [[self class] __derivationLevel];
}
//
// Methods
//
// Copy all class or instance (type) methods of a class in an array
static id copyMethods(Class class, NSMutableArray* array, NSString* type)
{
if ([type isEqualToString:@"class"]) class = objc_getMetaClass(class_getName(class));
unsigned int methodCount;
Method* methods = class_copyMethodList(class, &methodCount);
for (int i=0; i<methodCount; i++)
{
Method m = methods[i];
Dl_info info;
dladdr(method_getImplementation(m), &info);
id name = NSStringFromSelector(method_getName(m));
id encoding = [NSString stringWithUTF8String:method_getTypeEncoding(m)];
id framework= [NSString stringWithUTF8String:info.dli_fname];
id hash = [NSDictionary dictionaryWithObjectsAndKeys:
name, @"name",
encoding, @"encoding",
type, @"type",
class, @"class",
framework, @"framework",
nil];
[array addObject:hash];
}
free(methods);
return array;
}
+ (id)__ownMethods
{
id methods = [NSMutableArray array];
copyMethods([self class], methods, @"class");
copyMethods([self class], methods, @"instance");
return methods;
}
- (id)__ownMethods
{
return [[self class] __ownMethods];
}
+ (id)__methods
{
id classes = [self __derivationPath];
id methods = [NSMutableArray array];
for (id class in classes)
[methods addObjectsFromArray:[class __ownMethods]];
return methods;
}
- (id)__methods
{
return [[self class] __methods];
}
//
// Subclasses
//
// Recursively go breadth first all a class' subclasses
static void populateSubclasses(Class class, NSMutableArray* array, NSMutableDictionary* subclassesHash)
{
// Add ourselves
[array addObject:class];
id className = [NSString stringWithUTF8String:class_getName(class)];
id subclasses = [subclassesHash objectForKey:className];
for (id subclass in subclasses)
{
populateSubclasses(subclass, array, subclassesHash);
}
}
// Build a hash of className : [direct subclasses] then walk it down recursively.
+ (id)__subclasses
{
#if NS_BLOCKS_AVAILABLE
id classes = [JSCocoaLib classes];
id subclasses = [NSMutableArray array];
id subclassesHash = [NSMutableDictionary dictionary];
for (id class in classes)
{
id superclass = [class superclass];
if (!superclass) continue;
id superclassName = [NSString stringWithUTF8String:class_getName(superclass)];
id subclassesArray = [subclassesHash objectForKey:superclassName];
if (!subclassesArray)
{
subclassesArray = [NSMutableArray array];
[subclassesHash setObject:subclassesArray forKey:superclassName];
}
[subclassesArray addObject:class];
}
// (Optional) sort by class name
for (id className in subclassesHash)
{
id subclassesArray = [subclassesHash objectForKey:className];
[subclassesArray sortUsingComparator:
^(id a, id b)
{
// Case insensitive compare + remove underscores for sorting (yields [..., NSStatusBarButton, _NSThemeWidget, NSToolbarButton] )
return [[[a description] stringByReplacingOccurrencesOfString:@"_" withString:@""]
compare:[[b description] stringByReplacingOccurrencesOfString:@"_" withString:@""] options:NSCaseInsensitiveSearch];
}];
}
populateSubclasses(self, subclasses, subclassesHash);
return subclasses;
#else
return nil;
#endif
}
- (id)__subclasses
{
return [[self class] __subclasses];
}
// Returns a string showing subclasses, prefixed with as many spaces as their derivation level
+ (id)__subclassTree
{
id subclasses = [self __subclasses];
id str = [NSMutableString string];
for (id subclass in subclasses)
{
NSUInteger level = [subclass __derivationLevel];
for (int i=0; i<level; i++)
[str appendString:@" "];
[str appendString:[NSString stringWithUTF8String:class_getName(subclass)]];
[str appendString:@"\n"];
}
return str;
}
- (id)__subclassTree
{
return [[self class] __subclassTree];
}
//
// ivars
//
+ (id)__ownIvars
{
unsigned int ivarCount;
Ivar* ivars = class_copyIvarList(self, &ivarCount);
id array = [NSMutableArray array];
for (int i=0; i<ivarCount; i++)
{
Ivar ivar = ivars[i];
id name = [NSString stringWithUTF8String:ivar_getName(ivar)];
id encoding = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
id offset = [NSNumber numberWithLong:ivar_getOffset(ivar)];
id hash = [NSDictionary dictionaryWithObjectsAndKeys:
name, @"name",
encoding, @"encoding",
offset, @"offset",
self, @"class",
nil];
[array addObject:hash];
}
free(ivars);
return array;
}
- (id)__ownIvars
{
return [[self class] __ownIvars];
}
+ (id)__ivars
{
id classes = [self __derivationPath];
id ivars = [NSMutableArray array];
for (id class in classes)
[ivars addObjectsFromArray:[class __ownIvars]];
return ivars;
}
- (id)__ivars
{
return [[self class] __ivars];
}
//
// Properties
//
+ (id)__ownProperties
{
unsigned int propertyCount;
objc_property_t* properties = class_copyPropertyList(self, &propertyCount);
id array = [NSMutableArray array];
for (int i=0; i<propertyCount; i++)
{
objc_property_t property = properties[i];
id name = [NSString stringWithUTF8String:property_getName(property)];
id attributes = [NSString stringWithUTF8String:property_getAttributes(property)];
id hash = [NSDictionary dictionaryWithObjectsAndKeys:
name, @"name",
attributes, @"attributes",
self, @"class",
nil];
[array addObject:hash];
}
free(properties);
return array;
}
- (id)__ownProperties
{
return [[self class] __ownProperties];
}
+ (id)__properties
{
id classes = [self __derivationPath];
id properties = [NSMutableArray array];
for (id class in classes)
[properties addObjectsFromArray:[class __ownProperties]];
return properties;
}
- (id)__properties
{
return [[self class] __properties];
}
//
// Protocols
//
+ (id)__ownProtocols
{
unsigned int protocolCount;
Protocol** protocols = class_copyProtocolList(self, &protocolCount);
id array = [NSMutableArray array];
for (int i=0; i<protocolCount; i++)
{
id name = [NSString stringWithUTF8String:protocol_getName(protocols[i])];
id hash = [NSDictionary dictionaryWithObjectsAndKeys:
name, @"name",
self, @"class",
nil];
[array addObject:hash];
}
free(protocols);
return array;
}
- (id)__ownProtocols
{
return [[self class] __ownProtocols];
}
+ (id)__protocols
{
id classes = [self __derivationPath];
id protocols = [NSMutableArray array];
for (id class in classes)
[protocols addObjectsFromArray:[class __ownProtocols]];
return protocols;
}
- (id)__protocols
{
return [[self class] __protocols];
}
@end

View File

@@ -1,92 +0,0 @@
//
// JSCocoaPrivateObject.h
// JSCocoa
//
// Created by Patrick Geiller on 09/07/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#if !TARGET_IPHONE_SIMULATOR && !TARGET_OS_IPHONE
#import <Cocoa/Cocoa.h>
#import <JavaScriptCore/JavaScriptCore.h>
#endif
#import <mach-o/dyld.h>
#import <dlfcn.h>
//#import <objc/objc-class.h>
#import <objc/runtime.h>
#import <objc/message.h>
//
// Boxing object
//
// type
// @ ObjC object
// struct C struct
// method ObjC method name
// function C function
// rawPointer raw C pointer (_C_PTR)
// jsFunction Javascript function
// jsValueRef raw jsvalue
// externalJSValueRef jsvalue coming from an external context (eg, a WebView)
//
@interface JSCocoaPrivateObject : NSObject {
NSString* type;
NSString* xml;
NSString* methodName;
NSString* structureName;
NSString* declaredType;
void* rawPointer;
id object;
Method method;
JSValueRef jsValue;
JSContextRef ctx;
unsigned int externalJSValueIndex;
// (test) when storing JSValues from a WebView, used to retain the WebView's context.
// Disabled for now. Just make sure the WebView has a longer life than the vars it uses.
//
// Disabled because retaining the context crashes in 32 bits, but works in 64 bit.
// May be reenabled someday.
// JSContextGroupRef contextGroup;
BOOL isAutoCall;
BOOL retainObject;
// Disabled because of a crash on i386. Release globalContext last.
// BOOL retainContext;
}
@property (copy) NSString* type;
@property (copy) NSString* xml;
@property (copy) NSString* methodName;
@property (copy) NSString* structureName;
@property (copy) NSString* declaredType;
@property BOOL isAutoCall;
//- (void)setPtr:(void*)ptrValue;
//- (void*)ptr;
- (void)setObject:(id)o;
- (void)setObjectNoRetain:(id)o;
- (BOOL)retainObject;
- (id)object;
- (void)setMethod:(Method)m;
- (Method)method;
- (void)setJSValueRef:(JSValueRef)v ctx:(JSContextRef)ctx;
- (JSValueRef)jsValueRef;
- (void)setCtx:(JSContextRef)ctx;
- (JSContextRef)ctx;
- (void)setExternalJSValueRef:(JSValueRef)v ctx:(JSContextRef)ctx;
- (void*)rawPointer;
- (void)setRawPointer:(void*)rp encoding:(id)encoding;
- (id)rawPointerEncoding;
@end

View File

@@ -1,236 +0,0 @@
//
// JSCocoaPrivateObject.m
// JSCocoa
//
// Created by Patrick Geiller on 09/07/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "JSCocoaPrivateObject.h"
#import "JSCocoaController.h"
@implementation JSCocoaPrivateObject
@synthesize type, xml, declaredType, methodName, structureName, isAutoCall;
- (id)init
{
self = [super init];
type = xml = declaredType = methodName = nil;
object = nil;
isAutoCall = NO;
jsValue = NULL;
retainObject= YES;
rawPointer = NULL;
ctx = NULL;
// retainContext = NO;
externalJSValueIndex = 0;
[JSCocoaController upJSCocoaPrivateObjectCount];
return self;
}
- (void)cleanUp
{
[JSCocoaController downJSCocoaPrivateObjectCount];
if (object && retainObject)
{
// NSLog(@"commented downBoxedJSObjectCount");
// [JSCocoaController downBoxedJSObjectCount:object];
// NSLog(@"releasing %@(%d)", [object class], [object retainCount]);
// if ([object isKindOfClass:[JSCocoaController class]])
// [object autorelease];
// else
[object release];
}
if (jsValue)
{
if (!externalJSValueIndex) JSValueUnprotect(ctx, jsValue);
[JSCocoaController downJSValueProtectCount];
// If holding a value from an external context, remove it from the GC-safe hash and release context.
if (externalJSValueIndex)
{
JSStringRef scriptJS = JSStringCreateWithUTF8CString("delete __gcprotect[arguments[0]]");
JSObjectRef fn = JSObjectMakeFunction(ctx, NULL, 0, NULL, scriptJS, NULL, 1, NULL);
JSStringRelease(scriptJS);
JSValueRef jsNumber = JSValueMakeNumber(ctx, externalJSValueIndex);
JSValueRef exception = NULL;
JSObjectCallAsFunction(ctx, fn, NULL, 1, (JSValueRef*)&jsNumber, &exception);
// JSGlobalContextRelease((JSGlobalContextRef)ctx);
if (exception)
NSLog(@"Got an exception while trying to release externalJSValueRef %p of context %p", jsValue, ctx);
}
}
/*
if (retainContext)
{
NSLog(@"releasing %p", ctx);
JSContextGroupRelease(contextGroup);
// JSGlobalContextRelease((JSGlobalContextRef)ctx);
}
*/
// Release properties
[type release];
[xml release];
[methodName release];
[structureName release];
[declaredType release];
}
- (void)dealloc
{
[self cleanUp];
[super dealloc];
}
- (void)finalize
{
[self cleanUp];
[super finalize];
}
- (void)setObject:(id)o
{
// if (object && retainObject)
// [object release];
object = o;
if (object && [object retainCount] == -1) return;
[object retain];
}
- (void)setObjectNoRetain:(id)o
{
object = o;
retainObject = NO;
}
- (BOOL)retainObject
{
return retainObject;
}
- (id)object
{
return object;
}
- (void)setMethod:(Method)m
{
method = m;
}
- (Method)method
{
return method;
}
- (void)setJSValueRef:(JSValueRef)v ctx:(JSContextRef)c
{
// While autocalling we'll get a NULL value when boxing a void return type - just skip JSValueProtect
if (!v)
{
// NSLog(@"setJSValueRef: NULL value");
jsValue = 0;
return;
}
jsValue = v;
// ctx = c;
// Register global context (this would crash the launcher as JSValueUnprotect was called on a destroyed context)
ctx = [[JSCocoaController controllerFromContext:c] ctx];
JSValueProtect(ctx, jsValue);
[JSCocoaController upJSValueProtectCount];
}
- (JSValueRef)jsValueRef
{
return jsValue;
}
- (void)setCtx:(JSContextRef)_ctx {
ctx = _ctx;
}
- (JSContextRef)ctx
{
return ctx;
}
- (void)setExternalJSValueRef:(JSValueRef)v ctx:(JSContextRef)c
{
if (!v)
{
jsValue = 0;
return;
}
jsValue = v;
ctx = c;
// Register value in a global hash to protect it from GC. This sucks but JSValueProtect() fails.
JSStringRef scriptJS = JSStringCreateWithUTF8CString("if (!('__gcprotect' in this)) { __gcprotect = {}; __gcprotectidx = 1; } __gcprotect[__gcprotectidx] = arguments[0]; return __gcprotectidx++ ");
JSObjectRef fn = JSObjectMakeFunction(ctx, NULL, 0, NULL, scriptJS, NULL, 1, NULL);
JSStringRelease(scriptJS);
JSValueRef exception = NULL;
JSValueRef result = JSObjectCallAsFunction(ctx, fn, NULL, 1, (JSValueRef*)&jsValue, &exception);
if (exception) return;
// Use hash index as key, will be used to remove value from hash upon deletion.
externalJSValueIndex = (unsigned int)JSValueToNumber(ctx, result, &exception);
if (exception) return;
// JSGlobalContextRetain((JSGlobalContextRef)ctx);
[JSCocoaController upJSValueProtectCount];
}
- (void*)rawPointer
{
return rawPointer;
}
- (void)setRawPointer:(void*)rp encoding:(id)encoding
{
rawPointer = rp;
// NSLog(@"RAWPOINTER=%@", encoding);
declaredType = encoding;
[declaredType retain];
}
- (id)rawPointerEncoding
{
return declaredType;
}
- (id)description {
id extra = @"";
if ([type isEqualToString:@"rawPointer"])
extra = [NSString stringWithFormat:@" rawPointer=%p declaredType=%@", rawPointer, declaredType];
return [NSString stringWithFormat:@"<%@: %p holding %@%@>",
[self class],
self,
type,
extra
];
}
+ (id)description {
return @"<JSCocoaPrivateObject class>";
}
- (id)dereferencedObject {
if (![type isEqualToString:@"rawPointer"] || !rawPointer)
return nil;
return *(void**)rawPointer;
}
- (BOOL)referenceObject:(id)o {
if (![type isEqualToString:@"rawPointer"])
return NO;
*(id*)rawPointer = o;
return YES;
}
@end

289
Atom/MainMenu.xib Executable file
View File

@@ -0,0 +1,289 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
<data>
<int key="IBDocument.SystemTarget">1050</int>
<string key="IBDocument.SystemVersion">11C74</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
<string key="IBDocument.AppKitVersion">1138.23</string>
<string key="IBDocument.HIToolboxVersion">567.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">1938</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSUserDefaultsController</string>
<string>NSMenu</string>
<string>NSMenuItem</string>
<string>NSCustomObject</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomObject" id="1021">
<string key="NSClassName">ClientApplication</string>
</object>
<object class="NSCustomObject" id="1014">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1050">
<string key="NSClassName">Atom</string>
</object>
<object class="NSMenu" id="649796088">
<string key="NSTitle">AMainMenu</string>
<object class="NSMutableArray" key="NSMenuItems">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMenuItem" id="694149608">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Atom</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<object class="NSCustomResource" key="NSOnImage" id="293900348">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSMenuCheckmark</string>
</object>
<object class="NSCustomResource" key="NSMixedImage" id="169361956">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSMenuMixedState</string>
</object>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="110575045">
<string key="NSTitle">Atom</string>
<object class="NSMutableArray" key="NSMenuItems">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMenuItem" id="238522557">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Run Specs</string>
<string key="NSKeyEquiv">s</string>
<int key="NSKeyEquivModMask">1835008</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="293900348"/>
<reference key="NSMixedImage" ref="169361956"/>
</object>
<object class="NSMenuItem" id="305640227">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Quit</string>
<string key="NSKeyEquiv">q</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="293900348"/>
<reference key="NSMixedImage" ref="169361956"/>
</object>
</object>
<string key="NSName">_NSAppleMenu</string>
</object>
</object>
</object>
<string key="NSName">_NSMainMenu</string>
</object>
<object class="NSUserDefaultsController" id="143541711">
<bool key="NSSharedInstance">YES</bool>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="1050"/>
<reference key="destination" ref="1021"/>
</object>
<int key="connectionID">440</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">stop:</string>
<reference key="source" ref="1050"/>
<reference key="destination" ref="305640227"/>
</object>
<int key="connectionID">447</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">runSpecs:</string>
<reference key="source" ref="1050"/>
<reference key="destination" ref="238522557"/>
</object>
<int key="connectionID">449</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="755588897">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1048"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1021"/>
<reference key="parent" ref="755588897"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1014"/>
<reference key="parent" ref="755588897"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1050"/>
<reference key="parent" ref="755588897"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">29</int>
<reference key="object" ref="649796088"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="694149608"/>
</object>
<reference key="parent" ref="755588897"/>
<string key="objectName">MainMenu</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">56</int>
<reference key="object" ref="694149608"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="110575045"/>
</object>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">57</int>
<reference key="object" ref="110575045"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="238522557"/>
<reference ref="305640227"/>
</object>
<reference key="parent" ref="694149608"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">58</int>
<reference key="object" ref="238522557"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">389</int>
<reference key="object" ref="143541711"/>
<reference key="parent" ref="755588897"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">441</int>
<reference key="object" ref="305640227"/>
<reference key="parent" ref="110575045"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.IBPluginDependency</string>
<string>-2.IBPluginDependency</string>
<string>-3.IBPluginDependency</string>
<string>29.IBPluginDependency</string>
<string>389.IBPluginDependency</string>
<string>441.IBPluginDependency</string>
<string>56.IBPluginDependency</string>
<string>57.IBPluginDependency</string>
<string>58.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="755588897"/>
<reference key="dict.values" ref="755588897"/>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference key="dict.sortedKeys" ref="755588897"/>
<reference key="dict.values" ref="755588897"/>
</object>
<nil key="sourceID"/>
<int key="maxID">449</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">Atom</string>
<string key="superclassName">NSApplication</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">runSpecs:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<string key="NS.key.0">runSpecs:</string>
<object class="IBActionInfo" key="NS.object.0">
<string key="name">runSpecs:</string>
<string key="candidateClassName">id</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/Atom.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<integer value="1050" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
<real value="1060" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSMenuCheckmark</string>
<string>NSMenuMixedState</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>{9, 8}</string>
<string>{7, 2}</string>
</object>
</object>
</data>
</archive>

View File

@@ -1,49 +0,0 @@
/* =============================================================================
FILE: UKFNSubscribeFileWatcher.m
PROJECT: Filie
COPYRIGHT: (c) 2005 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT License
REVISIONS:
2006-03-13 UK Commented, added singleton.
2005-03-02 UK Created.
========================================================================== */
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import <Cocoa/Cocoa.h>
#import "UKFileWatcher.h"
#import <Carbon/Carbon.h>
/*
NOTE: FNSubscribe has a built-in delay: If your application is in the
background while the changes happen, all notifications will be queued up
and sent to your app at once the moment it is brought to front again. If
your app really needs to do live updates in the background, use a KQueue
instead.
*/
// -----------------------------------------------------------------------------
// Class declaration:
// -----------------------------------------------------------------------------
@interface UKFNSubscribeFileWatcher : NSObject <UKFileWatcher>
{
id delegate; // Delegate must respond to UKFileWatcherDelegate protocol.
NSMutableDictionary* subscriptions; // List of FNSubscription pointers in NSValues, with the pathnames as their keys.
}
+(id) sharedFileWatcher;
// UKFileWatcher defines the methods: addPath: removePath: and delegate accessors.
// Private:
-(void) sendDelegateMessage: (FNMessage)message forSubscription: (FNSubscriptionRef)subscription;
@end

View File

@@ -1,201 +0,0 @@
/* =============================================================================
FILE: UKFNSubscribeFileWatcher.m
PROJECT: Filie
COPYRIGHT: (c) 2005 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT License
REVISIONS:
2006-03-13 UK Commented, added singleton, added notifications.
2005-03-02 UK Created.
========================================================================== */
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import "UKFNSubscribeFileWatcher.h"
#import <Carbon/Carbon.h>
// -----------------------------------------------------------------------------
// Prototypes:
// -----------------------------------------------------------------------------
void UKFileSubscriptionProc(FNMessage message, OptionBits flags, void *refcon, FNSubscriptionRef subscription);
@implementation UKFNSubscribeFileWatcher
// -----------------------------------------------------------------------------
// sharedFileWatcher:
// Singleton accessor.
// -----------------------------------------------------------------------------
+(id) sharedFileWatcher
{
static UKFNSubscribeFileWatcher* sSharedFileWatcher = nil;
if( !sSharedFileWatcher )
sSharedFileWatcher = [[UKFNSubscribeFileWatcher alloc] init]; // This is a singleton, and thus an intentional "leak".
return sSharedFileWatcher;
}
// -----------------------------------------------------------------------------
// * CONSTRUCTOR:
// -----------------------------------------------------------------------------
-(id) init
{
self = [super init];
if( !self )
return nil;
subscriptions = [[NSMutableDictionary alloc] init];
return self;
}
// -----------------------------------------------------------------------------
// * DESTRUCTOR:
// -----------------------------------------------------------------------------
-(void) dealloc
{
NSEnumerator* enny = [subscriptions objectEnumerator];
NSValue* subValue = nil;
while( (subValue = [enny nextObject]) )
{
FNSubscriptionRef subscription = [subValue pointerValue];
FNUnsubscribe( subscription );
}
[subscriptions release];
[super dealloc];
}
// -----------------------------------------------------------------------------
// addPath:
// Start watching the object at the specified path. This only sends write
// notifications for all changes, as FNSubscribe doesn't tell what actually
// changed about our folder.
// -----------------------------------------------------------------------------
-(void) addPath: (NSString*)path
{
OSStatus err = noErr;
static FNSubscriptionUPP subscriptionUPP = NULL;
FNSubscriptionRef subscription = NULL;
if( !subscriptionUPP )
subscriptionUPP = NewFNSubscriptionUPP( UKFileSubscriptionProc );
err = FNSubscribeByPath( (UInt8*) [path fileSystemRepresentation], subscriptionUPP, (void*)self,
kNilOptions, &subscription );
if( err != noErr )
{
NSLog( @"UKFNSubscribeFileWatcher addPath: %@ failed due to error ID=%d.", path, err );
return;
}
[subscriptions setObject: [NSValue valueWithPointer: subscription] forKey: path];
}
// -----------------------------------------------------------------------------
// removePath:
// Stop watching the object at the specified path.
// -----------------------------------------------------------------------------
-(void) removePath: (NSString*)path
{
NSValue* subValue = nil;
@synchronized( self )
{
subValue = [[[subscriptions objectForKey: path] retain] autorelease];
[subscriptions removeObjectForKey: path];
}
if( subValue )
{
FNSubscriptionRef subscription = [subValue pointerValue];
FNUnsubscribe( subscription );
}
}
// -----------------------------------------------------------------------------
// sendDelegateMessage:forSubscription:
// Bottleneck for change notifications. This is called by our callback
// function to actually inform the delegate and send out notifications.
//
// This *only* sends out write notifications, as FNSubscribe doesn't tell
// what changed about our folder.
// -----------------------------------------------------------------------------
-(void) sendDelegateMessage: (FNMessage)message forSubscription: (FNSubscriptionRef)subscription
{
NSValue* subValue = [NSValue valueWithPointer: subscription];
NSString* path = [[subscriptions allKeysForObject: subValue] objectAtIndex: 0];
[[[NSWorkspace sharedWorkspace] notificationCenter] postNotificationName: UKFileWatcherWriteNotification
object: self
userInfo: [NSDictionary dictionaryWithObjectsAndKeys: path, @"path", nil]];
[delegate watcher: self receivedNotification: UKFileWatcherWriteNotification forPath: path];
//NSLog( @"UKFNSubscribeFileWatcher noticed change to %@", path ); // DEBUG ONLY!
}
// -----------------------------------------------------------------------------
// delegate:
// Accessor for file watcher delegate.
// -----------------------------------------------------------------------------
-(id) delegate
{
return delegate;
}
// -----------------------------------------------------------------------------
// setDelegate:
// Mutator for file watcher delegate.
// -----------------------------------------------------------------------------
-(void) setDelegate: (id)newDelegate
{
delegate = newDelegate;
}
@end
// -----------------------------------------------------------------------------
// UKFileSubscriptionProc:
// Callback function we hand to Carbon so it can tell us when something
// changed about our watched folders. We set the refcon to a pointer to
// our object. This simply extracts the object and hands the info off to
// sendDelegateMessage:forSubscription: which does the actual work.
// -----------------------------------------------------------------------------
void UKFileSubscriptionProc( FNMessage message, OptionBits flags, void *refcon, FNSubscriptionRef subscription )
{
UKFNSubscribeFileWatcher* obj = (UKFNSubscribeFileWatcher*) refcon;
if( message == kFNDirectoryModifiedMessage ) // No others exist as of 10.4
[obj sendDelegateMessage: message forSubscription: subscription];
else
NSLog( @"UKFileSubscriptionProc: Unknown message %d", message );
}

View File

@@ -1,62 +0,0 @@
/* =============================================================================
FILE: UKFileWatcher.h
PROJECT: Filie
COPYRIGHT: (c) 2005 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT License
REVISIONS:
2006-03-13 UK Moved notification constants to .m file.
2005-02-25 UK Created.
========================================================================== */
/*
This is a protocol that file change notification classes should adopt.
That way, no matter whether you use Carbon's FNNotify/FNSubscribe, BSD's
kqueue or whatever, the object being notified can react to change
notifications the same way, and you can easily swap one out for the other
to cater to different OS versions, target volumes etc.
*/
// -----------------------------------------------------------------------------
// Protocol:
// -----------------------------------------------------------------------------
@protocol UKFileWatcher
// +(id) sharedFileWatcher; // Singleton accessor. Not officially part of the protocol, but use this name if you provide a singleton.
-(void) addPath: (NSString*)path;
-(void) removePath: (NSString*)path;
-(id) delegate;
-(void) setDelegate: (id)newDelegate;
@end
// -----------------------------------------------------------------------------
// Methods delegates need to provide:
// -----------------------------------------------------------------------------
@interface NSObject (UKFileWatcherDelegate)
-(void) watcher: (id<UKFileWatcher>)kq receivedNotification: (NSString*)nm forPath: (NSString*)fpath;
@end
// Notifications this sends:
/* object = the file watcher object
userInfo.path = file path watched
These notifications are sent via the NSWorkspace notification center */
extern NSString* UKFileWatcherRenameNotification;
extern NSString* UKFileWatcherWriteNotification;
extern NSString* UKFileWatcherDeleteNotification;
extern NSString* UKFileWatcherAttributeChangeNotification;
extern NSString* UKFileWatcherSizeIncreaseNotification;
extern NSString* UKFileWatcherLinkCountChangeNotification;
extern NSString* UKFileWatcherAccessRevocationNotification;

View File

@@ -1,38 +0,0 @@
/* =============================================================================
FILE: UKKQueue.m
PROJECT: Filie
COPYRIGHT: (c) 2005-06 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT License
REVISIONS:
2006-03-13 UK Created, moved notification constants here as exportable
symbols.
========================================================================== */
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import <Cocoa/Cocoa.h>
#import "UKFileWatcher.h"
// -----------------------------------------------------------------------------
// Constants:
// -----------------------------------------------------------------------------
// Do not rely on the actual contents of these constants. They will eventually
// be changed to be more generic and less KQueue-specific.
NSString* UKFileWatcherRenameNotification = @"UKKQueueFileRenamedNotification";
NSString* UKFileWatcherWriteNotification = @"UKKQueueFileWrittenToNotification";
NSString* UKFileWatcherDeleteNotification = @"UKKQueueFileDeletedNotification";
NSString* UKFileWatcherAttributeChangeNotification = @"UKKQueueFileAttributesChangedNotification";
NSString* UKFileWatcherSizeIncreaseNotification = @"UKKQueueFileSizeIncreasedNotification";
NSString* UKFileWatcherLinkCountChangeNotification = @"UKKQueueFileLinkCountChangedNotification";
NSString* UKFileWatcherAccessRevocationNotification = @"UKKQueueFileAccessRevocationNotification";

View File

@@ -1,122 +0,0 @@
/* =============================================================================
FILE: UKKQueue.h
PROJECT: Filie
COPYRIGHT: (c) 2003 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT License
REVISIONS:
2006-03-13 UK Clarified license, streamlined UKFileWatcher stuff,
Changed notifications to be useful and turned off by
default some deprecated stuff.
2003-12-21 UK Created.
========================================================================== */
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import <Foundation/Foundation.h>
#include <sys/types.h>
#include <sys/event.h>
#import "UKFileWatcher.h"
// -----------------------------------------------------------------------------
// Constants:
// -----------------------------------------------------------------------------
// Backwards compatibility constants. Don't rely on code commented out with these constants, because it may be deleted in a future version.
#ifndef UKKQUEUE_BACKWARDS_COMPATIBLE
#define UKKQUEUE_BACKWARDS_COMPATIBLE 0 // 1 to send old-style kqueue:receivedNotification:forFile: messages to objects that accept them.
#endif
#ifndef UKKQUEUE_SEND_STUPID_NOTIFICATIONS
#define UKKQUEUE_SEND_STUPID_NOTIFICATIONS 0 // 1 to send old-style notifications that have the path as the object and no userInfo dictionary.
#endif
#ifndef UKKQUEUE_OLD_SINGLETON_ACCESSOR_NAME
#define UKKQUEUE_OLD_SINGLETON_ACCESSOR_NAME 0 // 1 to allow use of sharedQueue instead of sharedFileWatcher.
#endif
#ifndef UKKQUEUE_OLD_NOTIFICATION_NAMES
#define UKKQUEUE_OLD_NOTIFICATION_NAMES 0 // 1 to allow use of old KQueue-style notification names instead of the new more generic ones in UKFileWatcher.
#endif
// Flags for notifyingAbout:
#define UKKQueueNotifyAboutRename NOTE_RENAME // Item was renamed.
#define UKKQueueNotifyAboutWrite NOTE_WRITE // Item contents changed (also folder contents changed).
#define UKKQueueNotifyAboutDelete NOTE_DELETE // item was removed.
#define UKKQueueNotifyAboutAttributeChange NOTE_ATTRIB // Item attributes changed.
#define UKKQueueNotifyAboutSizeIncrease NOTE_EXTEND // Item size increased.
#define UKKQueueNotifyAboutLinkCountChanged NOTE_LINK // Item's link count changed.
#define UKKQueueNotifyAboutAccessRevocation NOTE_REVOKE // Access to item was revoked.
// Notifications this sends:
// (see UKFileWatcher)
// Old names: *deprecated*
#if UKKQUEUE_OLD_NOTIFICATION_NAMES
#define UKKQueueFileRenamedNotification UKFileWatcherRenameNotification
#define UKKQueueFileWrittenToNotification UKFileWatcherWriteNotification
#define UKKQueueFileDeletedNotification UKFileWatcherDeleteNotification
#define UKKQueueFileAttributesChangedNotification UKFileWatcherAttributeChangeNotification
#define UKKQueueFileSizeIncreasedNotification UKFileWatcherSizeIncreaseNotification
#define UKKQueueFileLinkCountChangedNotification UKFileWatcherLinkCountChangeNotification
#define UKKQueueFileAccessRevocationNotification UKFileWatcherAccessRevocationNotification
#endif
// -----------------------------------------------------------------------------
// UKKQueue:
// -----------------------------------------------------------------------------
@interface UKKQueue : NSObject <UKFileWatcher>
{
int queueFD; // The actual queue ID (Unix file descriptor).
NSMutableArray* watchedPaths; // List of NSStrings containing the paths we're watching.
NSMutableArray* watchedFDs; // List of NSNumbers containing the file descriptors we're watching.
id delegate; // Gets messages about changes instead of notification center, if specified.
id delegateProxy; // Proxy object to which we send messages so they reach delegate on the main thread.
BOOL alwaysNotify; // Send notifications even if we have a delegate? Defaults to NO.
BOOL keepThreadRunning; // Termination criterion of our thread.
}
+(id) sharedFileWatcher; // Returns a singleton, a shared kqueue object Handy if you're subscribing to the notifications. Use this, or just create separate objects using alloc/init. Whatever floats your boat.
-(int) queueFD; // I know you unix geeks want this...
// High-level file watching: (use UKFileWatcher protocol methods instead, where possible!)
-(void) addPathToQueue: (NSString*)path;
-(void) addPathToQueue: (NSString*)path notifyingAbout: (u_int)fflags;
-(void) removePathFromQueue: (NSString*)path;
-(id) delegate;
-(void) setDelegate: (id)newDelegate;
-(BOOL) alwaysNotify;
-(void) setAlwaysNotify: (BOOL)n;
#if UKKQUEUE_OLD_SINGLETON_ACCESSOR_NAME
+(UKKQueue*) sharedQueue;
#endif
// private:
-(void) watcherThread: (id)sender;
-(void) postNotification: (NSString*)nm forFile: (NSString*)fp; // Message-posting bottleneck.
@end
// -----------------------------------------------------------------------------
// Methods delegates need to provide:
// * DEPRECATED * use UKFileWatcher delegate methods instead!
// -----------------------------------------------------------------------------
@interface NSObject (UKKQueueDelegate)
-(void) kqueue: (UKKQueue*)kq receivedNotification: (NSString*)nm forFile: (NSString*)fpath;
@end

View File

@@ -1,501 +0,0 @@
/* =============================================================================
FILE: UKKQueue.m
PROJECT: Filie
COPYRIGHT: (c) 2003 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT License
REVISIONS:
2006-03-13 UK Clarified license, streamlined UKFileWatcher stuff,
Changed notifications to be useful and turned off by
default some deprecated stuff.
2004-12-28 UK Several threading fixes.
2003-12-21 UK Created.
========================================================================== */
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import "UKKQueue.h"
#import "UKMainThreadProxy.h"
#import <unistd.h>
#import <fcntl.h>
#import <sys/param.h>
// -----------------------------------------------------------------------------
// Macros:
// -----------------------------------------------------------------------------
// @synchronized isn't available prior to 10.3, so we use a typedef so
// this class is thread-safe on Panther but still compiles on older OSs.
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
#define AT_SYNCHRONIZED(n) @synchronized(n)
#else
#define AT_SYNCHRONIZED(n)
#endif
// -----------------------------------------------------------------------------
// Globals:
// -----------------------------------------------------------------------------
static UKKQueue * gUKKQueueSharedQueueSingleton = nil;
@implementation UKKQueue
// Deprecated:
#if UKKQUEUE_OLD_SINGLETON_ACCESSOR_NAME
+(UKKQueue*) sharedQueue
{
return [self sharedFileWatcher];
}
#endif
// -----------------------------------------------------------------------------
// sharedQueue:
// Returns a singleton queue object. In many apps (especially those that
// subscribe to the notifications) there will only be one kqueue instance,
// and in that case you can use this.
//
// For all other cases, feel free to create additional instances to use
// independently.
//
// REVISIONS:
// 2006-03-13 UK Renamed from sharedQueue.
// 2005-07-02 UK Created.
// -----------------------------------------------------------------------------
+(id) sharedFileWatcher
{
AT_SYNCHRONIZED( self )
{
if( !gUKKQueueSharedQueueSingleton )
gUKKQueueSharedQueueSingleton = [[UKKQueue alloc] init]; // This is a singleton, and thus an intentional "leak".
}
return gUKKQueueSharedQueueSingleton;
}
// -----------------------------------------------------------------------------
// * CONSTRUCTOR:
// Creates a new KQueue and starts that thread we use for our
// notifications.
//
// REVISIONS:
// 2004-11-12 UK Doesn't pass self as parameter to watcherThread anymore,
// because detachNewThreadSelector retains target and args,
// which would cause us to never be released.
// 2004-03-13 UK Documented.
// -----------------------------------------------------------------------------
-(id) init
{
self = [super init];
if( self )
{
queueFD = kqueue();
if( queueFD == -1 )
{
[self release];
return nil;
}
watchedPaths = [[NSMutableArray alloc] init];
watchedFDs = [[NSMutableArray alloc] init];
// Start new thread that fetches and processes our events:
keepThreadRunning = YES;
[NSThread detachNewThreadSelector:@selector(watcherThread:) toTarget:self withObject:nil];
}
return self;
}
// -----------------------------------------------------------------------------
// release:
// Since NSThread retains its target, we need this method to terminate the
// thread when we reach a retain-count of two. The thread is terminated by
// setting keepThreadRunning to NO.
//
// REVISIONS:
// 2004-11-12 UK Created.
// -----------------------------------------------------------------------------
-(oneway void) release
{
AT_SYNCHRONIZED(self)
{
//NSLog(@"%@ (%d)", self, [self retainCount]);
if( [self retainCount] == 2 && keepThreadRunning )
keepThreadRunning = NO;
}
[super release];
}
// -----------------------------------------------------------------------------
// * DESTRUCTOR:
// Releases the kqueue again.
//
// REVISIONS:
// 2004-03-13 UK Documented.
// -----------------------------------------------------------------------------
-(void) dealloc
{
delegate = nil;
[delegateProxy release];
if( keepThreadRunning )
keepThreadRunning = NO;
// Close all our file descriptors so the files can be deleted:
NSEnumerator* enny = [watchedFDs objectEnumerator];
NSNumber* fdNum;
while( (fdNum = [enny nextObject]) )
{
if( close( [fdNum intValue] ) == -1 )
NSLog(@"dealloc: Couldn't close file descriptor (%d)", errno);
}
[watchedPaths release];
watchedPaths = nil;
[watchedFDs release];
watchedFDs = nil;
[super dealloc];
//NSLog(@"kqueue released.");
}
// -----------------------------------------------------------------------------
// queueFD:
// Returns a Unix file descriptor for the KQueue this uses. The descriptor
// is owned by this object. Do not close it!
//
// REVISIONS:
// 2004-03-13 UK Documented.
// -----------------------------------------------------------------------------
-(int) queueFD
{
return queueFD;
}
// -----------------------------------------------------------------------------
// addPathToQueue:
// Tell this queue to listen for all interesting notifications sent for
// the object at the specified path. If you want more control, use the
// addPathToQueue:notifyingAbout: variant instead.
//
// REVISIONS:
// 2004-03-13 UK Documented.
// -----------------------------------------------------------------------------
-(void) addPathToQueue: (NSString*)path
{
[self addPath: path];
}
-(void) addPath: (NSString*)path
{
[self addPathToQueue: path notifyingAbout: UKKQueueNotifyAboutRename
| UKKQueueNotifyAboutWrite
| UKKQueueNotifyAboutDelete
| UKKQueueNotifyAboutAttributeChange];
}
// -----------------------------------------------------------------------------
// addPathToQueue:notfyingAbout:
// Tell this queue to listen for the specified notifications sent for
// the object at the specified path.
//
// REVISIONS:
// 2005-06-29 UK Files are now opened using O_EVTONLY instead of O_RDONLY
// which allows ejecting or deleting watched files/folders.
// Thanks to Phil Hargett for finding this flag in the docs.
// 2004-03-13 UK Documented.
// -----------------------------------------------------------------------------
-(void) addPathToQueue: (NSString*)path notifyingAbout: (u_int)fflags
{
struct timespec nullts = { 0, 0 };
struct kevent ev;
int fd = open( [path fileSystemRepresentation], O_EVTONLY, 0 );
if( fd >= 0 )
{
EV_SET( &ev, fd, EVFILT_VNODE,
EV_ADD | EV_ENABLE | EV_CLEAR,
fflags, 0, (void*)path );
AT_SYNCHRONIZED( self )
{
[watchedPaths addObject: path];
[watchedFDs addObject: [NSNumber numberWithInt: fd]];
kevent( queueFD, &ev, 1, NULL, 0, &nullts );
}
}
}
-(void) removePath: (NSString*)path
{
[self removePathFromQueue: path];
}
// -----------------------------------------------------------------------------
// removePathFromQueue:
// Stop listening for changes to the specified path. This removes all
// notifications. Use this to balance both addPathToQueue:notfyingAbout:
// as well as addPathToQueue:.
//
// REVISIONS:
// 2004-03-13 UK Documented.
// -----------------------------------------------------------------------------
-(void) removePathFromQueue: (NSString*)path
{
NSUInteger index = 0;
int fd = -1;
AT_SYNCHRONIZED( self )
{
index = [watchedPaths indexOfObject: path];
if( index == NSNotFound )
return;
fd = [[watchedFDs objectAtIndex: index] intValue];
[watchedFDs removeObjectAtIndex: index];
[watchedPaths removeObjectAtIndex: index];
}
if( close( fd ) == -1 )
NSLog(@"removePathFromQueue: Couldn't close file descriptor (%d)", errno);
}
// -----------------------------------------------------------------------------
// removeAllPathsFromQueue:
// Stop listening for changes to all paths. This removes all
// notifications.
//
// REVISIONS:
// 2004-12-28 UK Added as suggested by bbum.
// -----------------------------------------------------------------------------
-(void) removeAllPathsFromQueue;
{
AT_SYNCHRONIZED( self )
{
NSEnumerator * fdEnumerator = [watchedFDs objectEnumerator];
NSNumber * anFD;
while( (anFD = [fdEnumerator nextObject]) != nil )
close( [anFD intValue] );
[watchedFDs removeAllObjects];
[watchedPaths removeAllObjects];
}
}
// -----------------------------------------------------------------------------
// watcherThread:
// This method is called by our NSThread to loop and poll for any file
// changes that our kqueue wants to tell us about. This sends separate
// notifications for the different kinds of changes that can happen.
// All messages are sent via the postNotification:forFile: main bottleneck.
//
// This also calls sharedWorkspace's noteFileSystemChanged.
//
// To terminate this method (and its thread), set keepThreadRunning to NO.
//
// REVISIONS:
// 2005-08-27 UK Changed to use keepThreadRunning instead of kqueueFD
// being -1 as termination criterion, and to close the
// queue in this thread so the main thread isn't blocked.
// 2004-11-12 UK Fixed docs to include termination criterion, added
// timeout to make sure the bugger gets disposed.
// 2004-03-13 UK Documented.
// -----------------------------------------------------------------------------
-(void) watcherThread: (id)sender
{
int n;
struct kevent ev;
struct timespec timeout = { 5, 0 }; // 5 seconds timeout.
int theFD = queueFD; // So we don't have to risk accessing iVars when the thread is terminated.
while( keepThreadRunning )
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NS_DURING
n = kevent( queueFD, NULL, 0, &ev, 1, &timeout );
if( n > 0 )
{
if( ev.filter == EVFILT_VNODE )
{
if( ev.fflags )
{
NSString* fpath = [[(NSString *)ev.udata retain] autorelease]; // In case one of the notified folks removes the path.
//NSLog(@"UKKQueue: Detected file change: %@", fpath);
[[NSWorkspace sharedWorkspace] noteFileSystemChanged: fpath];
//NSLog(@"ev.flags = %u",ev.fflags); // DEBUG ONLY!
if( (ev.fflags & NOTE_RENAME) == NOTE_RENAME ) {
char path[MAXPATHLEN];
fcntl((int)ev.ident, F_GETPATH, &path);
[self postNotification: UKFileWatcherRenameNotification forFile: [NSString stringWithUTF8String:path]];
}
if( (ev.fflags & NOTE_WRITE) == NOTE_WRITE ) {
[self postNotification: UKFileWatcherWriteNotification forFile: fpath];
}
if( (ev.fflags & NOTE_DELETE) == NOTE_DELETE ) {
[self removePathFromQueue:fpath];
int newFD = open( [fpath fileSystemRepresentation], O_EVTONLY, 0 );
if (newFD == -1) {
// It's really a delete
[self postNotification: UKFileWatcherDeleteNotification forFile: fpath];
}
else {
// Probably an atomic write, readd to the queue.
close(newFD);
[self addPathToQueue:fpath];
[self postNotification: UKFileWatcherWriteNotification forFile: fpath];
[self postNotification: UKFileWatcherAttributeChangeNotification forFile: fpath];
}
}
if( (ev.fflags & NOTE_ATTRIB) == NOTE_ATTRIB ) {
[self postNotification: UKFileWatcherAttributeChangeNotification forFile: fpath];
}
if( (ev.fflags & NOTE_EXTEND) == NOTE_EXTEND ) {
[self postNotification: UKFileWatcherSizeIncreaseNotification forFile: fpath];
}
if( (ev.fflags & NOTE_LINK) == NOTE_LINK ) {
[self postNotification: UKFileWatcherLinkCountChangeNotification forFile: fpath];
}
if( (ev.fflags & NOTE_REVOKE) == NOTE_REVOKE ) {
[self postNotification: UKFileWatcherAccessRevocationNotification forFile: fpath];
}
}
}
}
NS_HANDLER
NSLog(@"Error in UKKQueue watcherThread: %@",localException);
NS_ENDHANDLER
[pool release];
}
// Close our kqueue's file descriptor:
if( close( theFD ) == -1 )
NSLog(@"release: Couldn't close main kqueue (%d)", errno);
//NSLog(@"exiting kqueue watcher thread.");
}
// -----------------------------------------------------------------------------
// postNotification:forFile:
// This is the main bottleneck for posting notifications. If you don't want
// the notifications to go through NSWorkspace, override this method and
// send them elsewhere.
//
// REVISIONS:
// 2004-02-27 UK Changed this to send new notification, and the old one
// only to objects that respond to it. The old category on
// NSObject could cause problems with the proxy itself.
// 2004-10-31 UK Helloween fun: Make this use a mainThreadProxy and
// allow sending the notification even if we have a
// delegate.
// 2004-03-13 UK Documented.
// -----------------------------------------------------------------------------
-(void) postNotification: (NSString*)nm forFile: (NSString*)fp
{
if( delegateProxy )
{
#if UKKQUEUE_BACKWARDS_COMPATIBLE
if( ![delegateProxy respondsToSelector: @selector(watcher:receivedNotification:forPath:)] )
[delegateProxy kqueue: self receivedNotification: nm forFile: fp];
else
#endif
[delegateProxy watcher: self receivedNotification: nm forPath: fp];
}
if( !delegateProxy || alwaysNotify )
{
#if UKKQUEUE_SEND_STUPID_NOTIFICATIONS
[[[NSWorkspace sharedWorkspace] notificationCenter] postNotificationName: nm object: fp];
#else
[[[NSWorkspace sharedWorkspace] notificationCenter] postNotificationName: nm object: self
userInfo: [NSDictionary dictionaryWithObjectsAndKeys: fp, @"path", nil]];
#endif
}
}
-(id) delegate
{
return delegate;
}
-(void) setDelegate: (id)newDelegate
{
id oldProxy = delegateProxy;
delegate = newDelegate;
delegateProxy = [delegate copyMainThreadProxy];
[oldProxy release];
}
// -----------------------------------------------------------------------------
// Flag to send a notification even if we have a delegate:
// -----------------------------------------------------------------------------
-(BOOL) alwaysNotify
{
return alwaysNotify;
}
-(void) setAlwaysNotify: (BOOL)n
{
alwaysNotify = n;
}
// -----------------------------------------------------------------------------
// description:
// This method can be used to help in debugging. It provides the value
// used by NSLog & co. when you request to print this object using the
// %@ format specifier.
//
// REVISIONS:
// 2004-11-12 UK Created.
// -----------------------------------------------------------------------------
-(NSString*) description
{
return [NSString stringWithFormat: @"%@ { watchedPaths = %@, alwaysNotify = %@ }", NSStringFromClass([self class]), watchedPaths, (alwaysNotify? @"YES" : @"NO") ];
}
@end

View File

@@ -1,56 +0,0 @@
/* =============================================================================
FILE: UKMainThreadProxy.h
PROJECT: UKMainThreadProxy
PURPOSE: Send a message to object theObject to [theObject mainThreadProxy]
instead and the message will be received on the main thread by
theObject.
COPYRIGHT: (c) 2004 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT License
REVISIONS:
2006-03-13 UK Clarified license.
2004-10-14 UK Created.
========================================================================== */
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import <Cocoa/Cocoa.h>
// -----------------------------------------------------------------------------
// Categories:
// -----------------------------------------------------------------------------
@interface NSObject (UKMainThreadProxy)
-(id) mainThreadProxy; // You can't init or release this object.
-(id) copyMainThreadProxy; // Gives you a retained version.
@end
// -----------------------------------------------------------------------------
// Classes:
// -----------------------------------------------------------------------------
/*
This object is created as a proxy in a second thread for an existing object.
All messages you send to this object will automatically be sent to the other
object on the main thread, except NSObject methods like retain/release etc.
*/
@interface UKMainThreadProxy : NSObject
{
IBOutlet id target;
}
-(id) initWithTarget: (id)targ;
@end

View File

@@ -1,151 +0,0 @@
/* =============================================================================
FILE: UKMainThreadProxy.h
PROJECT: UKMainThreadProxy
PURPOSE: Send a message to object theObject to [theObject mainThreadProxy]
instead and the message will be received on the main thread by
theObject.
COPYRIGHT: (c) 2004 M. Uli Kusterer, all rights reserved.
AUTHORS: M. Uli Kusterer - UK
LICENSES: MIT Licenseâ
REVISIONS:
2006-03-13 UK Clarified license.
2004-10-14 UK Created.
========================================================================== */
// -----------------------------------------------------------------------------
// Headers:
// -----------------------------------------------------------------------------
#import "UKMainThreadProxy.h"
@implementation UKMainThreadProxy
-(id) initWithTarget: (id)targ
{
self = [super init];
if( self )
target = targ;
return self;
}
// -----------------------------------------------------------------------------
// Introspection overrides:
// -----------------------------------------------------------------------------
-(BOOL) respondsToSelector: (SEL)itemAction
{
BOOL does = [super respondsToSelector: itemAction];
return( does || [target respondsToSelector: itemAction] );
}
-(id) performSelector: (SEL)itemAction
{
BOOL does = [super respondsToSelector: itemAction];
if( does )
return [super performSelector: itemAction];
if( ![target respondsToSelector: itemAction] )
[self doesNotRecognizeSelector: itemAction];
[target retain];
[target performSelectorOnMainThread: itemAction withObject: nil waitUntilDone: YES];
[target release];
return nil;
}
-(id) performSelector: (SEL)itemAction withObject: (id)obj
{
BOOL does = [super respondsToSelector: itemAction];
if( does )
return [super performSelector: itemAction withObject: obj];
if( ![target respondsToSelector: itemAction] )
[self doesNotRecognizeSelector: itemAction];
[target retain];
[obj retain];
[target performSelectorOnMainThread: itemAction withObject: obj waitUntilDone: YES];
[obj release];
[target release];
return nil;
}
// -----------------------------------------------------------------------------
// Forwarding unknown methods to the target:
// -----------------------------------------------------------------------------
-(NSMethodSignature*) methodSignatureForSelector: (SEL)itemAction
{
NSMethodSignature* sig = [super methodSignatureForSelector: itemAction];
if( sig )
return sig;
return [target methodSignatureForSelector: itemAction];
}
-(void) forwardInvocation: (NSInvocation*)invocation
{
SEL itemAction = [invocation selector];
if( [target respondsToSelector: itemAction] )
{
[invocation retainArguments];
[target retain];
[invocation performSelectorOnMainThread: @selector(invokeWithTarget:) withObject: target waitUntilDone: YES];
[target release];
}
else
[self doesNotRecognizeSelector: itemAction];
}
// -----------------------------------------------------------------------------
// Safety net:
// -----------------------------------------------------------------------------
-(id) mainThreadProxy // Just in case someone accidentally sends this message to a main thread proxy.
{
return self;
}
-(id) copyMainThreadProxy // Just in case someone accidentally sends this message to a main thread proxy.
{
return [self retain];
}
@end
// -----------------------------------------------------------------------------
// Shorthand notation for getting a main thread proxy:
// -----------------------------------------------------------------------------
@implementation NSObject (UKMainThreadProxy)
-(id) mainThreadProxy
{
return [[[UKMainThreadProxy alloc] initWithTarget: self] autorelease];
}
-(id) copyMainThreadProxy
{
return [[UKMainThreadProxy alloc] initWithTarget: self];
}
@end

View File

@@ -1,2 +0,0 @@
/* Localized versions of Info.plist keys */

View File

@@ -1,380 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1070</int>
<string key="IBDocument.SystemVersion">11C74</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
<string key="IBDocument.AppKitVersion">1138.23</string>
<string key="IBDocument.HIToolboxVersion">567.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">1938</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>NSMenu</string>
<string>NSMenuItem</string>
<string>NSCustomObject</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
<object class="NSCustomObject" id="1021">
<string key="NSClassName">AtomApp</string>
</object>
<object class="NSCustomObject" id="1014">
<string key="NSClassName">FirstResponder</string>
</object>
<object class="NSCustomObject" id="1050">
<string key="NSClassName">AtomApp</string>
</object>
<object class="NSMenu" id="649796088">
<string key="NSTitle">AMainMenu</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="694149608">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">Atom</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<object class="NSCustomResource" key="NSOnImage" id="35465992">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSMenuCheckmark</string>
</object>
<object class="NSCustomResource" key="NSMixedImage" id="502551668">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSMenuMixedState</string>
</object>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="110575045">
<string key="NSTitle">Atom</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="208934156">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Run Specs</string>
<string key="NSKeyEquiv">s</string>
<int key="NSKeyEquivModMask">1835008</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="632727374">
<reference key="NSMenu" ref="110575045"/>
<string key="NSTitle">Quit Atom</string>
<string key="NSKeyEquiv">q</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
</array>
<string key="NSName">_NSAppleMenu</string>
</object>
</object>
<object class="NSMenuItem" id="379814623">
<reference key="NSMenu" ref="649796088"/>
<string key="NSTitle">File</string>
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="720053764">
<string key="NSTitle">File</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="705341025">
<reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">New</string>
<string key="NSKeyEquiv">n</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
<object class="NSMenuItem" id="722745758">
<reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Open…</string>
<string key="NSKeyEquiv">o</string>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="35465992"/>
<reference key="NSMixedImage" ref="502551668"/>
</object>
</array>
</object>
</object>
</array>
<string key="NSName">_NSMainMenu</string>
</object>
<object class="NSCustomObject" id="755631768">
<string key="NSClassName">NSFontManager</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">terminate:</string>
<reference key="source" ref="1050"/>
<reference key="destination" ref="632727374"/>
</object>
<int key="connectionID">449</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="1050"/>
</object>
<int key="connectionID">536</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">runSpecs:</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="208934156"/>
</object>
<int key="connectionID">541</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">openNewWindow:</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="705341025"/>
</object>
<int key="connectionID">545</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">openPathInNewWindow:</string>
<reference key="source" ref="1021"/>
<reference key="destination" ref="722745758"/>
</object>
<int key="connectionID">547</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1048"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="1021"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="1014"/>
<reference key="parent" ref="0"/>
<string key="objectName">First Responder</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-3</int>
<reference key="object" ref="1050"/>
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">29</int>
<reference key="object" ref="649796088"/>
<array class="NSMutableArray" key="children">
<reference ref="694149608"/>
<reference ref="379814623"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">56</int>
<reference key="object" ref="694149608"/>
<array class="NSMutableArray" key="children">
<reference ref="110575045"/>
</array>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">83</int>
<reference key="object" ref="379814623"/>
<array class="NSMutableArray" key="children">
<reference ref="720053764"/>
</array>
<reference key="parent" ref="649796088"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">81</int>
<reference key="object" ref="720053764"/>
<array class="NSMutableArray" key="children">
<reference ref="722745758"/>
<reference ref="705341025"/>
</array>
<reference key="parent" ref="379814623"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">72</int>
<reference key="object" ref="722745758"/>
<reference key="parent" ref="720053764"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">82</int>
<reference key="object" ref="705341025"/>
<reference key="parent" ref="720053764"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">57</int>
<reference key="object" ref="110575045"/>
<array class="NSMutableArray" key="children">
<reference ref="632727374"/>
<reference ref="208934156"/>
</array>
<reference key="parent" ref="694149608"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">136</int>
<reference key="object" ref="632727374"/>
<reference key="parent" ref="110575045"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">420</int>
<reference key="object" ref="755631768"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">537</int>
<reference key="object" ref="208934156"/>
<reference key="parent" ref="110575045"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="136.CustomClassName">AtomMenuItem</string>
<object class="NSMutableDictionary" key="136.IBAttributePlaceholdersKey">
<string key="NS.key.0">IBUserDefinedRuntimeAttributesPlaceholderName</string>
<object class="IBUserDefinedRuntimeAttributesPlaceholder" key="NS.object.0">
<string key="name">IBUserDefinedRuntimeAttributesPlaceholderName</string>
<reference key="object" ref="632727374"/>
<array key="userDefinedRuntimeAttributes">
<object class="IBUserDefinedRuntimeAttribute">
<string key="typeIdentifier">com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.boolean</string>
<string key="keyPath">global</string>
<boolean value="YES" key="value"/>
</object>
</array>
</object>
</object>
<string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="420.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="537.CustomClassName">AtomMenuItem</string>
<object class="NSMutableDictionary" key="537.IBAttributePlaceholdersKey">
<string key="NS.key.0">IBUserDefinedRuntimeAttributesPlaceholderName</string>
<object class="IBUserDefinedRuntimeAttributesPlaceholder" key="NS.object.0">
<string key="name">IBUserDefinedRuntimeAttributesPlaceholderName</string>
<reference key="object" ref="208934156"/>
<array key="userDefinedRuntimeAttributes">
<object class="IBUserDefinedRuntimeAttribute">
<string key="typeIdentifier">com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.boolean</string>
<string key="keyPath">global</string>
<boolean value="YES" key="value"/>
</object>
</array>
</object>
</object>
<string key="537.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="56.CustomClassName">AtomMenuItem</string>
<string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="72.CustomClassName">AtomMenuItem</string>
<object class="NSMutableDictionary" key="72.IBAttributePlaceholdersKey">
<string key="NS.key.0">IBUserDefinedRuntimeAttributesPlaceholderName</string>
<object class="IBUserDefinedRuntimeAttributesPlaceholder" key="NS.object.0">
<string key="name">IBUserDefinedRuntimeAttributesPlaceholderName</string>
<reference key="object" ref="722745758"/>
<array key="userDefinedRuntimeAttributes">
<object class="IBUserDefinedRuntimeAttribute">
<string key="typeIdentifier">com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.boolean</string>
<string key="keyPath">global</string>
<boolean value="YES" key="value"/>
</object>
</array>
</object>
</object>
<string key="72.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="81.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="82.CustomClassName">AtomMenuItem</string>
<object class="NSMutableDictionary" key="82.IBAttributePlaceholdersKey">
<string key="NS.key.0">IBUserDefinedRuntimeAttributesPlaceholderName</string>
<object class="IBUserDefinedRuntimeAttributesPlaceholder" key="NS.object.0">
<string key="name">IBUserDefinedRuntimeAttributesPlaceholderName</string>
<reference key="object" ref="705341025"/>
<array key="userDefinedRuntimeAttributes">
<object class="IBUserDefinedRuntimeAttribute">
<string key="typeIdentifier">com.apple.InterfaceBuilder.userDefinedRuntimeAttributeType.boolean</string>
<string key="keyPath">global</string>
<boolean value="YES" key="value"/>
</object>
</array>
</object>
</object>
<string key="82.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="83.CustomClassName">AtomMenuItem</string>
<string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">547</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">AtomApp</string>
<string key="superclassName">NSApplication</string>
<object class="NSMutableDictionary" key="actions">
<string key="NS.key.0">runSpecs:</string>
<string key="NS.object.0">id</string>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<string key="NS.key.0">runSpecs:</string>
<object class="IBActionInfo" key="NS.object.0">
<string key="name">runSpecs:</string>
<string key="candidateClassName">id</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/AtomApp.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">AtomMenuItem</string>
<string key="superclassName">NSMenuItem</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/AtomMenuItem.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<string key="NSMenuCheckmark">{9, 8}</string>
<string key="NSMenuMixedState">{7, 2}</string>
</dictionary>
</data>
</archive>

View File

@@ -1,14 +0,0 @@
//
// main.m
// Atom
//
// Created by Corey Johnson on 10/25/11.
// Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}

View File

Before

Width:  |  Height:  |  Size: 752 B

After

Width:  |  Height:  |  Size: 752 B

View File

Before

Width:  |  Height:  |  Size: 183 B

After

Width:  |  Height:  |  Size: 183 B

BIN
Atom/resources/chrome.pak Executable file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 523 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
Atom/resources/deleteButton.tiff Executable file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 123 B

After

Width:  |  Height:  |  Size: 123 B

View File

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 239 B

After

Width:  |  Height:  |  Size: 239 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
Atom/resources/inputSpeech.tiff Executable file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 341 B

After

Width:  |  Height:  |  Size: 341 B

View File

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 411 B

BIN
Atom/resources/missingImage.tiff Executable file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 175 B

After

Width:  |  Height:  |  Size: 175 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 90 B

After

Width:  |  Height:  |  Size: 90 B

View File

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 209 B

View File

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

View File

Before

Width:  |  Height:  |  Size: 125 B

After

Width:  |  Height:  |  Size: 125 B

View File

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 144 B

View File

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 174 B

View File

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 193 B

BIN
Atom/resources/nullPlugin.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
Atom/resources/nullPlugin@2x.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
Atom/resources/panIcon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 166 B

View File

Before

Width:  |  Height:  |  Size: 128 B

After

Width:  |  Height:  |  Size: 128 B

View File

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 177 B

View File

Before

Width:  |  Height:  |  Size: 146 B

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
Atom/resources/urlIcon.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 819 B

View File

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 120 B

View File

Before

Width:  |  Height:  |  Size: 125 B

After

Width:  |  Height:  |  Size: 125 B

View File

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 122 B

View File

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 199 B

View File

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 182 B

21
Atom/src/Atom.h Executable file
View File

@@ -0,0 +1,21 @@
#import "BrowserDelegate.h"
#import "include/cef.h"
#import "include/cef_application_mac.h"
class ClientHandler;
@class AtomController;
@interface Atom : NSApplication<CefAppProtocol, BrowserDelegate> {
NSWindow *_hiddenWindow;
BOOL handlingSendEvent_;
CefRefPtr<ClientHandler> _clientHandler;
}
- (void)open:(NSString *)path;
- (IBAction)runSpecs:(id)sender;
@end
// Returns the application settings based on command line arguments.
void AppGetSettings(CefSettings& settings);

120
Atom/src/Atom.mm Executable file
View File

@@ -0,0 +1,120 @@
#import "Atom.h"
#import "include/cef.h"
#import "AtomController.h"
#import "native_handler.h"
#import "client_handler.h"
// Provide the CefAppProtocol implementation required by CEF.
@implementation Atom
+ (NSApplication *)sharedApplication {
if (!NSApp) {
// Populate the settings based on command line arguments.
CefSettings settings;
AppGetSettings(settings);
// Initialize CEF.
CefRefPtr<CefApp> app;
CefInitialize(settings, app);
}
return [super sharedApplication];
}
- (void)dealloc {
[_hiddenWindow release];
[self dealloc];
}
- (BOOL)isHandlingSendEvent {
return handlingSendEvent_;
}
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
handlingSendEvent_ = handlingSendEvent;
}
- (void)sendEvent:(NSEvent*)event {
CefScopedSendingEvent sendingEventScoper;
if ([[self mainMenu] performKeyEquivalent:event]) return;
if (_clientHandler && ![self keyWindow] && [event type] == NSKeyDown) {
[_hiddenWindow makeKeyAndOrderFront:self];
[_hiddenWindow sendEvent:event];
}
else {
[super sendEvent:event];
}
}
- (void)createAtomContext {
_clientHandler = new ClientHandler(self);
CefWindowInfo window_info;
_hiddenWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 0, 0) styleMask:nil backing:nil defer:YES];
window_info.SetAsChild([_hiddenWindow contentView], 0, 0, 0, 0);
CefBrowserSettings settings;
NSURL *resourceDirURL = [[NSBundle mainBundle] resourceURL];
NSString *indexURLString = [[resourceDirURL URLByAppendingPathComponent:@"index.html"] absoluteString];
CefBrowser::CreateBrowser(window_info, _clientHandler.get(), [indexURLString UTF8String], settings);
}
- (void)open:(NSString *)path {
CefRefPtr<CefV8Context> atomContext = _clientHandler->GetBrowser()->GetMainFrame()->GetV8Context();
[[AtomController alloc] initWithPath:path atomContext:atomContext];
}
- (IBAction)runSpecs:(id)sender {
CefRefPtr<CefV8Context> atomContext = _clientHandler->GetBrowser()->GetMainFrame()->GetV8Context();
[[AtomController alloc] initSpecsWithAtomContext:atomContext];
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
[self createAtomContext];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
CefShutdown();
}
#pragma mark BrowserDelegate
- (void)loadStart {
CefRefPtr<CefV8Context> context = _clientHandler->GetBrowser()->GetMainFrame()->GetV8Context();
CefRefPtr<CefV8Value> global = context->GetGlobal();
context->Enter();
CefRefPtr<CefV8Value> bootstrapScript = CefV8Value::CreateString("atom-bootstrap");
global->SetValue("$bootstrapScript", bootstrapScript, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<NativeHandler> nativeHandler = new NativeHandler();
global->SetValue("$native", nativeHandler->m_object, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<CefV8Value> atom = CefV8Value::CreateObject(NULL);
global->SetValue("atom", atom, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<CefV8Value> loadPath = CefV8Value::CreateString(PROJECT_DIR);
atom->SetValue("loadPath", loadPath, V8_PROPERTY_ATTRIBUTE_NONE);
context->Exit();
}
@end
// Returns the application settings based on command line arguments.
void AppGetSettings(CefSettings& settings) {
CefString(&settings.cache_path) = "";
CefString(&settings.user_agent) = "";
CefString(&settings.product_version) = "";
CefString(&settings.locale) = "";
CefString(&settings.log_file) = "";
CefString(&settings.javascript_flags) = "";
settings.log_severity = LOGSEVERITY_ERROR;
settings.local_storage_quota = 0;
settings.session_storage_quota = 0;
}

28
Atom/src/AtomController.h Normal file
View File

@@ -0,0 +1,28 @@
#import <Cocoa/Cocoa.h>
#import "BrowserDelegate.h"
#import "include/cef.h"
class ClientHandler;
@interface AtomController : NSWindowController <NSWindowDelegate, BrowserDelegate> {
NSView *_webView;
NSString *_bootstrapScript;
NSString *_pathToOpen;
CefRefPtr<CefV8Context> _atomContext;
CefRefPtr<ClientHandler> _clientHandler;
}
- (id)initWithBootstrapScript:(NSString *)bootstrapScript atomContext:(CefRefPtr<CefV8Context>) context;
- (id)initWithPath:(NSString *)path atomContext:(CefRefPtr<CefV8Context>)atomContext;
- (id)initSpecsWithAtomContext:(CefRefPtr<CefV8Context>)atomContext;
- (void)createBrowser;
@property (nonatomic, retain) IBOutlet NSView *webView;
@end
// Returns the application browser settings based on command line arguments.
void AppGetBrowserSettings(CefBrowserSettings& settings);

170
Atom/src/AtomController.mm Normal file
View File

@@ -0,0 +1,170 @@
#import "AtomController.h"
#import "include/cef.h"
#import "client_handler.h"
#import "native_handler.h"
@implementation AtomController
@synthesize webView=_webView;
- (void)dealloc {
[_bootstrapScript release];
[_webView release];
[_pathToOpen release];
[super dealloc];
}
- (id)initWithBootstrapScript:(NSString *)bootstrapScript atomContext:(CefRefPtr<CefV8Context>)atomContext {
self = [super initWithWindowNibName:@"ClientWindow"];
_bootstrapScript = [bootstrapScript retain];
_atomContext = atomContext;
[self.window makeKeyAndOrderFront:nil];
[self createBrowser];
return self;
}
- (id)initWithPath:(NSString *)path atomContext:(CefRefPtr<CefV8Context>)atomContext {
_pathToOpen = [path retain];
return [self initWithBootstrapScript:@"window-bootstrap" atomContext:atomContext];
}
- (id)initSpecsWithAtomContext:(CefRefPtr<CefV8Context>)atomContext {
return [self initWithBootstrapScript:@"spec-bootstrap" atomContext:atomContext];
}
- (void)windowDidLoad {
[self.window setDelegate:self];
[self.window setReleasedWhenClosed:NO];
}
- (void)createBrowser {
_clientHandler = new ClientHandler(self);
CefWindowInfo window_info;
CefBrowserSettings settings;
AppGetBrowserSettings(settings);
window_info.SetAsChild(self.webView, 0, 0, self.webView.bounds.size.width, self.webView.bounds.size.height);
NSURL *resourceDirURL = [[NSBundle mainBundle] resourceURL];
NSString *indexURLString = [[resourceDirURL URLByAppendingPathComponent:@"index.html"] absoluteString];
CefBrowser::CreateBrowser(window_info, _clientHandler.get(), [indexURLString UTF8String], settings);
}
#pragma mark BrowserDelegate
- (void)loadStart {
CefRefPtr<CefV8Context> context = _clientHandler->GetBrowser()->GetMainFrame()->GetV8Context();
CefRefPtr<CefV8Value> global = context->GetGlobal();
context->Enter();
CefRefPtr<CefV8Value> bootstrapScript = CefV8Value::CreateString([_bootstrapScript UTF8String]);
global->SetValue("$bootstrapScript", bootstrapScript, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<NativeHandler> nativeHandler = new NativeHandler();
global->SetValue("$native", nativeHandler->m_object, V8_PROPERTY_ATTRIBUTE_NONE);
CefRefPtr<CefV8Value> pathToOpen = _pathToOpen ? CefV8Value::CreateString([_pathToOpen UTF8String]) : CefV8Value::CreateNull();
global->SetValue("$pathToOpen", pathToOpen, V8_PROPERTY_ATTRIBUTE_NONE);
global->SetValue("atom", _atomContext->GetGlobal()->GetValue("atom"), V8_PROPERTY_ATTRIBUTE_NONE);
context->Exit();
}
- (bool)keyEventOfType:(cef_handler_keyevent_type_t)type
code:(int)code
modifiers:(int)modifiers
isSystemKey:(bool)isSystemKey
isAfterJavaScript:(bool)isAfterJavaScript {
if (isAfterJavaScript && type == KEYEVENT_RAWKEYDOWN && modifiers == KEY_META && code == 'R') {
_clientHandler->GetBrowser()->ReloadIgnoreCache();
return YES;
}
return NO;
}
#pragma mark NSWindowDelegate
- (BOOL)windowShouldClose:(id)window {
CefRefPtr<CefV8Context> context = _clientHandler->GetBrowser()->GetMainFrame()->GetV8Context();
CefRefPtr<CefV8Value> global = context->GetGlobal();
context->Enter();
CefRefPtr<CefV8Value> atom = context->GetGlobal()->GetValue("atom");
CefRefPtr<CefV8Value> retval;
CefRefPtr<CefV8Exception> exception;
CefV8ValueList arguments;
arguments.push_back(global);
atom->GetValue("windowClosed")->ExecuteFunction(atom, arguments, retval, exception, true);
context->Exit();
_clientHandler->GetBrowser()->CloseDevTools();
_atomContext = NULL;
_clientHandler = NULL;
// Clean ourselves up after clearing the stack of anything that might have the window on it.
[self autorelease];
return YES;
}
@end
// Returns the application browser settings based on command line arguments.
void AppGetBrowserSettings(CefBrowserSettings& settings) {
CefString(&settings.default_encoding) = "";
CefString(&settings.user_style_sheet_location) = "";
settings.drag_drop_disabled = false;
settings.load_drops_disabled = false;
settings.history_disabled = false;
settings.remote_fonts_disabled = false;
settings.encoding_detector_enabled = false;
settings.javascript_disabled = false;
settings.javascript_open_windows_disallowed = false;
settings.javascript_close_windows_disallowed = false;
settings.javascript_access_clipboard_disallowed = false;
settings.dom_paste_disabled = false;
settings.caret_browsing_enabled = false;
settings.java_disabled = true;
settings.plugins_disabled = true;
settings.universal_access_from_file_urls_allowed = true;
settings.file_access_from_file_urls_allowed = false;
settings.web_security_disabled = true;
settings.xss_auditor_enabled = false;
settings.image_load_disabled = false;
settings.shrink_standalone_images_to_fit = false;
settings.site_specific_quirks_disabled = false;
settings.text_area_resize_disabled = false;
settings.page_cache_disabled = false;
settings.tab_to_links_disabled = false;
settings.hyperlink_auditing_disabled = false;
settings.user_style_sheet_enabled = false;
settings.author_and_user_styles_disabled = false;
settings.local_storage_disabled = false;
settings.databases_disabled = false;
settings.application_cache_disabled = false;
settings.webgl_disabled = false;
settings.accelerated_compositing_enabled = false;
settings.threaded_compositing_enabled = false;
settings.accelerated_layers_disabled = false;
settings.accelerated_video_disabled = false;
settings.accelerated_2d_canvas_disabled = false;
settings.accelerated_drawing_disabled = false;
settings.accelerated_plugins_disabled = false;
settings.developer_tools_disabled = false;
}

View File

@@ -0,0 +1,11 @@
#import <Foundation/Foundation.h>
#import "include/cef.h"
@protocol BrowserDelegate <NSObject>
@optional
- (void)afterCreated;
- (void)loadStart;
- (bool)keyEventOfType:(cef_handler_keyevent_type_t)type code:(int)code modifiers:(int)modifiers isSystemKey:(bool)isSystemKey isAfterJavaScript:(bool)isAfterJavaScript;
@end

128
Atom/src/client_handler.h Executable file
View File

@@ -0,0 +1,128 @@
// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef _CLIENT_HANDLER_H
#define _CLIENT_HANDLER_H
#import "include/cef.h"
@class AtomController;
// ClientHandler implementation.
class ClientHandler : public CefClient,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRequestHandler,
public CefDisplayHandler,
public CefFocusHandler,
public CefKeyboardHandler,
public CefPrintHandler,
public CefV8ContextHandler,
public CefDragHandler
{
public:
ClientHandler(id delegate);
virtual ~ClientHandler();
// CefClient methods
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefFocusHandler> GetFocusHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefPrintHandler> GetPrintHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefV8ContextHandler> GetV8ContextHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefDragHandler> GetDragHandler() OVERRIDE
{ return this; }
// CefLifeSpanHandler methods
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefLoadHandler methods
virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame) OVERRIDE;
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE;
virtual bool OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& failedUrl,
CefString& errorText) OVERRIDE;
// CefRequestHandler methods
virtual bool OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
CefString& redirectUrl,
CefRefPtr<CefStreamReader>& resourceStream,
CefRefPtr<CefResponse> response,
int loadFlags) OVERRIDE;
// CefDisplayHandler methods
virtual void OnNavStateChange(CefRefPtr<CefBrowser> browser,
bool canGoBack,
bool canGoForward) OVERRIDE;
virtual void OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) OVERRIDE;
// CefFocusHandler methods.
virtual void OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node) OVERRIDE;
// CefKeyboardHandler methods.
virtual bool OnKeyEvent(CefRefPtr<CefBrowser> browser,
KeyEventType type,
int code,
int modifiers,
bool isSystemKey,
bool isAfterJavaScript) OVERRIDE;
// CefV8ContextHandler methods
virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) OVERRIDE;
// CefDragHandler methods.
virtual bool OnDragStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask) OVERRIDE;
virtual bool OnDragEnter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask) OVERRIDE;
CefRefPtr<CefBrowser> GetBrowser() { return m_Browser; }
CefWindowHandle GetBrowserHwnd() { return m_BrowserHwnd; }
protected:
// The child browser window
CefRefPtr<CefBrowser> m_Browser;
// The main frame window handle
CefWindowHandle m_MainHwnd;
// The child browser window handle
CefWindowHandle m_BrowserHwnd;
id m_delegate;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientHandler);
// Include the default locking implementation.
IMPLEMENT_LOCKING(ClientHandler);
};
#endif // _CLIENT_HANDLER_H

199
Atom/src/client_handler.mm Executable file
View File

@@ -0,0 +1,199 @@
#import "include/cef.h"
#import "include/cef_wrapper.h"
#import "client_handler.h"
#import "AtomController.h"
#import <Cocoa/Cocoa.h>
#import <sstream>
#import <stdio.h>
#import <string>
#import <assert.h>
#ifndef NDEBUG
#define ASSERT(condition) if(!(condition)) { assert(false); }
#else
#define ASSERT(condition) ((void)0)
#endif
#define REQUIRE_UI_THREAD() ASSERT(CefCurrentlyOn(TID_UI));
#define REQUIRE_IO_THREAD() ASSERT(CefCurrentlyOn(TID_IO));
#define REQUIRE_FILE_THREAD() ASSERT(CefCurrentlyOn(TID_FILE));
ClientHandler::ClientHandler(id delegate)
: m_MainHwnd(NULL),
m_BrowserHwnd(NULL)
{
m_delegate = delegate;
}
ClientHandler::~ClientHandler()
{
}
void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
REQUIRE_UI_THREAD();
AutoLock lock_scope(this);
if(!m_Browser.get())
{
// We need to keep the main child window, but not popup windows
m_Browser = browser;
m_BrowserHwnd = browser->GetWindowHandle();
if ([m_delegate respondsToSelector:@selector(afterCreated)]) {
[m_delegate afterCreated];
}
}
}
bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser)
{
REQUIRE_UI_THREAD();
return false;
}
void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
REQUIRE_UI_THREAD();
if(m_BrowserHwnd == browser->GetWindowHandle()) {
// Free the browser pointer so that the browser can be destroyed
m_Browser = NULL;
}
}
void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame)
{
REQUIRE_UI_THREAD();
if ([m_delegate respondsToSelector:@selector(loadStart)]) {
[m_delegate loadStart];
}
}
void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode)
{
REQUIRE_UI_THREAD();
}
bool ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& failedUrl,
CefString& errorText)
{
REQUIRE_UI_THREAD();
if(errorCode == ERR_CACHE_MISS) {
// Usually caused by navigating to a page with POST data via back or
// forward buttons.
errorText = "<html><head><title>Expired Form Data</title></head>"
"<body><h1>Expired Form Data</h1>"
"<h2>Your form request has expired. "
"Click reload to re-submit the form data.</h2></body>"
"</html>";
} else {
// All other messages.
std::stringstream ss;
ss << "<html><head><title>Load Failed</title></head>"
"<body><h1>Load Failed</h1>"
"<h2>Load of URL " << std::string(failedUrl) <<
" failed with error code " << static_cast<int>(errorCode) <<
".</h2></body>"
"</html>";
errorText = ss.str();
}
return false;
}
void ClientHandler::OnNavStateChange(CefRefPtr<CefBrowser> browser,
bool canGoBack,
bool canGoForward)
{
REQUIRE_UI_THREAD();
}
void ClientHandler::OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node)
{
REQUIRE_UI_THREAD();
}
bool ClientHandler::OnKeyEvent(CefRefPtr<CefBrowser> browser,
KeyEventType type,
int code,
int modifiers,
bool isSystemKey,
bool isAfterJavaScript)
{
REQUIRE_UI_THREAD();
if ([m_delegate respondsToSelector:@selector(keyEventOfType:code:modifiers:isSystemKey:isAfterJavaScript:)]) {
return [m_delegate keyEventOfType:type code:code modifiers:modifiers isSystemKey:isSystemKey isAfterJavaScript:isAfterJavaScript];
}
else {
return false;
}
}
void ClientHandler::OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context)
{
REQUIRE_UI_THREAD();
}
bool ClientHandler::OnDragStart(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask)
{
REQUIRE_UI_THREAD();
return false;
}
bool ClientHandler::OnDragEnter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDragData> dragData,
DragOperationsMask mask)
{
REQUIRE_UI_THREAD();
return false;
}
bool ClientHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefRequest> request,
CefString& redirectUrl,
CefRefPtr<CefStreamReader>& resourceStream,
CefRefPtr<CefResponse> response,
int loadFlags)
{
REQUIRE_IO_THREAD();
return false;
}
void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title)
{
REQUIRE_UI_THREAD();
// Set the frame window title bar
NSView* view = (NSView*)browser->GetWindowHandle();
NSWindow* window = [view window];
std::string titleStr(title);
NSString* str = [NSString stringWithUTF8String:titleStr.c_str()];
[window setTitle:str];
}

19
Atom/src/main.mm Normal file
View File

@@ -0,0 +1,19 @@
#import <Cocoa/Cocoa.h>
#include "include/cef.h"
int main(int argc, char* argv[]) {
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
Class principalClass = NSClassFromString([infoDictionary objectForKey:@"NSPrincipalClass"]);
NSApplication *application = [principalClass sharedApplication];
NSString *mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"];
NSNib *mainNib = [[NSNib alloc] initWithNibNamed:mainNibName bundle:[NSBundle mainBundle]];
[mainNib instantiateNibWithOwner:application topLevelObjects:nil];
// Run the application message loop.
CefRunMessageLoop();
// Don't put anything below this line because it won't be executed.
return 0;
}

18
Atom/src/native_handler.h Normal file
View File

@@ -0,0 +1,18 @@
#import "include/cef.h"
#import <Cocoa/Cocoa.h>
class NativeHandler : public CefV8Handler {
public:
NativeHandler();
CefRefPtr<CefV8Value> m_object;
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE;
// Provide the reference counting implementation for this class.
IMPLEMENT_REFCOUNTING(NativeHandler);
};

258
Atom/src/native_handler.mm Normal file
View File

@@ -0,0 +1,258 @@
#import "native_handler.h"
#import "include/cef.h"
#import "Atom.h"
NSString *stringFromCefV8Value(const CefRefPtr<CefV8Value>& value) {
std::string cc_value = value->GetStringValue().ToString();
return [NSString stringWithUTF8String:cc_value.c_str()];
}
NativeHandler::NativeHandler() : CefV8Handler() {
m_object = CefV8Value::CreateObject(NULL);
const char *functionNames[] = {"exists", "read", "write", "absolute", "list", "isFile", "isDirectory", "remove", "asyncList", "open", "openDialog", "quit", "writeToPasteboard", "readFromPasteboard", "showDevTools", "newWindow", "saveDialog"};
NSUInteger arrayLength = sizeof(functionNames) / sizeof(const char *);
for (NSUInteger i = 0; i < arrayLength; i++) {
const char *functionName = functionNames[i];
CefRefPtr<CefV8Value> function = CefV8Value::CreateFunction(functionName, this);
m_object->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE);
}
}
bool NativeHandler::Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) {
if (name == "exists") {
NSString *path = stringFromCefV8Value(arguments[0]);
bool exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil];
retval = CefV8Value::CreateBool(exists);
return true;
}
else if (name == "read") {
NSString *path = stringFromCefV8Value(arguments[0]);
NSError *error = nil;
NSString *contents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (error) {
exception = [[error localizedDescription] UTF8String];
}
else {
retval = CefV8Value::CreateString([contents UTF8String]);
}
return true;
}
else if (name == "write") {
NSString *path = stringFromCefV8Value(arguments[0]);
NSString *content = stringFromCefV8Value(arguments[1]);
NSError *error = nil;
BOOL success = [content writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (error) {
exception = [[error localizedDescription] UTF8String];
}
else if (!success) {
std::string exception = "Cannot write to '";
exception += [path UTF8String];
exception += "'";
}
}
else if (name == "absolute") {
NSString *path = stringFromCefV8Value(arguments[0]);
path = [path stringByStandardizingPath];
if ([path characterAtIndex:0] == '/') {
retval = CefV8Value::CreateString([path UTF8String]);
}
return true;
}
else if (name == "list") {
NSString *path = stringFromCefV8Value(arguments[0]);
bool recursive = arguments[1]->GetBoolValue();
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *relativePaths = [NSArray array];
NSError *error = nil;
if (recursive) {
relativePaths = [fm subpathsOfDirectoryAtPath:path error:&error];
}
else {
relativePaths = [fm contentsOfDirectoryAtPath:path error:&error];
}
if (error) {
exception = [[error localizedDescription] UTF8String];
}
else {
retval = CefV8Value::CreateArray();
for (NSUInteger i = 0; i < relativePaths.count; i++) {
NSString *relativePath = [relativePaths objectAtIndex:i];
NSString *fullPath = [path stringByAppendingPathComponent:relativePath];
retval->SetValue(i, CefV8Value::CreateString([fullPath UTF8String]));
}
}
return true;
}
else if (name == "isDirectory") {
NSString *path = stringFromCefV8Value(arguments[0]);
BOOL isDir = false;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir];
retval = CefV8Value::CreateBool(exists && isDir);
return true;
}
else if (name == "remove") {
NSString *path = stringFromCefV8Value(arguments[0]);
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:path error:&error];
if (error) {
exception = [[error localizedDescription] UTF8String];
}
return true;
}
else if (name == "asyncList") {
NSString *path = stringFromCefV8Value(arguments[0]);
bool recursive = arguments[1]->GetBoolValue();
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *relativePaths = [NSArray array];
NSError *error = nil;
if (recursive) {
relativePaths = [fm subpathsOfDirectoryAtPath:path error:&error];
}
else {
relativePaths = [fm contentsOfDirectoryAtPath:path error:&error];
}
if (error) {
exception = [[error localizedDescription] UTF8String];
}
else {
CefRefPtr<CefV8Value> paths = CefV8Value::CreateArray();
for (NSUInteger i = 0; i < relativePaths.count; i++) {
NSString *relativePath = [relativePaths objectAtIndex:i];
NSString *fullPath = [path stringByAppendingPathComponent:relativePath];
paths->SetValue(i, CefV8Value::CreateString([fullPath UTF8String]));
}
CefV8ValueList args;
args.push_back(paths);
CefRefPtr<CefV8Exception> e;
arguments[2]->ExecuteFunction(arguments[2], args, retval, e, true);
if (e) exception = e->GetMessage();
}
return true;
}
else if (name == "alert") {
NSString *message = stringFromCefV8Value(arguments[0]);
NSString *detailedMessage = stringFromCefV8Value(arguments[1]);
CefRefPtr<CefV8Value> buttons = arguments[2];
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:message];
[alert setInformativeText:detailedMessage];
std::vector<CefString> buttonTitles;
std::vector<CefString>::iterator iter;
NSMutableDictionary *titleForTag = [NSMutableDictionary dictionary];
buttons->GetKeys(buttonTitles);
for (iter = buttonTitles.begin(); iter != buttonTitles.end(); iter++) {
NSString *buttonTitle = [NSString stringWithUTF8String:(*iter).ToString().c_str()];
NSButton *button = [alert addButtonWithTitle:buttonTitle];
[titleForTag setObject:buttonTitle forKey:[NSNumber numberWithInt:button.tag]];
}
NSUInteger buttonTag = [alert runModal];
const char *buttonTitle = [[titleForTag objectForKey:[NSNumber numberWithInt:buttonTag]] UTF8String];
CefRefPtr<CefV8Value> callback = buttons->GetValue(buttonTitle);
CefV8ValueList args;
CefRefPtr<CefV8Exception> e;
callback->ExecuteFunction(callback , args, retval, e, true);
if (e) exception = e->GetMessage();
return true;
}
else if (name == "writeToPasteboard") {
NSString *text = stringFromCefV8Value(arguments[0]);
NSPasteboard *pb = [NSPasteboard generalPasteboard];
[pb declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil] owner:nil];
[pb setString:text forType:NSStringPboardType];
return true;
}
else if (name == "readFromPasteboard") {
NSPasteboard *pb = [NSPasteboard generalPasteboard];
NSArray *results = [pb readObjectsForClasses:[NSArray arrayWithObjects:[NSString class], nil] options:nil];
if (results) {
retval = CefV8Value::CreateString([[results objectAtIndex:0] UTF8String]);
}
return true;
}
else if (name == "openDialog") {
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseDirectories:YES];
if ([panel runModal] == NSFileHandlingPanelOKButton) {
NSURL *url = [[panel URLs] lastObject];
retval = CefV8Value::CreateString([[url path] UTF8String]);
}
else {
retval = CefV8Value::CreateNull();
}
return true;
}
else if (name == "open") {
NSString *path = stringFromCefV8Value(arguments[0]);
[NSApp open:path];
return true;
}
else if (name == "newWindow") {
[NSApp open:nil];
return true;
}
else if (name == "saveDialog") {
NSSavePanel *panel = [NSSavePanel savePanel];
if ([panel runModal] == NSFileHandlingPanelOKButton) {
NSURL *url = [panel URL];
retval = CefV8Value::CreateString([[url path] UTF8String]);
}
else {
return CefV8Value::CreateNull();
}
return true;
}
else if (name == "quit") {
[NSApp terminate:nil];
return true;
}
else if (name == "showDevTools") {
CefV8Context::GetCurrentContext()->GetBrowser()->ShowDevTools();
return true;
}
return false;
};

View File

@@ -8,7 +8,7 @@ task :build do
dest = File.join(built_dir, contents_dir, "Resources")
%w(index.html src docs static extensions vendor spec).each do |dir|
%w(index.html src static vendor spec).each do |dir|
rm_rf File.join(dest, dir)
cp_r dir, File.join(dest, dir)
end
@@ -19,7 +19,8 @@ task :build do
"http://coffeescript.org/ - (try `npm i -g coffee-script`)"
end
sh "coffee -c #{dest}/src #{dest}/vendor #{dest}/extensions #{dest}/spec"
puts contents_dir
sh "coffee -c #{dest}/src #{dest}/vendor #{dest}/spec"
end
desc "Install the app in /Applications"

View File

3975
cef/include/cef.h Executable file

File diff suppressed because it is too large Load Diff

120
cef/include/cef_application_mac.h Executable file
View File

@@ -0,0 +1,120 @@
// Copyright (c) 2011 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _CEF_APPLICATION_MAC_H
#define _CEF_APPLICATION_MAC_H
#pragma once
#include "cef.h"
#if defined(OS_MACOSX) && defined(__OBJC__)
#ifdef BUILDING_CEF_SHARED
// Use the existing CrAppProtocol definition.
#include "base/message_pump_mac.h"
// Use the existing empty protocol definitions.
#import "base/mac/cocoa_protocols.h"
#else // BUILDING_CEF_SHARED
#import <AppKit/AppKit.h>
#import <Cocoa/Cocoa.h>
// Copy of CrAppProtocol definition from base/message_pump_mac.h.
@protocol CrAppProtocol
// Must return true if -[NSApplication sendEvent:] is currently on the stack.
- (BOOL)isHandlingSendEvent;
@end
// The Mac OS X 10.6 SDK introduced new protocols used for delegates. These
// protocol defintions were not present in earlier releases of the Mac OS X
// SDK. In order to support building against the new SDK, which requires
// delegates to conform to these protocols, and earlier SDKs, which do not
// define these protocols at all, this file will provide empty protocol
// definitions when used with earlier SDK versions.
#if !defined(MAC_OS_X_VERSION_10_6) || \
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
#define DEFINE_EMPTY_PROTOCOL(p) \
@protocol p \
@end
DEFINE_EMPTY_PROTOCOL(NSAlertDelegate)
DEFINE_EMPTY_PROTOCOL(NSApplicationDelegate)
DEFINE_EMPTY_PROTOCOL(NSControlTextEditingDelegate)
DEFINE_EMPTY_PROTOCOL(NSMatrixDelegate)
DEFINE_EMPTY_PROTOCOL(NSMenuDelegate)
DEFINE_EMPTY_PROTOCOL(NSOpenSavePanelDelegate)
DEFINE_EMPTY_PROTOCOL(NSOutlineViewDataSource)
DEFINE_EMPTY_PROTOCOL(NSOutlineViewDelegate)
DEFINE_EMPTY_PROTOCOL(NSSpeechSynthesizerDelegate)
DEFINE_EMPTY_PROTOCOL(NSSplitViewDelegate)
DEFINE_EMPTY_PROTOCOL(NSTableViewDataSource)
DEFINE_EMPTY_PROTOCOL(NSTableViewDelegate)
DEFINE_EMPTY_PROTOCOL(NSTextFieldDelegate)
DEFINE_EMPTY_PROTOCOL(NSTextViewDelegate)
DEFINE_EMPTY_PROTOCOL(NSWindowDelegate)
#undef DEFINE_EMPTY_PROTOCOL
#endif
#endif // BUILDING_CEF_SHARED
// All CEF client applications must subclass NSApplication and implement this
// protocol.
@protocol CefAppProtocol<CrAppProtocol>
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent;
@end
// Controls the state of |isHandlingSendEvent| in the event loop so that it is
// reset properly.
class CefScopedSendingEvent {
public:
CefScopedSendingEvent()
: app_(static_cast<NSApplication<CefAppProtocol>*>(
[NSApplication sharedApplication])),
handling_([app_ isHandlingSendEvent]) {
[app_ setHandlingSendEvent:YES];
}
~CefScopedSendingEvent() {
[app_ setHandlingSendEvent:handling_];
}
private:
NSApplication<CefAppProtocol>* app_;
BOOL handling_;
};
#endif // defined(OS_MACOSX) && defined(__OBJC__)
#endif // _CEF_APPLICATION_MAC_H

3769
cef/include/cef_capi.h Executable file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More