mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-20 05:13:58 -07:00
Pass authtoken in from user, and add a wrapper for web UI on Mac.
This commit is contained in:
parent
e58047eaa0
commit
5b54612d91
68 changed files with 7537 additions and 1 deletions
21
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/App.h
Normal file
21
ext/mac-ui-macgap1-wrapper/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/MacGap/Classes/Commands/App.m
Normal file
128
ext/mac-ui-macgap1-wrapper/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/MacGap/Classes/Commands/Command.h
Executable file
18
ext/mac-ui-macgap1-wrapper/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/MacGap/Classes/Commands/Command.m
Executable file
28
ext/mac-ui-macgap1-wrapper/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
|
11
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Dock.h
Normal file
11
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Dock.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Dock : NSObject {
|
||||
|
||||
}
|
||||
- (void) setBadge:(NSString*)value;
|
||||
- (NSString *) badge;
|
||||
|
||||
@property (readwrite, copy) NSString *badge;
|
||||
|
||||
@end
|
31
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Dock.m
Normal file
31
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Dock.m
Normal file
|
@ -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/MacGap/Classes/Commands/MenuItemProxy.h
Executable file
31
ext/mac-ui-macgap1-wrapper/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/MacGap/Classes/Commands/MenuItemProxy.m
Executable file
150
ext/mac-ui-macgap1-wrapper/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/MacGap/Classes/Commands/MenuProxy.h
Executable file
31
ext/mac-ui-macgap1-wrapper/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/MacGap/Classes/Commands/MenuProxy.m
Executable file
233
ext/mac-ui-macgap1-wrapper/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
|
26
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Notice.h
Normal file
26
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Notice.h
Normal file
|
@ -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/MacGap/Classes/Commands/Notice.m
Normal file
108
ext/mac-ui-macgap1-wrapper/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
|
21
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Path.h
Normal file
21
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Path.h
Normal file
|
@ -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
|
53
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Path.m
Normal file
53
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Path.m
Normal file
|
@ -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
|
17
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Sound.h
Normal file
17
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Sound.h
Normal file
|
@ -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
|
97
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Sound.m
Normal file
97
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/Sound.m
Normal file
|
@ -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
|
48
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/fonts.m
Normal file
48
ext/mac-ui-macgap1-wrapper/MacGap/Classes/Commands/fonts.m
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue