Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/maccman/macgap into get-w…
Browse files Browse the repository at this point in the history
…indow-position
  • Loading branch information
jeff-h committed Mar 30, 2014
2 parents a20855e + 72f7675 commit 3f927e1
Show file tree
Hide file tree
Showing 17 changed files with 812 additions and 3 deletions.
34 changes: 34 additions & 0 deletions MacGap.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

/* Begin PBXBuildFile section */
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */ = {isa = PBXBuildFile; fileRef = 1495814E15C15CCC00E1CFE5 /* Notice.m */; };
6FD6E4ED18C2D48C00DFFBE6 /* fonts.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */; };
6F169DA718CC332E005EDDF3 /* Command.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DA618CC332E005EDDF3 /* Command.m */; };
6F169DAA18CC35FD005EDDF3 /* CallbackDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */; };
6F169DAC18CD8A4A005EDDF3 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */; };
6F169DB118CD906F005EDDF3 /* MenuItemProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */; };
6F169DB218CD906F005EDDF3 /* MenuProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DB018CD906F005EDDF3 /* MenuProxy.m */; };
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 88746BED14CCA435001E160E /* JSEventHelper.m */; };
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0645F14BDE10A00E4BCE2 /* Window.m */; };
88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 88C0646414BDEC5800E4BCE2 /* Window.xib */; };
Expand Down Expand Up @@ -50,6 +56,17 @@
/* Begin PBXFileReference section */
1495814D15C15CCC00E1CFE5 /* Notice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Notice.h; path = Classes/Commands/Notice.h; sourceTree = "<group>"; };
1495814E15C15CCC00E1CFE5 /* Notice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Notice.m; path = Classes/Commands/Notice.m; sourceTree = "<group>"; };
6FD6E4EB18C2D48200DFFBE6 /* fonts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fonts.h; path = Classes/Commands/fonts.h; sourceTree = "<group>"; };
6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = fonts.m; path = Classes/Commands/fonts.m; sourceTree = "<group>"; };
6F169DA518CC332E005EDDF3 /* Command.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Command.h; path = Classes/Commands/Command.h; sourceTree = "<group>"; };
6F169DA618CC332E005EDDF3 /* Command.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Command.m; path = Classes/Commands/Command.m; sourceTree = "<group>"; };
6F169DA818CC35FD005EDDF3 /* CallbackDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CallbackDelegate.h; path = Classes/CallbackDelegate.h; sourceTree = "<group>"; };
6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CallbackDelegate.m; path = Classes/CallbackDelegate.m; sourceTree = "<group>"; };
6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
6F169DAD18CD906F005EDDF3 /* MenuItemProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MenuItemProxy.h; path = Classes/Commands/MenuItemProxy.h; sourceTree = "<group>"; };
6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MenuItemProxy.m; path = Classes/Commands/MenuItemProxy.m; sourceTree = "<group>"; };
6F169DAF18CD906F005EDDF3 /* MenuProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MenuProxy.h; path = Classes/Commands/MenuProxy.h; sourceTree = "<group>"; };
6F169DB018CD906F005EDDF3 /* MenuProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MenuProxy.m; path = Classes/Commands/MenuProxy.m; sourceTree = "<group>"; };
88746BEC14CCA435001E160E /* JSEventHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSEventHelper.h; path = Classes/JSEventHelper.h; sourceTree = "<group>"; };
88746BED14CCA435001E160E /* JSEventHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JSEventHelper.m; path = Classes/JSEventHelper.m; sourceTree = "<group>"; };
88C0645E14BDE10A00E4BCE2 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Window.h; path = Classes/Window.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -102,6 +119,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6F169DAC18CD8A4A005EDDF3 /* JavaScriptCore.framework in Frameworks */,
FA3F7743168F70850027B324 /* Growl.framework in Frameworks */,
FA3F7742168F70790027B324 /* Cocoa.framework in Frameworks */,
FA32509D14BA813600BF0781 /* WebKit.framework in Frameworks */,
Expand All @@ -116,6 +134,8 @@
children = (
FA3250E114BA87DD00BF0781 /* Commands */,
FA3250BA14BA85E700BF0781 /* Constants.h */,
6F169DA818CC35FD005EDDF3 /* CallbackDelegate.h */,
6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */,
FA3250BB14BA85E700BF0781 /* ContentView.h */,
FA3250BC14BA85E700BF0781 /* ContentView.m */,
FA3250BF14BA85E700BF0781 /* WebViewDelegate.h */,
Expand All @@ -129,10 +149,14 @@
FA3250E114BA87DD00BF0781 /* Commands */ = {
isa = PBXGroup;
children = (
6F169DA518CC332E005EDDF3 /* Command.h */,
6F169DA618CC332E005EDDF3 /* Command.m */,
1495814D15C15CCC00E1CFE5 /* Notice.h */,
1495814E15C15CCC00E1CFE5 /* Notice.m */,
FA3250CA14BA860800BF0781 /* Dock.h */,
FA3250CB14BA860800BF0781 /* Dock.m */,
6FD6E4EB18C2D48200DFFBE6 /* fonts.h */,
6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */,
FA3250BD14BA85E700BF0781 /* Utils.h */,
FA3250BE14BA85E700BF0781 /* Utils.m */,
FA3250CC14BA860800BF0781 /* Growl.h */,
Expand All @@ -143,6 +167,10 @@
FA3250D114BA860800BF0781 /* Sound.m */,
FA3250C814BA860800BF0781 /* App.h */,
FA3250C914BA860800BF0781 /* App.m */,
6F169DAD18CD906F005EDDF3 /* MenuItemProxy.h */,
6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */,
6F169DAF18CD906F005EDDF3 /* MenuProxy.h */,
6F169DB018CD906F005EDDF3 /* MenuProxy.m */,
88C0645E14BDE10A00E4BCE2 /* Window.h */,
88C0645F14BDE10A00E4BCE2 /* Window.m */,
88746BEC14CCA435001E160E /* JSEventHelper.h */,
Expand Down Expand Up @@ -175,6 +203,7 @@
FAE451BD14BA79C600190544 /* Frameworks */ = {
isa = PBXGroup;
children = (
6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */,
FA3250DE14BA878D00BF0781 /* Growl.framework */,
FA32509E14BA816E00BF0781 /* Growl.framework */,
FA32509C14BA813600BF0781 /* WebKit.framework */,
Expand Down Expand Up @@ -288,6 +317,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6F169DAA18CC35FD005EDDF3 /* CallbackDelegate.m in Sources */,
FA3250D314BA860800BF0781 /* App.m in Sources */,
FA3250D514BA860800BF0781 /* Dock.m in Sources */,
FA3250D714BA860800BF0781 /* Growl.m in Sources */,
Expand All @@ -297,9 +327,13 @@
FA3250C514BA85E700BF0781 /* Utils.m in Sources */,
FA3250C714BA85E700BF0781 /* WebViewDelegate.m in Sources */,
FAE451CB14BA79C600190544 /* main.m in Sources */,
6F169DB118CD906F005EDDF3 /* MenuItemProxy.m in Sources */,
FAE451D214BA79C600190544 /* AppDelegate.m in Sources */,
6F169DA718CC332E005EDDF3 /* Command.m in Sources */,
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */,
6F169DB218CD906F005EDDF3 /* MenuProxy.m in Sources */,
88C0646D14BDF6A600E4BCE2 /* WindowController.m in Sources */,
6FD6E4ED18C2D48C00DFFBE6 /* fonts.m in Sources */,
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */,
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */,
F2B80016179E0FC100B069A8 /* Clipboard.m in Sources */,
Expand Down
20 changes: 20 additions & 0 deletions MacGap/Classes/CallbackDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// CallbackDelegate.h
// MacGap
//
// Created by Joe Hildebrand on 1/10/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import "Command.h"

@interface CallbackDelegate : Command {
}

@property JSObjectRef callback;

- (id) initWithContext:(JSContextRef)aContext forCallback:(WebScriptObject*)aCallback;
- (id) call;
- (id) callWithParams:(id)firstOrNil, ... NS_REQUIRES_NIL_TERMINATION;

@end
168 changes: 168 additions & 0 deletions MacGap/Classes/CallbackDelegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
//
// CallbackDelegate.m
// MacGap
//
// Created by Joe Hildebrand on 1/10/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import "CallbackDelegate.h"
#import <JavaScriptCore/JavaScript.h>

@implementation CallbackDelegate

@synthesize callback;

- (id) initWithContext:(JSContextRef)aContext forCallback:(WebScriptObject*)aCallback
{
if (!aCallback)
return nil;
if ([aCallback isKindOfClass:[WebUndefined class]])
return nil;

self = [super initWithContext:aContext];
if (!self)
return nil;

callback = [aCallback JSObject];
JSValueProtect(context, callback);
return self;
}

- (void) dealloc
{
if (callback)
{
JSValueUnprotect(context, callback);
callback = nil;
}
}

- (id) objectFromValue:(JSValueRef)val
{
JSStringRef jstr;
NSString *rets;

switch(JSValueGetType(context, val))
{
case kJSTypeUndefined:
case kJSTypeNull:
return nil;
case kJSTypeBoolean:
return [NSNumber numberWithBool:JSValueToBoolean(context, val)];
case kJSTypeNumber:
return [NSNumber numberWithDouble:JSValueToNumber(context, val, NULL)];
case kJSTypeString:
jstr = JSValueToStringCopy(context, val, NULL);
size_t sz = JSStringGetMaximumUTF8CStringSize(jstr);
char *buf = (char*)malloc(sz);
JSStringGetUTF8CString(jstr, buf, sz);
rets = [NSString stringWithUTF8String:buf];
free(buf);
return rets;
case kJSTypeObject:
// TODO: dictionary or something
return nil;
default:
NSAssert(false, @"Invalid JavaScript type");
return nil;
}
}

- (JSValueRef) valueFromObject:(id)obj
{
JSValueRef val = nil;
if (!obj)
{
val = JSValueMakeNull(context);
}
else if ([obj isKindOfClass:[NSString class]])
{
JSStringRef jstr = JSStringCreateWithUTF8CString([obj UTF8String]);
val = JSValueMakeString(context, jstr);
JSStringRelease(jstr);
}
else if ([obj isKindOfClass:[NSNumber class]])
{
val = JSValueMakeNumber(context, [obj doubleValue]);
}
else if ([obj isKindOfClass:[NSDictionary class]])
{
JSObjectRef o = JSObjectMake(context, NULL, NULL);
for (NSString *key in obj)
{
JSStringRef kstr = JSStringCreateWithUTF8CString([key UTF8String]);
JSValueRef v = [self valueFromObject:[obj objectForKey:key]];

JSObjectSetProperty(context, o, kstr, v, kJSPropertyAttributeNone, NULL);
JSStringRelease(kstr);
}
val = o;
}
else if ([obj isKindOfClass:[NSArray class]])
{
NSUInteger pcount = [obj count];
JSValueRef jsArgs[pcount];
NSUInteger i=0;
for (id v in obj)
{
jsArgs[i++] = [self valueFromObject:v];
}
val = JSObjectMakeArray(context, pcount, jsArgs, NULL);
}
else if ([obj isKindOfClass:[NSDate class]])
{
NSTimeInterval secs = [obj timeIntervalSince1970];
JSValueRef jsArgs[1];
// call the Date(milliseconds) constructor in JS
jsArgs[0] = JSValueMakeNumber(context, secs * 1000.0);
val = JSObjectMakeDate(context, 1, jsArgs, NULL);
}
else
{
NSLog(@"Warning: unknown object type for: %@", obj);
val = JSValueMakeUndefined(context);
}
return val;
}

- (id) call
{
NSAssert(callback, @"Callback required");
if (!JSObjectIsFunction(context, callback))
return nil;

JSValueRef jsArgs[0];
JSValueRef ret = JSObjectCallAsFunction(context, callback, NULL, 0, jsArgs, NULL);
return [self objectFromValue:ret];
}

- (id) callWithParams:(id)firstOrNil, ...
{
NSAssert(callback, @"Callback required");
if (!JSObjectIsFunction(context, callback))
return nil;
NSUInteger pcount = 0;
id p;
va_list args;
va_start(args, firstOrNil);
for (p=firstOrNil; p; p=va_arg(args, id))
{
pcount++;
}
va_end(args);

JSValueRef jsArgs[pcount];
NSUInteger j = 0;
va_start(args, firstOrNil);
for (p=firstOrNil; p; p=va_arg(args, id))
{
jsArgs[j++] = [self valueFromObject:p];
}
va_end(args);

JSValueRef ret = JSObjectCallAsFunction(context, callback, NULL, j, jsArgs, NULL);
return [self objectFromValue:ret];
}

@end
18 changes: 18 additions & 0 deletions MacGap/Classes/Commands/Command.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Command.h
// MacGap
//
// Created by Joe Hildebrand on 1/10/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <Webkit/WebScriptObject.h>

@interface Command : NSObject {
JSContextRef context;
}

- (id) initWithContext:(JSContextRef)aContext;

@end
28 changes: 28 additions & 0 deletions MacGap/Classes/Commands/Command.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Command.m
// MacGap
//
// Created by Joe Hildebrand on 1/10/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import "Command.h"
#import <JavaScriptCore/JSContextRef.h>

@implementation Command

- (id) initWithContext:(JSContextRef)aContext {
self = [super init];
if (!self)
return nil;
context = aContext;
JSGlobalContextRetain((JSGlobalContextRef)context);
return self;
}

- (void)dealloc
{
if (context)
JSGlobalContextRelease((JSGlobalContextRef)context);
}
@end
29 changes: 29 additions & 0 deletions MacGap/Classes/Commands/MenuItemProxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// MenuItemProxy.h
// MacGap
//
// Created by Joe Hildebrand on 1/15/12.
// Copyright (c) 2012 Twitter. All rights reserved.
//

#import "Command.h"
#import "CallbackDelegate.h"

@class MenuProxy;

@interface MenuItemProxy : Command {
NSMenuItem *item;
CallbackDelegate *callback;
}

+ (MenuItemProxy*) proxyWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem;

- (MenuProxy*)addSubmenu;

- (void) remove;
- (void)setCallback:(WebScriptObject*)aCallback;
- (void)setKey:(NSString*)keyCommand;
- (void) setTitle:(NSString*)title;
- (MenuProxy*)submenu;

@end
Loading

0 comments on commit 3f927e1

Please sign in to comment.