mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-07-14 09:03:14 -07:00
Move mac-ui into src/
This commit is contained in:
parent
a40192a40b
commit
8594e17f2b
63 changed files with 0 additions and 0 deletions
18
ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.h
Normal file
18
ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// AppDelegate.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Alex MacCaw on 08/01/2012.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "Classes/ContentView.h"
|
||||
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (retain, nonatomic) WindowController *windowController;
|
||||
|
||||
@end
|
145
ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.m
Normal file
145
ext/mac-ui-macgap1-wrapper/src/MacGap/AppDelegate.m
Normal file
|
@ -0,0 +1,145 @@
|
|||
//
|
||||
// AppDelegate.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Alex MacCaw on 08/01/2012.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@synthesize windowController;
|
||||
|
||||
- (void) applicationWillFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
}
|
||||
|
||||
-(BOOL)applicationShouldHandleReopen:(NSApplication*)application
|
||||
hasVisibleWindows:(BOOL)visibleWindows{
|
||||
if(!visibleWindows){
|
||||
[self.windowController.window makeKeyAndOrderFront: nil];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
char buf[16384],userAuthTokenPath[4096];
|
||||
|
||||
FILE *pf = fopen("/Library/Application Support/ZeroTier/One/zerotier-one.port","r");
|
||||
long port = 9993; // default
|
||||
if (pf) {
|
||||
long n = fread(buf,1,sizeof(buf)-1,pf);
|
||||
if (n > 0) {
|
||||
buf[n] = (char)0;
|
||||
port = strtol(buf,(char **)0,10);
|
||||
}
|
||||
fclose(pf);
|
||||
}
|
||||
|
||||
char url[16384];
|
||||
memset(url,0,sizeof(url));
|
||||
|
||||
const char *homeDir = getenv("HOME");
|
||||
if (homeDir) {
|
||||
snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One/authtoken.secret",homeDir);
|
||||
pf = fopen(userAuthTokenPath,"r");
|
||||
if (pf) {
|
||||
long n = fread(buf,1,sizeof(buf)-1,pf);
|
||||
if (n > 0) {
|
||||
buf[n] = (char)0;
|
||||
snprintf(url,sizeof(url),"http://127.0.0.1:%ld/index.html?authToken=%s",port,buf);
|
||||
}
|
||||
fclose(pf);
|
||||
}
|
||||
}
|
||||
|
||||
if (!url[0]) {
|
||||
// Create authorization reference
|
||||
OSStatus status;
|
||||
AuthorizationRef authorizationRef;
|
||||
|
||||
// AuthorizationCreate and pass NULL as the initial
|
||||
// AuthorizationRights set so that the AuthorizationRef gets created
|
||||
// successfully, and then later call AuthorizationCopyRights to
|
||||
// determine or extend the allowable rights.
|
||||
// http://developer.apple.com/qa/qa2001/qa1172.html
|
||||
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
|
||||
if (status != errAuthorizationSuccess)
|
||||
{
|
||||
NSLog(@"Error Creating Initial Authorization: %d", status);
|
||||
return;
|
||||
}
|
||||
|
||||
// kAuthorizationRightExecute == "system.privilege.admin"
|
||||
AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0};
|
||||
AuthorizationRights rights = {1, &right};
|
||||
AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
|
||||
|
||||
// Call AuthorizationCopyRights to determine or extend the allowable rights.
|
||||
status = AuthorizationCopyRights(authorizationRef, &rights, NULL, flags, NULL);
|
||||
if (status != errAuthorizationSuccess)
|
||||
{
|
||||
NSLog(@"Copy Rights Unsuccessful: %d", status);
|
||||
return;
|
||||
}
|
||||
|
||||
// use rm tool with -rf
|
||||
char *tool = "/bin/cat";
|
||||
char *args[] = {"/Library/Application Support/ZeroTier/One/authtoken.secret", NULL};
|
||||
FILE *pipe = NULL;
|
||||
|
||||
status = AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe);
|
||||
if (status != errAuthorizationSuccess)
|
||||
{
|
||||
NSLog(@"Error: %d", status);
|
||||
}
|
||||
|
||||
if (pipe) {
|
||||
long n = (long)fread(buf,1,sizeof(buf)-1,pipe);
|
||||
if (n > 0) {
|
||||
buf[n] = (char)0;
|
||||
snprintf(url,sizeof(url),"http://127.0.0.1:%ld/index.html?authToken=%s",port,buf);
|
||||
|
||||
if (homeDir) {
|
||||
snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier",homeDir);
|
||||
mkdir(userAuthTokenPath,0755);
|
||||
snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One",homeDir);
|
||||
mkdir(userAuthTokenPath,0755);
|
||||
snprintf(userAuthTokenPath,sizeof(userAuthTokenPath),"%s/Library/Application Support/ZeroTier/One/authtoken.secret",homeDir);
|
||||
pf = fopen(userAuthTokenPath,"w");
|
||||
if (pf) {
|
||||
fwrite(buf,1,strlen(buf),pf);
|
||||
fclose(pf);
|
||||
chmod(userAuthTokenPath,0600);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(pipe);
|
||||
}
|
||||
|
||||
// The only way to guarantee that a credential acquired when you
|
||||
// request a right is not shared with other authorization instances is
|
||||
// to destroy the credential. To do so, call the AuthorizationFree
|
||||
// function with the flag kAuthorizationFlagDestroyRights.
|
||||
// http://developer.apple.com/documentation/Security/Conceptual/authorization_concepts/02authconcepts/chapter_2_section_7.html
|
||||
status = AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
|
||||
}
|
||||
|
||||
NSString *urlStr = [[NSString alloc] initWithCString:url];
|
||||
self.windowController = [[WindowController alloc] initWithURL: urlStr];
|
||||
[self.windowController showWindow: [NSApplication sharedApplication].delegate];
|
||||
self.windowController.contentView.webView.alphaValue = 1.0;
|
||||
self.windowController.contentView.alphaValue = 1.0;
|
||||
[self.windowController showWindow:self];
|
||||
}
|
||||
|
||||
@end
|
20
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.h
Executable file
20
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.h
Executable file
|
@ -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
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.m
Executable file
168
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/CallbackDelegate.m
Executable file
|
@ -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
|
21
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.h
Normal file
21
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface App : NSObject {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) WebView *webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *)view;
|
||||
|
||||
- (void) terminate;
|
||||
- (void) activate;
|
||||
- (void) hide;
|
||||
- (void) unhide;
|
||||
- (void) beep;
|
||||
- (void) bounce;
|
||||
- (void) setCustomUserAgent:(NSString *)userAgentString;
|
||||
- (NSNumber*) systemIdleTime;
|
||||
@end
|
128
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.m
Normal file
128
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/App.m
Normal file
|
@ -0,0 +1,128 @@
|
|||
#import "App.h"
|
||||
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@implementation App
|
||||
|
||||
@synthesize webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *) view{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
self.webView = view;
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
|
||||
selector: @selector(receiveSleepNotification:)
|
||||
name: NSWorkspaceWillSleepNotification object: NULL];
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
|
||||
selector: @selector(receiveWakeNotification:)
|
||||
name: NSWorkspaceDidWakeNotification object: NULL];
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
|
||||
selector: @selector(receiveActivateNotification:)
|
||||
name: NSWorkspaceDidActivateApplicationNotification object: NULL];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) terminate {
|
||||
[NSApp terminate:nil];
|
||||
}
|
||||
|
||||
- (void) activate {
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
- (void) hide {
|
||||
[NSApp hide:nil];
|
||||
}
|
||||
|
||||
- (void) unhide {
|
||||
[NSApp unhide:nil];
|
||||
}
|
||||
|
||||
- (void)beep {
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
- (void) bounce {
|
||||
[NSApp requestUserAttention:NSInformationalRequest];
|
||||
}
|
||||
|
||||
- (void)setCustomUserAgent:(NSString *)userAgentString {
|
||||
[self.webView setCustomUserAgent: userAgentString];
|
||||
}
|
||||
|
||||
- (void) open:(NSString*)url {
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:url]];
|
||||
}
|
||||
|
||||
- (void) launch:(NSString *)name {
|
||||
[[NSWorkspace sharedWorkspace] launchApplication:name];
|
||||
}
|
||||
|
||||
- (void)receiveSleepNotification:(NSNotification*)note{
|
||||
[JSEventHelper triggerEvent:@"sleep" forWebView:self.webView];
|
||||
}
|
||||
|
||||
- (void) receiveWakeNotification:(NSNotification*)note{
|
||||
[JSEventHelper triggerEvent:@"wake" forWebView:self.webView];
|
||||
}
|
||||
|
||||
- (void) receiveActivateNotification:(NSNotification*)notification{
|
||||
NSDictionary* userInfo = [notification userInfo];
|
||||
NSRunningApplication* runningApplication = [userInfo objectForKey:NSWorkspaceApplicationKey];
|
||||
if (runningApplication) {
|
||||
NSMutableDictionary* applicationDidGetFocusDict = [[NSMutableDictionary alloc] initWithCapacity:2];
|
||||
[applicationDidGetFocusDict setObject:runningApplication.localizedName
|
||||
forKey:@"localizedName"];
|
||||
[applicationDidGetFocusDict setObject:[runningApplication.bundleURL absoluteString]
|
||||
forKey:@"bundleURL"];
|
||||
|
||||
[JSEventHelper triggerEvent:@"appActivated" withArgs:applicationDidGetFocusDict forWebView:self.webView];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
To get the elapsed time since the previous input event—keyboard, mouse, or tablet—specify kCGAnyInputEventType.
|
||||
*/
|
||||
- (NSNumber*)systemIdleTime {
|
||||
CFTimeInterval timeSinceLastEvent = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateHIDSystemState, kCGAnyInputEventType);
|
||||
|
||||
return [NSNumber numberWithDouble:timeSinceLastEvent];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(open:)) {
|
||||
result = @"open";
|
||||
} else if (selector == @selector(launch:)) {
|
||||
result = @"launch";
|
||||
} else if (selector == @selector(setCustomUserAgent:)) {
|
||||
result = @"setCustomUserAgent";
|
||||
} else if (selector == @selector(systemIdleTime)) {
|
||||
result = @"systemIdleTime";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
18
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.h
Executable file
18
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.h
Executable file
|
@ -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
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.m
Executable file
28
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Command.m
Executable file
|
@ -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
|
|
@ -0,0 +1,11 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Dock : NSObject {
|
||||
|
||||
}
|
||||
- (void) setBadge:(NSString*)value;
|
||||
- (NSString *) badge;
|
||||
|
||||
@property (readwrite, copy) NSString *badge;
|
||||
|
||||
@end
|
|
@ -0,0 +1,31 @@
|
|||
#import "Dock.h"
|
||||
|
||||
@implementation Dock
|
||||
|
||||
@synthesize badge;
|
||||
|
||||
- (void) setBadge:(NSString *)value
|
||||
{
|
||||
NSDockTile *tile = [[NSApplication sharedApplication] dockTile];
|
||||
[tile setBadgeLabel:value];
|
||||
}
|
||||
|
||||
- (NSString *) badge
|
||||
{
|
||||
NSDockTile *tile = [[NSApplication sharedApplication] dockTile];
|
||||
return [tile badgeLabel];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
31
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.h
Executable file
31
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.h
Executable file
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// 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;
|
||||
- (void) enable;
|
||||
- (void) disable;
|
||||
- (MenuProxy*)submenu;
|
||||
|
||||
@end
|
150
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.m
Executable file
150
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuItemProxy.m
Executable file
|
@ -0,0 +1,150 @@
|
|||
//
|
||||
// MenuItemProxy.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/15/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MenuItemProxy.h"
|
||||
#import "MenuProxy.h"
|
||||
|
||||
@implementation MenuItemProxy
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem
|
||||
{
|
||||
NSAssert(anItem, @"anItem required");
|
||||
self = [super initWithContext:aContext];
|
||||
if (!self)
|
||||
return nil;
|
||||
item = anItem;
|
||||
item.representedObject = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (MenuItemProxy*) proxyWithContext:(JSContextRef)aContext andMenuItem:(NSMenuItem*)anItem
|
||||
{
|
||||
MenuItemProxy *proxy = [anItem representedObject];
|
||||
if (proxy)
|
||||
{
|
||||
NSLog(@"MIP Cache hit");
|
||||
NSAssert([proxy class] == [MenuItemProxy class], @"Bad proxy");
|
||||
return proxy;
|
||||
}
|
||||
return [[MenuItemProxy alloc] initWithContext:aContext andMenuItem:anItem];
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [item description];
|
||||
}
|
||||
|
||||
- (MenuProxy*)addSubmenu
|
||||
{
|
||||
NSMenu *s = [item submenu];
|
||||
if (!s)
|
||||
{
|
||||
s = [[NSMenu alloc] initWithTitle:@"FFFFFFOOOOO"];
|
||||
[item setSubmenu:s];
|
||||
}
|
||||
return [MenuProxy proxyWithContext:context andMenu:s];
|
||||
}
|
||||
|
||||
- (void) remove
|
||||
{
|
||||
NSMenu *menu = [item menu];
|
||||
[menu removeItem:item];
|
||||
}
|
||||
|
||||
- (void)callCallback:(id)sender
|
||||
{
|
||||
[callback callWithParams:[sender title], nil];
|
||||
}
|
||||
|
||||
- (void) setCallback:(WebScriptObject*)aCallback
|
||||
{
|
||||
NSAssert(item, @"item required");
|
||||
callback = [[CallbackDelegate alloc] initWithContext:context forCallback:aCallback];
|
||||
[item setAction:@selector(callCallback:)];
|
||||
[item setTarget:self];
|
||||
}
|
||||
|
||||
- (void)setKey:(NSString*)keyCommand
|
||||
{
|
||||
NSString *aKey = [MenuProxy getKeyFromString:keyCommand];
|
||||
[item setKeyEquivalent:aKey];
|
||||
|
||||
NSUInteger modifiers = [MenuProxy getModifiersFromString:keyCommand];
|
||||
[item setKeyEquivalentModifierMask:modifiers];
|
||||
}
|
||||
|
||||
- (void) setTitle:(NSString*)title
|
||||
{
|
||||
[item setTitle:title];
|
||||
}
|
||||
|
||||
- (MenuProxy*)submenu;
|
||||
{
|
||||
// TODO: make this work as a property
|
||||
NSMenu *s = [item submenu];
|
||||
if (!s)
|
||||
return nil;
|
||||
return [MenuProxy proxyWithContext:context andMenu:s];
|
||||
}
|
||||
|
||||
- (void) enable
|
||||
{
|
||||
[item setEnabled:YES];
|
||||
}
|
||||
|
||||
- (void) disable
|
||||
{
|
||||
[item setEnabled:NO];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return [self webScriptNameForSelector:selector] == nil;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(addSubmenu)) {
|
||||
result = @"addSubmenu";
|
||||
}
|
||||
else if (selector == @selector(remove)) {
|
||||
result = @"remove";
|
||||
}
|
||||
else if (selector == @selector(setCallback:)) {
|
||||
result = @"setCallback";
|
||||
}
|
||||
else if (selector == @selector(setKey:)) {
|
||||
result = @"setKey";
|
||||
}
|
||||
else if (selector == @selector(setTitle:)) {
|
||||
result = @"setTitle";
|
||||
}
|
||||
else if (selector == @selector(submenu)) {
|
||||
result = @"submenu";
|
||||
}
|
||||
else if (selector == @selector(enable)) {
|
||||
result = @"enable";
|
||||
}
|
||||
else if (selector == @selector(disable)) {
|
||||
result = @"disable";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
31
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.h
Executable file
31
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.h
Executable file
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// MenuProxy.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/14/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Command.h"
|
||||
|
||||
@class MenuItemProxy;
|
||||
|
||||
@interface MenuProxy : Command {
|
||||
NSMenu *menu;
|
||||
}
|
||||
|
||||
+ (MenuProxy*)proxyWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu;
|
||||
|
||||
- (MenuItemProxy*)addItemWithTitle:(NSString*)title
|
||||
keyEquivalent:(NSString*)aKey
|
||||
callback:(WebScriptObject*)aCallback
|
||||
atIndex:(NSInteger)index;
|
||||
|
||||
- (MenuItemProxy*)addSeparator;
|
||||
- (MenuItemProxy*)itemForKey:(id)key;
|
||||
- (MenuProxy*)removeItem:(id)key;
|
||||
|
||||
+ (NSString*)getKeyFromString:(NSString*)keyCommand;
|
||||
+ (NSUInteger*)getModifiersFromString:(NSString*)keyCommand;
|
||||
|
||||
@end
|
233
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.m
Executable file
233
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/MenuProxy.m
Executable file
|
@ -0,0 +1,233 @@
|
|||
//
|
||||
// MenuProxy.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Joe Hildebrand on 1/14/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#import <JavaScriptCore/JavaScript.h>
|
||||
|
||||
#import "MenuProxy.h"
|
||||
#import "MenuItemProxy.h"
|
||||
|
||||
static char REPRESENTED_OBJECT;
|
||||
|
||||
@interface NSMenu (represented)
|
||||
@property (strong) id representedObject;
|
||||
@end
|
||||
|
||||
@implementation NSMenu (represented)
|
||||
|
||||
- (id) representedObject
|
||||
{
|
||||
return objc_getAssociatedObject(self, &REPRESENTED_OBJECT);
|
||||
}
|
||||
|
||||
- (void) setRepresentedObject:(id)representedObject
|
||||
{
|
||||
objc_setAssociatedObject(self,
|
||||
&REPRESENTED_OBJECT,
|
||||
representedObject,
|
||||
OBJC_ASSOCIATION_RETAIN);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MenuProxy
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu
|
||||
{
|
||||
self = [super initWithContext:aContext];
|
||||
if (!self)
|
||||
return nil;
|
||||
menu = aMenu;
|
||||
menu.representedObject = self;
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (MenuProxy*)proxyWithContext:(JSContextRef)aContext andMenu:(NSMenu*)aMenu
|
||||
{
|
||||
// singleton-ish.
|
||||
MenuProxy *ret = [aMenu representedObject];
|
||||
if (ret)
|
||||
{
|
||||
NSLog(@"MP cache hit");
|
||||
return ret;
|
||||
}
|
||||
return [[MenuProxy alloc] initWithContext:aContext andMenu:aMenu];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
menu.representedObject = nil;
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [menu description];
|
||||
}
|
||||
|
||||
static BOOL isNullish(id o)
|
||||
{
|
||||
if (!o)
|
||||
return YES;
|
||||
if ([o isKindOfClass:[WebUndefined class]])
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (MenuItemProxy*)addItemWithTitle:(NSString*)title
|
||||
keyEquivalent:(NSString*)keyCommand
|
||||
callback:(WebScriptObject*)aCallback
|
||||
atIndex:(NSInteger)index
|
||||
{
|
||||
if (isNullish(title))
|
||||
title = @"";
|
||||
|
||||
NSString *aKey = [MenuProxy getKeyFromString:keyCommand];
|
||||
NSMenuItem *item = nil;
|
||||
|
||||
if(index) {
|
||||
item = [menu insertItemWithTitle:title action:nil keyEquivalent:aKey atIndex:index ];
|
||||
} else {
|
||||
item = [menu addItemWithTitle:title action:nil keyEquivalent:aKey ];
|
||||
|
||||
}
|
||||
|
||||
// Set the modifiers.
|
||||
NSUInteger modifiers = [MenuProxy getModifiersFromString:keyCommand];
|
||||
[item setKeyEquivalentModifierMask:modifiers];
|
||||
|
||||
if(!menu.supermenu) {
|
||||
NSMenu *s = [[NSMenu alloc] initWithTitle:title];
|
||||
[item setSubmenu:s];
|
||||
}
|
||||
|
||||
MenuItemProxy *mip = [MenuItemProxy proxyWithContext:context andMenuItem:item];
|
||||
if (!isNullish(aCallback))
|
||||
[mip setCallback:aCallback];
|
||||
|
||||
|
||||
return mip;
|
||||
}
|
||||
|
||||
+ (NSString*)getKeyFromString:(NSString*)keyCommand {
|
||||
if (isNullish(keyCommand))
|
||||
keyCommand = @"";
|
||||
|
||||
// Obtain the key (if there are modifiers, it will be the last character).
|
||||
NSString *aKey = @"";
|
||||
if ([keyCommand length] > 0) {
|
||||
aKey = [keyCommand substringFromIndex:[keyCommand length] - 1];
|
||||
}
|
||||
|
||||
return aKey;
|
||||
}
|
||||
|
||||
+ (NSUInteger*)getModifiersFromString:(NSString*)keyCommand {
|
||||
// aKeys may optionally specify one or more modifiers.
|
||||
NSUInteger modifiers = 0;
|
||||
|
||||
if ([keyCommand rangeOfString:@"caps"].location != NSNotFound) modifiers += NSAlphaShiftKeyMask;
|
||||
if ([keyCommand rangeOfString:@"shift"].location != NSNotFound) modifiers += NSShiftKeyMask;
|
||||
if ([keyCommand rangeOfString:@"cmd"].location != NSNotFound) modifiers += NSCommandKeyMask;
|
||||
if ([keyCommand rangeOfString:@"ctrl"].location != NSNotFound) modifiers += NSControlKeyMask;
|
||||
if ([keyCommand rangeOfString:@"opt"].location != NSNotFound) modifiers += NSAlternateKeyMask;
|
||||
if ([keyCommand rangeOfString:@"alt"].location != NSNotFound) modifiers += NSAlternateKeyMask;
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
- (MenuItemProxy*)addSeparator
|
||||
{
|
||||
NSMenuItem *sep = [NSMenuItem separatorItem];
|
||||
[menu addItem:sep];
|
||||
return [MenuItemProxy proxyWithContext:context andMenuItem:sep];
|
||||
}
|
||||
|
||||
- (MenuItemProxy*)itemForKey:(id)key
|
||||
{
|
||||
if (isNullish(key))
|
||||
return nil;
|
||||
NSMenuItem *item = nil;
|
||||
if ([key isKindOfClass:[NSNumber class]])
|
||||
{
|
||||
item = [menu itemAtIndex:[key intValue]];
|
||||
}
|
||||
else if ([key isKindOfClass:[NSString class]])
|
||||
{
|
||||
item = [menu itemWithTitle:key];
|
||||
if (!item)
|
||||
{
|
||||
// Try again, with ... appended. e.g. "Save..."
|
||||
item = [menu itemWithTitle:
|
||||
[key stringByAppendingString:@"\u2026"]];
|
||||
}
|
||||
}
|
||||
if (!item)
|
||||
return nil;
|
||||
|
||||
return [MenuItemProxy proxyWithContext:context andMenuItem:item];
|
||||
}
|
||||
|
||||
- (MenuProxy*)removeItem:(id)key
|
||||
{
|
||||
if (isNullish(key))
|
||||
return nil;
|
||||
|
||||
NSMenuItem *item = nil;
|
||||
if ([key isKindOfClass:[NSNumber class]])
|
||||
{
|
||||
item = [menu itemAtIndex:[key intValue]];
|
||||
}
|
||||
else if ([key isKindOfClass:[NSString class]])
|
||||
{
|
||||
item = [menu itemWithTitle:key];
|
||||
if (!item)
|
||||
{
|
||||
// Try again, with ... appended. e.g. "Save..."
|
||||
item = [menu itemWithTitle:
|
||||
[key stringByAppendingString:@"\u2026"]];
|
||||
}
|
||||
}
|
||||
if (!item)
|
||||
return nil;
|
||||
|
||||
[menu removeItem:item];
|
||||
return [MenuProxy proxyWithContext:context andMenu:menu];
|
||||
}
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return [self webScriptNameForSelector:selector] == nil;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(addItemWithTitle:keyEquivalent:callback:atIndex:)) {
|
||||
result = @"addItem";
|
||||
}
|
||||
else if (selector == @selector(addSeparator)) {
|
||||
result = @"addSeparator";
|
||||
}
|
||||
else if (selector == @selector(itemForKey:)) {
|
||||
result = @"getItem";
|
||||
}
|
||||
else if (selector == @selector(removeItem:)) {
|
||||
result = @"removeMenu";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@end
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// Notice.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Christian Sullivan on 7/26/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "WindowController.h"
|
||||
|
||||
#define APP_NOTICE_NOTIFICATION @"Notice"
|
||||
|
||||
@interface Notice : NSObject <NSUserNotificationCenterDelegate> {
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) WebView *webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *)view;
|
||||
- (void) notify:(NSDictionary*)message;
|
||||
- (void) close:(NSString*)notificationId;
|
||||
+ (BOOL) available;
|
||||
|
||||
@end
|
||||
|
108
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Notice.m
Normal file
108
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Commands/Notice.m
Normal file
|
@ -0,0 +1,108 @@
|
|||
//
|
||||
// Notice.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Christian Sullivan on 7/26/12.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Notice.h"
|
||||
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@implementation Notice
|
||||
|
||||
- (id) initWithWebView:(WebView*)view
|
||||
{
|
||||
if(self = [super init]) {
|
||||
self.webView = view;
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) notify:(NSDictionary *)message {
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
[notification setTitle:[message valueForKey:@"title"]];
|
||||
[notification setInformativeText:[message valueForKey:@"content"]];
|
||||
[notification setDeliveryDate:[NSDate dateWithTimeInterval:0 sinceDate:[NSDate date]]];
|
||||
BOOL playSound = true; // optional parameter, false only when {sound: false}
|
||||
@try {
|
||||
NSNumber *s = [message valueForKey:@"sound"];
|
||||
if ([[s className] isEqual: @"__NSCFBoolean"]) {
|
||||
playSound = [s boolValue];
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
}
|
||||
if (playSound) {
|
||||
[notification setSoundName:NSUserNotificationDefaultSoundName];
|
||||
}
|
||||
NSString *id = @""; // optional, needed for close
|
||||
@try {
|
||||
id = [message valueForKey:@"id"];
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
}
|
||||
[notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:id, @"id", nil]];
|
||||
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
|
||||
[center scheduleNotification:notification];
|
||||
}
|
||||
|
||||
// close all notifications with id == notificationId or close all notifications if notificationId == "*"
|
||||
- (void) close:(NSString*)notificationId {
|
||||
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
|
||||
for(NSUserNotification * deliveredNote in center.deliveredNotifications) {
|
||||
if ([notificationId isEqualToString:@"*"] || [deliveredNote.userInfo[@"id"] isEqualToString:notificationId]) {
|
||||
[center removeDeliveredNotification: deliveredNote];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL) available {
|
||||
if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)])
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
|
||||
{
|
||||
NSString *notificationId = [notification.userInfo valueForKey:@"id"];
|
||||
[JSEventHelper triggerEvent:@"macgap.notify.activated" forDetail:notificationId forWebView:self.webView];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
BOOL result = YES;
|
||||
if (selector == @selector(notify:))
|
||||
result = NO;
|
||||
if (selector == @selector(close:))
|
||||
result = NO;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(notify:)) {
|
||||
result = @"notify";
|
||||
}
|
||||
if (selector == @selector(close:)) {
|
||||
result = @"close";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// right now exclude all properties (eg keys)
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,21 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Path : NSObject {
|
||||
|
||||
}
|
||||
|
||||
- (NSString *) application;
|
||||
- (NSString *) resource;
|
||||
- (NSString *) documents;
|
||||
- (NSString *) library;
|
||||
- (NSString *) home;
|
||||
- (NSString *) temp;
|
||||
|
||||
@property (readonly,copy) NSString* application;
|
||||
@property (readonly,copy) NSString* resource;
|
||||
@property (readonly,copy) NSString* documents;
|
||||
@property (readonly,copy) NSString* library;
|
||||
@property (readonly,copy) NSString* home;
|
||||
@property (readonly,copy) NSString* temp;
|
||||
|
||||
@end
|
|
@ -0,0 +1,53 @@
|
|||
#import "Path.h"
|
||||
|
||||
@implementation Path
|
||||
|
||||
@synthesize application;
|
||||
@synthesize resource;
|
||||
@synthesize documents;
|
||||
@synthesize library;
|
||||
@synthesize home;
|
||||
@synthesize temp;
|
||||
|
||||
- (NSString *)application {
|
||||
return [[NSBundle mainBundle] bundlePath];
|
||||
}
|
||||
|
||||
- (NSString *)resource {
|
||||
return [[NSBundle mainBundle] resourcePath];
|
||||
}
|
||||
|
||||
- (NSString *)documents {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
return [paths objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (NSString *)library {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
|
||||
NSLog( @"%@", paths );
|
||||
return [paths objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (NSString *)home {
|
||||
return NSHomeDirectory();
|
||||
}
|
||||
|
||||
- (NSString *)temp {
|
||||
return NSTemporaryDirectory();
|
||||
}
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
/* checks whether a selector is acceptable to be called from JavaScript */
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
// right now exclude all properties (eg keys)
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,17 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import "Command.h"
|
||||
#import "CallbackDelegate.h"
|
||||
|
||||
|
||||
@interface Sound : Command {
|
||||
|
||||
}
|
||||
|
||||
// pending callbacks for sounds being played, to keep
|
||||
// ARC from freeing them too early
|
||||
@property (nonatomic, strong) NSMutableSet *pending;
|
||||
|
||||
- (void) play:(NSString*)file onComplete:(WebScriptObject*)callback;
|
||||
- (void) playSystem:(NSString*)name onComplete:(WebScriptObject*)callback;
|
||||
|
||||
@end
|
|
@ -0,0 +1,97 @@
|
|||
#import "Sound.h"
|
||||
|
||||
|
||||
@interface PlayDelegate : CallbackDelegate <NSSoundDelegate> {
|
||||
}
|
||||
|
||||
@property (nonatomic, weak) Sound *sound;
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext
|
||||
forCallback:(WebScriptObject*)aCallback
|
||||
withSound:(Sound*)aSound;
|
||||
@end
|
||||
|
||||
@implementation PlayDelegate
|
||||
|
||||
@synthesize sound;
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext
|
||||
forCallback:(WebScriptObject*)aCallback
|
||||
withSound:(Sound*)aSound
|
||||
{
|
||||
self = [super initWithContext:aContext forCallback:aCallback];
|
||||
if (!self)
|
||||
return nil;
|
||||
sound = aSound;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)sound:(NSSound *)aSound didFinishPlaying:(BOOL)finishedPlaying {
|
||||
[self callWithParams:[aSound name], nil];
|
||||
[sound.pending removeObject:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation Sound
|
||||
|
||||
@synthesize pending;
|
||||
|
||||
- (id) initWithContext:(JSContextRef)aContext {
|
||||
self = [super initWithContext:aContext];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
pending = [NSMutableSet new];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) playSound:(NSSound*)sound onComplete:(WebScriptObject*)callback {
|
||||
if (callback != (id)[WebUndefined undefined]) {
|
||||
PlayDelegate *d = [[PlayDelegate alloc] initWithContext:context
|
||||
forCallback:callback
|
||||
withSound:self];
|
||||
[pending addObject:d];
|
||||
[sound setDelegate:d];
|
||||
}
|
||||
[sound play];
|
||||
}
|
||||
|
||||
- (void) play:(NSString*)file onComplete:(WebScriptObject*)callback {
|
||||
NSURL* fileUrl = [NSURL fileURLWithPath:[[Utils sharedInstance] pathForResource:file]];
|
||||
DebugNSLog(@"Sound file:%@", [fileUrl description]);
|
||||
|
||||
NSSound* sound = [[NSSound alloc] initWithContentsOfURL:fileUrl byReference:YES];
|
||||
[self playSound:sound onComplete:callback];
|
||||
}
|
||||
|
||||
- (void) playSystem:(NSString*)name onComplete:(WebScriptObject*)callback {
|
||||
NSSound *systemSound = [NSSound soundNamed:name];
|
||||
[self playSound:systemSound onComplete:callback];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
|
||||
return [self webScriptNameForSelector:selector] == nil;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name {
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector {
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(play:onComplete:)) {
|
||||
result = @"play";
|
||||
}
|
||||
else if (selector == @selector(playSystem:onComplete:)) {
|
||||
result = @"playSystem";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// UserDefaults.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Jeff Hanbury on 16/04/2014.
|
||||
// Copyright (c) 2014 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface UserDefaults : NSObject
|
||||
|
||||
@property (nonatomic, retain) WebView *webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *)view;
|
||||
- (NSString*) getMyDefaults;
|
||||
- (NSDictionary*) myDefaultsDictionary;
|
||||
- (void) removeObjectForKey:(NSString*)key;
|
||||
- (NSArray*) getUserDefaultsKeys;
|
||||
|
||||
- (NSString*) addPrefix:(NSString*)key;
|
||||
|
||||
- (void) setString:(NSString*)key withValue:(NSString*)value;
|
||||
- (NSString*) getString:(NSString*)key;
|
||||
|
||||
- (void) setInteger:(NSString*)key withValue:(NSString*)value;
|
||||
- (NSNumber*) getInteger:(NSString*)key;
|
||||
|
||||
- (void) setBool:(NSString*)key withValue:(NSString*)value;
|
||||
- (NSNumber*) getBool:(NSString*)key;
|
||||
|
||||
- (void) setFloat:(NSString*)key withValue:(NSString*)value;
|
||||
- (NSNumber*) getFloat:(NSString*)key;
|
||||
|
||||
// Could also be implemented:
|
||||
//– setObject:forKey:
|
||||
//– setDouble:forKey:
|
||||
//– setURL:forKey:
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
//
|
||||
// UserDefaults.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Jeff Hanbury on 16/04/2014.
|
||||
// Copyright (c) 2014 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UserDefaults.h"
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@interface UserDefaults() {
|
||||
|
||||
}
|
||||
|
||||
-(void) setupNotificationCenter;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation UserDefaults
|
||||
|
||||
- (id) initWithWebView:(WebView *) view{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
self.webView = view;
|
||||
[self setupNotificationCenter];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
-(void) setupNotificationCenter{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(defaultsChanged:)
|
||||
name:NSUserDefaultsDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)defaultsChanged:(NSNotification *)notification {
|
||||
NSDictionary* returnDict = [self myDefaultsDictionary];
|
||||
[JSEventHelper triggerEvent:@"userDefaultsChanged" withArgs:returnDict forWebView:self.webView];
|
||||
}
|
||||
|
||||
- (NSString*) getMyDefaults {
|
||||
NSDictionary* myDefaults = [self myDefaultsDictionary];
|
||||
|
||||
return [[Utils sharedInstance] convertDictionaryToJSON:myDefaults];
|
||||
}
|
||||
|
||||
- (NSDictionary*) myDefaultsDictionary {
|
||||
NSString* prefix = [kWebScriptNamespace stringByAppendingString:@"_"];
|
||||
NSMutableDictionary* returnDict = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// Get the user defaults.
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
// Build up a dictionary containing just the items beginning with our
|
||||
// prefix.
|
||||
for (NSString* key in [self getUserDefaultsKeys]) {
|
||||
if ([key hasPrefix:prefix]) {
|
||||
id val = [defaults valueForKey:key];
|
||||
[returnDict setObject:val forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
return returnDict;
|
||||
}
|
||||
|
||||
- (NSArray*) getUserDefaultsKeys {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [[prefs dictionaryRepresentation] allKeys];
|
||||
}
|
||||
|
||||
- (void) removeObjectForKey:(NSString*)key {
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] removeObjectForKey:prefixedKey];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
// Check we have a standard prefix for JS-modified keys, for security purposes.
|
||||
// If not, add it. This stops JavaScript from ever being able to modify keys
|
||||
// it did not create.
|
||||
- (NSString*) addPrefix:(NSString*)key {
|
||||
NSString* prefix;
|
||||
prefix = [kWebScriptNamespace stringByAppendingString:@"_"];
|
||||
|
||||
if (![key hasPrefix:prefix]) {
|
||||
key = [prefix stringByAppendingString:key];
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// String
|
||||
|
||||
- (void) setString:(NSString*)key withValue:(NSString*)value {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
[prefs setObject:value forKey:prefixedKey];
|
||||
}
|
||||
|
||||
- (NSString*) getString:(NSString *)key {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [prefs stringForKey:key];
|
||||
}
|
||||
|
||||
// All the following must convert their type to NSNumber for JavaScript.
|
||||
|
||||
// Integer
|
||||
|
||||
- (void) setInteger:(NSString*)key withValue:(NSString*)value {
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
NSInteger myInt = [value intValue];
|
||||
[prefs setInteger:myInt forKey:prefixedKey];
|
||||
}
|
||||
|
||||
- (NSNumber*) getInteger:(NSString *)key {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [NSNumber numberWithInteger:[prefs integerForKey:key]];
|
||||
}
|
||||
|
||||
// Boolean
|
||||
|
||||
- (void) setBool:(NSString*)key withValue:(NSString*)value {
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
BOOL myBool = [value boolValue];
|
||||
[prefs setBool:myBool forKey:prefixedKey];
|
||||
}
|
||||
|
||||
- (NSNumber*) getBool:(NSString *)key {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [NSNumber numberWithBool:[prefs boolForKey:key]];
|
||||
}
|
||||
|
||||
// Float
|
||||
|
||||
- (void) setFloat:(NSString*)key withValue:(NSString*)value {
|
||||
NSString* prefixedKey;
|
||||
prefixedKey = [self addPrefix:key];
|
||||
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
float myFloat = [value floatValue];
|
||||
[prefs setFloat:myFloat forKey:prefixedKey];
|
||||
}
|
||||
|
||||
- (NSNumber*) getFloat:(NSString *)key {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [NSNumber numberWithFloat:[prefs floatForKey:key]];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector {
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(getMyDefaults)) {
|
||||
result = @"getMyDefaults";
|
||||
}
|
||||
|
||||
if (selector == @selector(removeObjectForKey:)) {
|
||||
result = @"removeObjectForKey";
|
||||
}
|
||||
|
||||
else if (selector == @selector(setString:withValue:)) {
|
||||
result = @"setString";
|
||||
} else if (selector == @selector(getString:)) {
|
||||
result = @"getString";
|
||||
}
|
||||
|
||||
else if (selector == @selector(setInteger:withValue:)) {
|
||||
result = @"setInteger";
|
||||
} else if (selector == @selector(getInteger:)) {
|
||||
result = @"getInteger";
|
||||
}
|
||||
|
||||
else if (selector == @selector(setBool:withValue:)) {
|
||||
result = @"setBool";
|
||||
} else if (selector == @selector(getBool:)) {
|
||||
result = @"getBool";
|
||||
}
|
||||
|
||||
else if (selector == @selector(setFloat:withValue:)) {
|
||||
result = @"setFloat";
|
||||
} else if (selector == @selector(getFloat:)) {
|
||||
result = @"getFloat";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,9 @@
|
|||
@interface Fonts : NSObject {
|
||||
}
|
||||
|
||||
- (NSArray*) availableFonts;
|
||||
- (NSArray*) availableFontFamilies;
|
||||
- (NSArray*) availableMembersOfFontFamily:(NSString*)fontFamily;
|
||||
- (CGFloat) defaultLineHeightForFont:(NSString *)theFontName ofSize:(CGFloat)theFontSize;
|
||||
|
||||
@end
|
|
@ -0,0 +1,48 @@
|
|||
#import "fonts.h"
|
||||
|
||||
@implementation Fonts
|
||||
|
||||
|
||||
- (NSArray*) availableFonts {
|
||||
return [[NSFontManager sharedFontManager] availableFonts];
|
||||
}
|
||||
|
||||
- (NSArray*) availableFontFamilies {
|
||||
return [[NSFontManager sharedFontManager] availableFontFamilies];
|
||||
}
|
||||
|
||||
- (NSArray*) availableMembersOfFontFamily:(NSString *)fontFamily {
|
||||
return [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily];
|
||||
}
|
||||
|
||||
- (CGFloat) defaultLineHeightForFont:(NSString*)theFontName ofSize:(CGFloat)theFontSize {
|
||||
NSFont *theFont = [NSFont fontWithName:theFontName size:theFontSize];
|
||||
NSLayoutManager *lm = [[NSLayoutManager alloc] init];
|
||||
|
||||
return [lm defaultLineHeightForFont:theFont];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark WebScripting Protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector {
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector {
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(availableMembersOfFontFamily:)) {
|
||||
result = @"availableMembersOfFontFamily";
|
||||
} else if (selector == @selector(defaultLineHeightForFont:ofSize:)) {
|
||||
result = @"defaultLineHeightForFont";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,7 @@
|
|||
// Application constants
|
||||
|
||||
#define kStartPage @"http://127.0.0.1:9993/"
|
||||
|
||||
#define kStartFolder @"."
|
||||
|
||||
#define kWebScriptNamespace @"macgap"
|
15
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.h
Normal file
15
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@class WebViewDelegate;
|
||||
|
||||
@interface ContentView : NSView {
|
||||
IBOutlet WebView* webView;
|
||||
WebViewDelegate* delegate;
|
||||
}
|
||||
|
||||
@property (retain) WebView* webView;
|
||||
@property (retain) WebViewDelegate* delegate;
|
||||
@property (strong) IBOutlet NSMenu *mainMenu;
|
||||
|
||||
@end
|
68
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.m
Normal file
68
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/ContentView.m
Normal file
|
@ -0,0 +1,68 @@
|
|||
#import "ContentView.h"
|
||||
#import "WebViewDelegate.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@interface WebPreferences (WebPreferencesPrivate)
|
||||
- (void)_setLocalStorageDatabasePath:(NSString *)path;
|
||||
- (void) setLocalStorageEnabled: (BOOL) localStorageEnabled;
|
||||
- (void) setDatabasesEnabled:(BOOL)databasesEnabled;
|
||||
- (void) setDeveloperExtrasEnabled:(BOOL)developerExtrasEnabled;
|
||||
- (void) setWebGLEnabled:(BOOL)webGLEnabled;
|
||||
- (void) setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEnabled;
|
||||
@end
|
||||
|
||||
@implementation ContentView
|
||||
|
||||
@synthesize webView, delegate, mainMenu;
|
||||
|
||||
- (void) awakeFromNib
|
||||
{
|
||||
WebPreferences *webPrefs = [WebPreferences standardPreferences];
|
||||
|
||||
NSString *cappBundleName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||
NSString *applicationSupportFile = [@"~/Library/Application Support/" stringByExpandingTildeInPath];
|
||||
NSString *savePath = [NSString pathWithComponents:[NSArray arrayWithObjects:applicationSupportFile, cappBundleName, @"LocalStorage", nil]];
|
||||
[webPrefs _setLocalStorageDatabasePath:savePath];
|
||||
[webPrefs setLocalStorageEnabled:YES];
|
||||
[webPrefs setDatabasesEnabled:YES];
|
||||
[webPrefs setDeveloperExtrasEnabled:[[NSUserDefaults standardUserDefaults] boolForKey: @"developer"]];
|
||||
[webPrefs setOfflineWebApplicationCacheEnabled:YES];
|
||||
[webPrefs setWebGLEnabled:YES];
|
||||
|
||||
[self.webView setPreferences:webPrefs];
|
||||
|
||||
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage
|
||||
sharedHTTPCookieStorage];
|
||||
[cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
|
||||
|
||||
[self.webView setApplicationNameForUserAgent: @"MacGap"];
|
||||
|
||||
self.delegate = [[WebViewDelegate alloc] initWithMenu:[NSApp mainMenu]];
|
||||
[self.webView setFrameLoadDelegate:self.delegate];
|
||||
[self.webView setUIDelegate:self.delegate];
|
||||
[self.webView setResourceLoadDelegate:self.delegate];
|
||||
[self.webView setDownloadDelegate:self.delegate];
|
||||
[self.webView setPolicyDelegate:self.delegate];
|
||||
[self.webView setDrawsBackground:NO];
|
||||
[self.webView setShouldCloseWithWindow:NO];
|
||||
|
||||
[self.webView setGroupName:@"MacGap"];
|
||||
|
||||
}
|
||||
|
||||
- (void) windowResized:(NSNotification*)notification;
|
||||
{
|
||||
NSWindow* window = (NSWindow*)notification.object;
|
||||
NSSize size = [window frame].size;
|
||||
|
||||
DebugNSLog(@"window width = %f, window height = %f", size.width, size.height);
|
||||
|
||||
bool isFullScreen = (window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask;
|
||||
int titleBarHeight = isFullScreen ? 0 : [[Utils sharedInstance] titleBarHeight:window];
|
||||
|
||||
[self.webView setFrame:NSMakeRect(0, 0, size.width, size.height - titleBarHeight)];
|
||||
[JSEventHelper triggerEvent:@"orientationchange" forWebView:self.webView];
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// Helper.h
|
||||
// MacGap
|
||||
//
|
||||
// Created by Liam Kaufman Simpkins on 12-01-22.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface JSEventHelper : NSObject
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event forWebView:(WebView *)webView;
|
||||
+ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forWebView:(WebView *)webView;
|
||||
+ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forObject:(NSString *)objName forWebView:(WebView *)webView;
|
||||
+ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forWebView:(WebView *)webView;
|
||||
+ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forObject:(NSString *)objName forWebView:(WebView *)webView;
|
||||
|
||||
@end
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Helper.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Liam Kaufman Simpkins on 12-01-22.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JSEventHelper.h"
|
||||
|
||||
@implementation JSEventHelper
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event forWebView:(WebView *)webView {
|
||||
[self triggerEvent:event withArgs:[NSMutableDictionary dictionary] forObject:@"document" forWebView:webView];
|
||||
}
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forWebView:(WebView *)webView {
|
||||
[self triggerEvent:event withArgs:args forObject:@"document" forWebView:webView];
|
||||
}
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event withArgs:(NSDictionary *)args forObject:(NSString *)objName forWebView:(WebView *)webView {
|
||||
|
||||
// Convert args Dictionary to JSON.
|
||||
NSString* jsonString = [[Utils sharedInstance] convertDictionaryToJSON:args];
|
||||
|
||||
// Create the event JavaScript and run it.
|
||||
NSString * str = [NSString stringWithFormat:@"var e = document.createEvent('Events'); e.initEvent('%@', true, false); e.data=%@; %@.dispatchEvent(e); ", event, jsonString, objName];
|
||||
[webView stringByEvaluatingJavaScriptFromString:str];
|
||||
}
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forWebView:(WebView *)webView {
|
||||
[self triggerEvent:event forDetail:detail forObject:@"document" forWebView:webView];
|
||||
}
|
||||
|
||||
+ (void) triggerEvent:(NSString *)event forDetail:(NSString *)detail forObject:(NSString *)objName forWebView:(WebView *)webView {
|
||||
NSString *detailEscaped = [detail stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
|
||||
NSString *str = [NSString stringWithFormat:@"var e = new CustomEvent('%@', { 'detail': decodeURIComponent(\"%@\") }); %@.dispatchEvent(e); ", event, detailEscaped, objName];
|
||||
[webView stringByEvaluatingJavaScriptFromString:str];
|
||||
}
|
||||
|
||||
@end
|
20
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.h
Normal file
20
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import <Webkit/WebScriptObject.h>
|
||||
|
||||
#define DEG_EPS 0.001
|
||||
#define fequal(a,b) (fabs((a) - (b)) < DEG_EPS)
|
||||
#define fequalzero(a) (fabs(a) < DEG_EPS)
|
||||
|
||||
@class LoadingView;
|
||||
|
||||
@interface Utils : NSObject {
|
||||
}
|
||||
|
||||
- (float) titleBarHeight:(NSWindow*)aWindow;
|
||||
- (NSString*) pathForResource:(NSString*)resourcepath;
|
||||
- (NSString*) convertDictionaryToJSON:(NSDictionary*)dict;
|
||||
- (NSArray*) convertJSarrayToNSArray:(WebScriptObject*)jsArray;
|
||||
|
||||
+ (Utils*) sharedInstance;
|
||||
|
||||
@end
|
93
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.m
Normal file
93
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Utils.m
Normal file
|
@ -0,0 +1,93 @@
|
|||
#import "Utils.h"
|
||||
#import <Webkit/WebScriptObject.h>
|
||||
|
||||
static Utils* sharedInstance = nil;
|
||||
|
||||
@implementation Utils
|
||||
|
||||
- (float) titleBarHeight:(NSWindow*)aWindow
|
||||
{
|
||||
NSRect frame = [aWindow frame];
|
||||
NSRect contentRect = [NSWindow contentRectForFrameRect: frame
|
||||
styleMask: NSTitledWindowMask];
|
||||
|
||||
return (frame.size.height - contentRect.size.height);
|
||||
}
|
||||
|
||||
- (NSString*) pathForResource:(NSString*)resourcepath
|
||||
{
|
||||
NSBundle * mainBundle = [NSBundle mainBundle];
|
||||
NSMutableArray *directoryParts = [NSMutableArray arrayWithArray:[resourcepath componentsSeparatedByString:@"/"]];
|
||||
NSString *filename = [directoryParts lastObject];
|
||||
[directoryParts removeLastObject];
|
||||
|
||||
NSString *directoryStr = [NSString stringWithFormat:@"%@/%@", kStartFolder, [directoryParts componentsJoinedByString:@"/"]];
|
||||
return [mainBundle pathForResource:filename
|
||||
ofType:@""
|
||||
inDirectory:directoryStr];
|
||||
}
|
||||
|
||||
- (NSString*) convertDictionaryToJSON:(NSDictionary*)dict {
|
||||
// Convert defaults Dictionary to JSON.
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization
|
||||
dataWithJSONObject:dict
|
||||
options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
|
||||
error:&error];
|
||||
|
||||
NSString *jsonString;
|
||||
if (! jsonData) {
|
||||
NSLog(@"Got an error converting to JSON: %@", error);
|
||||
}
|
||||
else {
|
||||
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
// Convert JavaScript array (arrives as a WebScriptObject) into an NSArray of strings.
|
||||
- (NSArray*) convertJSarrayToNSArray:(WebScriptObject*)jsArray {
|
||||
NSInteger count = [[jsArray valueForKey:@"length"] integerValue];
|
||||
|
||||
NSMutableArray *args = [NSMutableArray array];
|
||||
for (int i = 0; i < count; i++) {
|
||||
NSString *item = [jsArray webScriptValueAtIndex:i];
|
||||
if ([item isKindOfClass:[NSString class]]) {
|
||||
[args addObject:item];
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Singleton methods
|
||||
|
||||
+ (Utils*) sharedInstance
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
if (sharedInstance == nil){
|
||||
sharedInstance = [[Utils alloc] init];
|
||||
}
|
||||
}
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
+ (id) allocWithZone:(NSZone *)zone {
|
||||
@synchronized(self) {
|
||||
if (sharedInstance == nil) {
|
||||
sharedInstance = [super allocWithZone:zone];
|
||||
return sharedInstance; // assignment and return on first allocation
|
||||
}
|
||||
}
|
||||
return nil; // on subsequent allocation attempts return nil
|
||||
}
|
||||
|
||||
- (id) copyWithZone:(NSZone *)zone
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,49 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@class Sound;
|
||||
@class Dock;
|
||||
@class Growl;
|
||||
@class Notice;
|
||||
@class Path;
|
||||
@class App;
|
||||
@class Window;
|
||||
@class Clipboard;
|
||||
@class Fonts;
|
||||
@class MenuProxy;
|
||||
@class UserDefaults;
|
||||
|
||||
@class WindowController;
|
||||
|
||||
@interface WebViewDelegate : NSObject {
|
||||
Sound* sound;
|
||||
Dock* dock;
|
||||
Growl* growl;
|
||||
Notice* notice;
|
||||
Path* path;
|
||||
App* app;
|
||||
Window* window;
|
||||
Clipboard* clipboard;
|
||||
Fonts* fonts;
|
||||
NSMenu *mainMenu;
|
||||
UserDefaults* userDefaults;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@property (nonatomic, retain) Sound* sound;
|
||||
@property (nonatomic, retain) Dock* dock;
|
||||
@property (nonatomic, retain) Growl* growl;
|
||||
@property (nonatomic, retain) Notice* notice;
|
||||
@property (nonatomic, retain) Path* path;
|
||||
@property (nonatomic, retain) App* app;
|
||||
@property (nonatomic, retain) Window* window;
|
||||
@property (nonatomic, retain) Clipboard* clipboard;
|
||||
@property (nonatomic, retain) Fonts* fonts;
|
||||
@property (nonatomic, retain) MenuProxy* menu;
|
||||
@property (nonatomic, retain) UserDefaults* userDefaults;
|
||||
|
||||
@property (nonatomic, retain) WindowController *requestedWindow;
|
||||
|
||||
- (id) initWithMenu:(NSMenu*)menu;
|
||||
@end
|
206
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/WebViewDelegate.m
Normal file
206
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/WebViewDelegate.m
Normal file
|
@ -0,0 +1,206 @@
|
|||
#import "WebViewDelegate.h"
|
||||
#import "Sound.h"
|
||||
#import "Dock.h"
|
||||
#import "Notice.h"
|
||||
#import "Path.h"
|
||||
#import "App.h"
|
||||
#import "Window.h"
|
||||
#import "WindowController.h"
|
||||
#import "Clipboard.h"
|
||||
#import "Fonts.h"
|
||||
#import "MenuProxy.h"
|
||||
#import "UserDefaults.h"
|
||||
|
||||
@implementation WebViewDelegate
|
||||
|
||||
@synthesize sound;
|
||||
@synthesize dock;
|
||||
@synthesize growl;
|
||||
@synthesize notice;
|
||||
@synthesize path;
|
||||
@synthesize app;
|
||||
@synthesize window;
|
||||
@synthesize requestedWindow;
|
||||
@synthesize clipboard;
|
||||
@synthesize fonts;
|
||||
@synthesize menu;
|
||||
@synthesize userDefaults;
|
||||
|
||||
- (id) initWithMenu:(NSMenu*)aMenu
|
||||
{
|
||||
self = [super init];
|
||||
if (!self)
|
||||
return nil;
|
||||
|
||||
mainMenu = aMenu;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) webView:(WebView*)webView didClearWindowObject:(WebScriptObject*)windowScriptObject forFrame:(WebFrame *)frame
|
||||
{
|
||||
JSContextRef context = [frame globalContext];
|
||||
if (self.sound == nil) { self.sound = [[Sound alloc] initWithContext:context]; }
|
||||
if (self.dock == nil) { self.dock = [Dock new]; }
|
||||
if (self.path == nil) { self.path = [Path new]; }
|
||||
if (self.clipboard == nil) { self.clipboard = [Clipboard new]; }
|
||||
if (self.fonts == nil) { self.fonts = [Fonts new]; }
|
||||
|
||||
if (self.notice == nil && [Notice available] == YES) {
|
||||
self.notice = [[Notice alloc] initWithWebView:webView];
|
||||
}
|
||||
|
||||
if (self.app == nil) {
|
||||
self.app = [[App alloc] initWithWebView:webView];
|
||||
}
|
||||
|
||||
if (self.window == nil) {
|
||||
self.window = [[Window alloc] initWithWebView:webView];
|
||||
}
|
||||
|
||||
if (self.menu == nil) {
|
||||
self.menu = [MenuProxy proxyWithContext:context andMenu:mainMenu];
|
||||
}
|
||||
|
||||
if (self.userDefaults == nil) {
|
||||
self.userDefaults = [[UserDefaults alloc] initWithWebView:webView];
|
||||
}
|
||||
|
||||
[windowScriptObject setValue:self forKey:kWebScriptNamespace];
|
||||
}
|
||||
|
||||
|
||||
- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id < WebOpenPanelResultListener >)resultListener allowMultipleFiles:(BOOL)allowMultipleFiles{
|
||||
|
||||
NSOpenPanel * openDlg = [NSOpenPanel openPanel];
|
||||
|
||||
[openDlg setCanChooseFiles:YES];
|
||||
[openDlg setCanChooseDirectories:NO];
|
||||
|
||||
[openDlg beginWithCompletionHandler:^(NSInteger result){
|
||||
if (result == NSFileHandlingPanelOKButton) {
|
||||
NSArray * files = [[openDlg URLs] valueForKey: @"relativePath"];
|
||||
[resultListener chooseFilenames: files];
|
||||
} else {
|
||||
[resultListener cancel];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) webView:(WebView*)webView addMessageToConsole:(NSDictionary*)message
|
||||
{
|
||||
if (![message isKindOfClass:[NSDictionary class]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"JavaScript console: %@:%@: %@",
|
||||
[[message objectForKey:@"sourceURL"] lastPathComponent], // could be nil
|
||||
[message objectForKey:@"lineNumber"],
|
||||
[message objectForKey:@"message"]);
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
|
||||
{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:@"OK"];
|
||||
[alert setMessageText:message];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
[alert runModal];
|
||||
}
|
||||
|
||||
- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
|
||||
{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:@"Yes"];
|
||||
[alert addButtonWithTitle:@"No"];
|
||||
[alert setMessageText:message];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
|
||||
if ([alert runModal] == NSAlertFirstButtonReturn)
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
By default the size of a database is set to 0 [1]. When a database is being created
|
||||
it calls this delegate method to get an increase in quota size - or call an error.
|
||||
PS this method is defined in WebUIDelegatePrivate and may make it difficult, but
|
||||
not impossible [2], to get an app accepted into the mac app store.
|
||||
|
||||
Further reading:
|
||||
[1] http://stackoverflow.com/questions/353808/implementing-a-webview-database-quota-delegate
|
||||
[2] http://stackoverflow.com/questions/4527905/how-do-i-enable-local-storage-in-my-webkit-based-application/4608549#4608549
|
||||
*/
|
||||
- (void)webView:(WebView *)sender frame:(WebFrame *)frame exceededDatabaseQuotaForSecurityOrigin:(id) origin database:(NSString *)databaseIdentifier
|
||||
{
|
||||
static const unsigned long long defaultQuota = 5 * 1024 * 1024;
|
||||
if ([origin respondsToSelector: @selector(setQuota:)]) {
|
||||
[origin performSelector:@selector(setQuota:) withObject:[NSNumber numberWithLongLong: defaultQuota]];
|
||||
} else {
|
||||
NSLog(@"could not increase quota for %lld", defaultQuota);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems
|
||||
{
|
||||
NSMutableArray *webViewMenuItems = [defaultMenuItems mutableCopy];
|
||||
|
||||
if (webViewMenuItems)
|
||||
{
|
||||
NSEnumerator *itemEnumerator = [defaultMenuItems objectEnumerator];
|
||||
NSMenuItem *menuItem = nil;
|
||||
while ((menuItem = [itemEnumerator nextObject]))
|
||||
{
|
||||
NSInteger tag = [menuItem tag];
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case WebMenuItemTagOpenLinkInNewWindow:
|
||||
case WebMenuItemTagDownloadLinkToDisk:
|
||||
case WebMenuItemTagCopyLinkToClipboard:
|
||||
case WebMenuItemTagOpenImageInNewWindow:
|
||||
case WebMenuItemTagDownloadImageToDisk:
|
||||
case WebMenuItemTagCopyImageToClipboard:
|
||||
case WebMenuItemTagOpenFrameInNewWindow:
|
||||
case WebMenuItemTagGoBack:
|
||||
case WebMenuItemTagGoForward:
|
||||
case WebMenuItemTagStop:
|
||||
case WebMenuItemTagOpenWithDefaultApplication:
|
||||
case WebMenuItemTagReload:
|
||||
[webViewMenuItems removeObjectIdenticalTo: menuItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return webViewMenuItems;
|
||||
}
|
||||
|
||||
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request{
|
||||
requestedWindow = [[WindowController alloc] initWithRequest:request];
|
||||
return requestedWindow.contentView.webView;
|
||||
}
|
||||
|
||||
- (void)webViewShow:(WebView *)sender{
|
||||
[requestedWindow showWindow:sender];
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)webView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id < WebPolicyDecisionListener >)listener
|
||||
{
|
||||
[[NSWorkspace sharedWorkspace] openURL:[request URL]];
|
||||
[listener ignore];
|
||||
}
|
||||
|
||||
#pragma mark WebScripting protocol
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
@end
|
23
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.h
Normal file
23
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "WindowController.h"
|
||||
|
||||
@interface Window : NSObject{
|
||||
CGRect _oldRestoreFrame;
|
||||
}
|
||||
|
||||
@property (retain, nonatomic) WindowController *windowController;
|
||||
@property (nonatomic, retain) WebView *webView;
|
||||
|
||||
- (id) initWithWebView:(WebView *)view;
|
||||
- (void) open:(NSDictionary *)properties;
|
||||
- (void) move:(NSDictionary *)properties;
|
||||
- (void) resize:(NSDictionary *) properties;
|
||||
- (Boolean) isMaximized;
|
||||
- (CGFloat) getX;
|
||||
- (CGFloat) getY;
|
||||
- (void) maximize;
|
||||
- (void) restore;
|
||||
- (void) toggleFullscreen;
|
||||
|
||||
@end
|
94
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.m
Normal file
94
ext/mac-ui-macgap1-wrapper/src/MacGap/Classes/Window.m
Normal file
|
@ -0,0 +1,94 @@
|
|||
#import "Window.h"
|
||||
|
||||
@implementation Window
|
||||
|
||||
@synthesize windowController, webView;
|
||||
|
||||
- (id) initWithWebView:(WebView*)view
|
||||
{
|
||||
if(self = [super init]) {
|
||||
self.webView = view;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) open:(NSDictionary *)properties
|
||||
{
|
||||
self.windowController = [[WindowController alloc] initWithURL:[properties valueForKey:@"url"]];
|
||||
[self.windowController showWindow: [NSApplication sharedApplication].delegate];
|
||||
[self.windowController.window makeKeyWindow];
|
||||
}
|
||||
|
||||
- (void) minimize {
|
||||
[[NSApp mainWindow] miniaturize:[NSApp mainWindow]];
|
||||
}
|
||||
|
||||
- (void) toggleFullscreen {
|
||||
[[NSApp mainWindow] toggleFullScreen:[NSApp mainWindow]];
|
||||
}
|
||||
|
||||
- (void) maximize {
|
||||
CGRect a = [NSApp mainWindow].frame;
|
||||
_oldRestoreFrame = CGRectMake(a.origin.x, a.origin.y, a.size.width, a.size.height);
|
||||
[[NSApp mainWindow] setFrame:[[NSScreen mainScreen] visibleFrame] display:YES];
|
||||
}
|
||||
|
||||
- (Boolean) isMaximized {
|
||||
NSRect a = [NSApp mainWindow].frame;
|
||||
NSRect b = [[NSScreen mainScreen] visibleFrame];
|
||||
return a.origin.x == b.origin.x && a.origin.y == b.origin.y && a.size.width == b.size.width && a.size.height == b.size.height;
|
||||
}
|
||||
|
||||
- (CGFloat) getX {
|
||||
NSRect frame = [self.webView window].frame;
|
||||
return frame.origin.x;
|
||||
}
|
||||
|
||||
- (CGFloat) getY {
|
||||
NSRect frame = [self.webView window].frame;
|
||||
return frame.origin.y;
|
||||
}
|
||||
|
||||
- (void) move:(NSDictionary *)properties
|
||||
{
|
||||
NSRect frame = [self.webView window].frame;
|
||||
frame.origin.x = [[properties valueForKey:@"x"] doubleValue];
|
||||
frame.origin.y = [[properties valueForKey:@"y"] doubleValue];
|
||||
[[self.webView window] setFrame:frame display:YES];
|
||||
|
||||
}
|
||||
|
||||
- (void) resize:(NSDictionary *) properties
|
||||
{
|
||||
NSRect frame = [self.webView window].frame;
|
||||
frame.size.width = [[properties valueForKey:@"width"] doubleValue];
|
||||
frame.size.height = [[properties valueForKey:@"height"] doubleValue];
|
||||
[[self.webView window] setFrame:frame display:YES];
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(open:)) {
|
||||
result = @"open";
|
||||
}else if (selector == @selector(move:)){
|
||||
result = @"move";
|
||||
}else if (selector == @selector(resize:)){
|
||||
result = @"resize";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
10
ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.h
Normal file
10
ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Clipboard : NSObject {
|
||||
|
||||
}
|
||||
|
||||
- (void) copy:(NSString*)text;
|
||||
- (NSString *) paste;
|
||||
|
||||
@end
|
51
ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.m
Normal file
51
ext/mac-ui-macgap1-wrapper/src/MacGap/Clipboard.m
Normal file
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// clipboard.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by David Zorychta on 2013-07-22.
|
||||
// Copyright (c) 2013 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Clipboard.h"
|
||||
|
||||
@implementation Clipboard
|
||||
|
||||
- (void) copy:(NSString*)text {
|
||||
[[NSPasteboard generalPasteboard] clearContents];
|
||||
[[NSPasteboard generalPasteboard] setString:text forType:NSStringPboardType];
|
||||
}
|
||||
|
||||
- (NSString *) paste {
|
||||
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
|
||||
NSArray *classArray = [NSArray arrayWithObject:[NSString class]];
|
||||
NSDictionary *options = [NSDictionary dictionary];
|
||||
BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options];
|
||||
if (ok) {
|
||||
NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
|
||||
return (NSString *) [objectsToPaste objectAtIndex:0];
|
||||
}
|
||||
return @"";
|
||||
}
|
||||
|
||||
+ (NSString*) webScriptNameForSelector:(SEL)selector
|
||||
{
|
||||
id result = nil;
|
||||
|
||||
if (selector == @selector(copy:)) {
|
||||
result = @"copy";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL) isKeyExcludedFromWebScript:(const char*)name
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"size" : "16x16",
|
||||
"idiom" : "mac",
|
||||
"filename" : "application16x16.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "32x32",
|
||||
"idiom" : "mac",
|
||||
"filename" : "application32x32.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"size" : "128x128",
|
||||
"idiom" : "mac",
|
||||
"filename" : "application128x128.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"size" : "256x256",
|
||||
"idiom" : "mac",
|
||||
"filename" : "application256x256.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"size" : "512x512",
|
||||
"idiom" : "mac",
|
||||
"filename" : "application512x512.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
After Width: | Height: | Size: 715 B |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
32
ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Info.plist
Normal file
32
ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Info.plist
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>ZeroTier One</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.zerotier.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>ZeroTier One</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>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
15
ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Prefix.pch
Normal file
15
ext/mac-ui-macgap1-wrapper/src/MacGap/MacGap-Prefix.pch
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// Prefix header for all source files of the 'MacGap' target in the 'MacGap' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#ifdef _DEBUG
|
||||
#define DebugNSLog(format, ...) NSLog(format, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DebugNSLog(format, ...)
|
||||
#endif
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "Constants.h"
|
||||
#import "Utils.h"
|
||||
#endif
|
13
ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.h
Normal file
13
ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import "ContentView.h"
|
||||
|
||||
@interface WindowController : NSWindowController {
|
||||
|
||||
}
|
||||
|
||||
- (id) initWithURL:(NSString *) url;
|
||||
- (id) initWithRequest: (NSURLRequest *)request;
|
||||
@property (retain) NSURL * url;
|
||||
@property (retain) IBOutlet ContentView *contentView;
|
||||
|
||||
@end
|
54
ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.m
Normal file
54
ext/mac-ui-macgap1-wrapper/src/MacGap/WindowController.m
Normal file
|
@ -0,0 +1,54 @@
|
|||
#import "WindowController.h"
|
||||
|
||||
|
||||
@interface WindowController() {
|
||||
|
||||
}
|
||||
|
||||
-(void) notificationCenter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation WindowController
|
||||
|
||||
@synthesize contentView, url;
|
||||
|
||||
- (id) initWithURL:(NSString *) relativeURL{
|
||||
self = [super initWithWindowNibName:@"Window"];
|
||||
self.url = [NSURL URLWithString:relativeURL relativeToURL:[[NSBundle mainBundle] resourceURL]];
|
||||
|
||||
[self.window setFrameAutosaveName:@"MacGapWindow"];
|
||||
[self notificationCenter];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(id) initWithRequest: (NSURLRequest *)request{
|
||||
self = [super initWithWindowNibName:@"Window"];
|
||||
[self notificationCenter];
|
||||
[[self.contentView.webView mainFrame] loadRequest:request];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) notificationCenter{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self.contentView
|
||||
selector:@selector(windowResized:)
|
||||
name:NSWindowDidResizeNotification
|
||||
object:[self window]];
|
||||
}
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
[super windowDidLoad];
|
||||
|
||||
if (self.url != nil) {
|
||||
[self.contentView.webView setMainFrameURL:[self.url absoluteString]];
|
||||
}
|
||||
|
||||
|
||||
// Implement this method to handle any initialization after your
|
||||
// window controller's window has been loaded from its nib file.
|
||||
}
|
||||
|
||||
@end
|
13
ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Credits.rtf
Normal file
13
ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Credits.rtf
Normal file
|
@ -0,0 +1,13 @@
|
|||
{\rtf1\ansi\ansicpg1252\cocoartf1347\cocoasubrtf570
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\vieww9600\viewh8400\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
|
||||
|
||||
\f0\b\fs24 \cf0 (c)2011-2015 ZeroTier, Inc.\
|
||||
Licensed under the GNU GPLv3\
|
||||
\
|
||||
UI Wrapper MacGap (c) Twitter, Inc.\
|
||||
Licensed under the MIT License\
|
||||
http://macgap.com/\
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
/* Localized versions of Info.plist keys */
|
||||
|
3404
ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/MainMenu.xib
Normal file
3404
ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/MainMenu.xib
Normal file
File diff suppressed because it is too large
Load diff
337
ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Window.xib
Normal file
337
ext/mac-ui-macgap1-wrapper/src/MacGap/en.lproj/Window.xib
Normal file
|
@ -0,0 +1,337 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
|
||||
<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">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.WebKitIBPlugin</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>1938</string>
|
||||
<string>822</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>NSWindowTemplate</string>
|
||||
<string>NSView</string>
|
||||
<string>NSCustomObject</string>
|
||||
<string>WebView</string>
|
||||
</object>
|
||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.WebKitIBPlugin</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="1000">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSCustomObject" id="1001">
|
||||
<string key="NSClassName">WindowController</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1003">
|
||||
<string key="NSClassName">FirstResponder</string>
|
||||
</object>
|
||||
<object class="NSCustomObject" id="1004">
|
||||
<string key="NSClassName">NSApplication</string>
|
||||
</object>
|
||||
<object class="NSWindowTemplate" id="1005">
|
||||
<int key="NSWindowStyleMask">15</int>
|
||||
<int key="NSWindowBacking">2</int>
|
||||
<string key="NSWindowRect">{{196, 240}, {758, 410}}</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="1006">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<object class="NSMutableArray" key="NSSubviews">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="WebView" id="807146547">
|
||||
<reference key="NSNextResponder" ref="1006"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<object class="NSMutableSet" key="NSDragTypes">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="set.sortedObjects">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>Apple HTML pasteboard type</string>
|
||||
<string>Apple PDF pasteboard type</string>
|
||||
<string>Apple PICT pasteboard type</string>
|
||||
<string>Apple URL pasteboard type</string>
|
||||
<string>Apple Web Archive pasteboard type</string>
|
||||
<string>NSColor pasteboard type</string>
|
||||
<string>NSFilenamesPboardType</string>
|
||||
<string>NSStringPboardType</string>
|
||||
<string>NeXT RTFD pasteboard type</string>
|
||||
<string>NeXT Rich Text Format v1.0 pasteboard type</string>
|
||||
<string>NeXT TIFF v4.0 pasteboard type</string>
|
||||
<string>WebURLsWithTitlesPboardType</string>
|
||||
<string>public.png</string>
|
||||
<string>public.url</string>
|
||||
<string>public.url-name</string>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSFrameSize">{758, 410}</string>
|
||||
<reference key="NSSuperview" ref="1006"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<int key="NSViewLayerContentsRedrawPolicy">2</int>
|
||||
<string key="NSReuseIdentifierKey">_NS:51</string>
|
||||
<string key="FrameName"/>
|
||||
<string key="GroupName"/>
|
||||
<object class="WebPreferences" key="Preferences">
|
||||
<string key="Identifier"/>
|
||||
<object class="NSMutableDictionary" key="Values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="NSArray" key="dict.sortedKeys">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<string>WebKitDefaultFixedFontSize</string>
|
||||
<string>WebKitDefaultFontSize</string>
|
||||
<string>WebKitMinimumFontSize</string>
|
||||
</object>
|
||||
<object class="NSMutableArray" key="dict.values">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<integer value="12"/>
|
||||
<integer value="12"/>
|
||||
<integer value="1"/>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<bool key="UseBackForwardList">YES</bool>
|
||||
<bool key="AllowsUndo">YES</bool>
|
||||
</object>
|
||||
</object>
|
||||
<string key="NSFrameSize">{758, 410}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="807146547"/>
|
||||
</object>
|
||||
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
|
||||
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
|
||||
<int key="NSWindowCollectionBehavior">128</int>
|
||||
<bool key="NSWindowIsRestorable">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">contentView</string>
|
||||
<reference key="source" ref="1001"/>
|
||||
<reference key="destination" ref="1006"/>
|
||||
</object>
|
||||
<int key="connectionID">23</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">window</string>
|
||||
<reference key="source" ref="1001"/>
|
||||
<reference key="destination" ref="1005"/>
|
||||
</object>
|
||||
<int key="connectionID">25</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBBindingConnection" key="connection">
|
||||
<string key="label">title: contentView.webView.mainFrameTitle</string>
|
||||
<reference key="source" ref="1005"/>
|
||||
<reference key="destination" ref="1001"/>
|
||||
<object class="NSNibBindingConnector" key="connector">
|
||||
<reference key="NSSource" ref="1005"/>
|
||||
<reference key="NSDestination" ref="1001"/>
|
||||
<string key="NSLabel">title: contentView.webView.mainFrameTitle</string>
|
||||
<string key="NSBinding">title</string>
|
||||
<string key="NSKeyPath">contentView.webView.mainFrameTitle</string>
|
||||
<int key="NSNibBindingConnectorVersion">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<int key="connectionID">31</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBOutletConnection" key="connection">
|
||||
<string key="label">webView</string>
|
||||
<reference key="source" ref="1006"/>
|
||||
<reference key="destination" ref="807146547"/>
|
||||
</object>
|
||||
<int key="connectionID">19</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="1002">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
</object>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="1001"/>
|
||||
<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="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="1002"/>
|
||||
<string key="objectName">Application</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">1</int>
|
||||
<reference key="object" ref="1005"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="1006"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1002"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">2</int>
|
||||
<reference key="object" ref="1006"/>
|
||||
<object class="NSMutableArray" key="children">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<reference ref="807146547"/>
|
||||
</object>
|
||||
<reference key="parent" ref="1005"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">5</int>
|
||||
<reference key="object" ref="807146547"/>
|
||||
<reference key="parent" ref="1006"/>
|
||||
</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>1.IBPluginDependency</string>
|
||||
<string>1.IBWindowTemplateEditedContentRect</string>
|
||||
<string>1.NSWindowTemplate.visibleAtLaunch</string>
|
||||
<string>2.CustomClassName</string>
|
||||
<string>2.IBPluginDependency</string>
|
||||
<string>5.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>{{357, 418}, {480, 270}}</string>
|
||||
<integer value="1"/>
|
||||
<string>ContentView</string>
|
||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
||||
<string>com.apple.WebKitIBPlugin</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="unlocalizedProperties">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<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="1002"/>
|
||||
<reference key="dict.values" ref="1002"/>
|
||||
</object>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">31</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">ContentView</string>
|
||||
<string key="superclassName">NSView</string>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">webView</string>
|
||||
<string key="NS.object.0">WebView</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">WebView</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/ContentView.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">WebView</string>
|
||||
<object class="NSMutableDictionary" key="actions">
|
||||
<string key="NS.key.0">reloadFromOrigin:</string>
|
||||
<string key="NS.object.0">id</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="actionInfosByName">
|
||||
<string key="NS.key.0">reloadFromOrigin:</string>
|
||||
<object class="IBActionInfo" key="NS.object.0">
|
||||
<string key="name">reloadFromOrigin:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/WebView.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">WindowController</string>
|
||||
<string key="superclassName">NSWindowController</string>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">contentView</string>
|
||||
<string key="NS.object.0">ContentView</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<string key="NS.key.0">contentView</string>
|
||||
<object class="IBToOneOutletInfo" key="NS.object.0">
|
||||
<string key="name">contentView</string>
|
||||
<string key="candidateClassName">ContentView</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/WindowController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
||||
<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>
|
||||
</data>
|
||||
</archive>
|
14
ext/mac-ui-macgap1-wrapper/src/MacGap/main.m
Normal file
14
ext/mac-ui-macgap1-wrapper/src/MacGap/main.m
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// main.m
|
||||
// MacGap
|
||||
//
|
||||
// Created by Alex MacCaw on 08/01/2012.
|
||||
// Copyright (c) 2012 Twitter. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, (const char **)argv);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue