-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathTumblrful.m
147 lines (130 loc) · 5.12 KB
/
Tumblrful.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
* @file Tumblrful.cpp
* @brief SIMBL Plugin entry point
* @author Masayuki YAMAYA
* @date 2008-03-02
*/
#import "Tumblrful.h"
#import "TumblrfulBrowserWebView.h"
#import "SafariSingleWindow.h"
#import "GrowlSupport.h"
#import "UserSettings.h"
#import "TumblrfulConstants.h"
#import "DebugLog.h"
#import <objc/objc-runtime.h>
#ifdef DEBUG
#define DEBUG_LOG_SWITCH true
#else
#define DEBUG_LOG_SWITCH false
#endif
/**
* Original code is from http://github.com/rentzsch/jrswizzle
* Copyright (c) 2007 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
*/
static BOOL jr_swizzleMethod(Class klass, SEL orgSel, SEL altSel)
{
Method orgMethod = class_getInstanceMethod(klass, orgSel);
if (orgMethod == NULL) {
D0(@"failed class_getInstanceMethod for orignal");
return NO;
}
Method altMethod = class_getInstanceMethod(klass, altSel);
if (altMethod == NULL) {
D0(@"failed class_getInstanceMethod for alternate");
return NO;
}
#if 1
if (class_addMethod(klass, orgSel, method_getImplementation(altMethod), method_getTypeEncoding(altMethod))) {
class_addMethod(klass, altSel, method_getImplementation(orgMethod), method_getTypeEncoding(orgMethod));
}
else {
method_exchangeImplementations(orgMethod, altMethod);
}
#else
class_addMethod(klass, orgSel, class_getMethodImplementation(klass, orgSel), method_getTypeEncoding(orgMethod));
class_addMethod(klass, altSel, class_getMethodImplementation(klass, altSel), method_getTypeEncoding(altMethod));
method_exchangeImplementations(class_getInstanceMethod(klass, orgSel), class_getInstanceMethod(klass, altSel));
#endif
return YES;
}
static BOOL jr_swizzleClassMethod(Class klass, SEL orgSel, SEL altSel)
{
Method orgMethod = class_getClassMethod(klass, orgSel);
if (orgMethod == NULL) {
D0(@"failed class_getClassMethod for orignal");
return NO;
}
Method altMethod = class_getClassMethod(klass, altSel);
if (altMethod == NULL) {
D0(@"failed class_getClassMethod for alternate");
return NO;
}
method_exchangeImplementations(orgMethod, altMethod);
return YES;
}
@implementation Tumblrful
/**
* 'load' class method
* A special method called by SIMBL once the application has started and
* all classes are initialized.
*/
+ (void)load
{
NSString * bundleInfoString = [[[NSBundle bundleWithIdentifier:TUMBLRFUL_BUNDLE_ID] infoDictionary] objectForKey:@"CFBundleGetInfoString"];
LogEnable(DEBUG_LOG_SWITCH);
NSLog(@"%@", bundleInfoString);
D0(bundleInfoString);
Tumblrful* plugin = [Tumblrful sharedInstance];
plugin = plugin;
// Contextual Menu
BOOL swizzled;
Class clazz = NSClassFromString(@"BrowserWebView");
swizzled = jr_swizzleMethod(clazz, @selector(webView:contextMenuItemsForElement:defaultMenuItems:), @selector(webView_SwizzledByTumblrful:contextMenuItemsForElement:defaultMenuItems:));
if (!swizzled) D0(@"failed swizzle webView:contextMenuItemsForElement:defaultMenuItems:");
swizzled = jr_swizzleMethod(clazz, @selector(performKeyEquivalent:), @selector(performKeyEquivalent_SwizzledByTumblrful:));
if (!swizzled) D0(@"failed swizzle performKeyEquivalent:");
swizzled = jr_swizzleMethod(clazz, @selector(mouseMoved:), @selector(mouseMoved_SwizzledByTumblrful:));
if (!swizzled) D0(@"failed swizzle mouseMoved:");
// Single Window
if ([[UserSettings sharedInstance] boolForKey:@"openInBackgroundTab"]) {
swizzled = jr_swizzleMethod(clazz, @selector(webView:createWebViewWithRequest:windowFeatures:), @selector(webView_SwizzledBySafariSingleWindow:createWebViewWithRequest:windowFeatures:));
if (!swizzled) D0(@"failed swizzle webView:createWebViewWithRequest:windowFeatures:");
swizzled = jr_swizzleMethod(clazz, @selector(webView:createWebViewWithRequest:), @selector(webView_SwizzledBySafariSingleWindow:createWebViewWithRequest:));
if (!swizzled) D0(@"failed swizzle webView:createWebViewWithRequest:");
swizzled = jr_swizzleMethod(clazz, @selector(webView:setFrame:), @selector(webView_SwizzledBySafariSingleWindow:setFrame:));
if (!swizzled) D0(@"failed swizzle webView:setFrame:");
swizzled = jr_swizzleMethod(clazz, @selector(webView:setToolbarsVisible:), @selector(webView_SwizzledBySafariSingleWindow:setToolbarsVisible:));
if (!swizzled) D0(@"failed swizzle webView:setToolbarsVisible:");
swizzled = jr_swizzleMethod(clazz, @selector(webView:setStatusBarVisible:), @selector(webView_SwizzledBySafariSingleWindow:setStatusBarVisible:));
if (!swizzled) D0(@"failed swizzle webView:setStatusBarVisible:");
}
clazz = NSClassFromString(@"WebHTMLView");
swizzled = jr_swizzleMethod(clazz, @selector(mouseDown:), @selector(mouseDown_SwizzledByTumblrful:));
if (!swizzled) D0(@"failed swizzle mouseDown:");
// Preferences Pange
clazz = NSClassFromString(@"NSPreferences");
swizzled = jr_swizzleClassMethod(
clazz
, @selector(sharedPreferences)
, @selector(sharedPreferences_SwizzledByTumblrful)
);
if (!swizzled) D0(@"failed swizzle sharedPreferences");
}
/**
* install.
* invoke by SIMBL, after 'load' method.
* @note need NSPricipalClass description in Info.plist.
*/
+ (void)install
{
// do nothing.
}
+ (Tumblrful *)sharedInstance
{
static Tumblrful * plugin = nil;
if (plugin == nil) {
plugin = [[Tumblrful alloc] init];
}
return plugin;
}
@end