-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathQSWebSearchController.m
163 lines (139 loc) · 6.2 KB
/
QSWebSearchController.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#import "QSWebSearchController.h"
@implementation QSWebSearchController
+ (id)sharedInstance {
static id _sharedInstance;
if (!_sharedInstance) {
id __block t = nil;
QSGCDMainSync(^{
t = [[[self class] allocWithZone:[self zone]] init];
});
_sharedInstance = t;
}
return _sharedInstance;
}
- (id)init {
self = [super init]; // initWithWindowNibName:@"WebSearch"];
if (self) {
[[self window] setLevel:NSFloatingWindowLevel];
}
return self;
}
- (void)windowDidLoad {
[super windowDidLoad];
[[self window]setHidesOnDeactivate:NO];
// [webSearchWindow setFrameTopLeftPoint:[mainWindow frame].origin];
}
- (void)searchURL:(NSURL *)searchURL {
// NSLog(@"SEARCH: %@",searchURL);
[self setWebSearch:searchURL];
//performingWebSearch=YES;
[self showSearchView:self];
[[self window] makeKeyAndOrderFront:self];
}
//kQSStringEncoding
- (NSString *)resolvedURL:(NSString *)searchURL forString:(NSString *)string
{
if (![string length]) {
// empty search
return searchURL;
}
// escape URL, but not # or %
NSString *query = [searchURL URLEncoding];
// replace 'LINE SEPARATOR' 0x2028 with 'LINE FEED (LF)' 0x0a
string = [string stringByReplacingOccurrencesOfString:[NSString stringWithUTF8String:"\u2028"] withString:@"\n"];
// Escape everything in the query string
NSString *searchTerm = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef) string,
NULL,
(CFStringRef) @"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8);
// Query key set in QSDefines.h - QS Code (typically ***)
query = [query stringByReplacingOccurrencesOfString:QUERY_KEY withString:searchTerm];
[searchTerm release];
return query;
}
- (void)searchURL:(NSString *)searchURL forString:(NSString *)string
{
NSPasteboard *findPboard=[NSPasteboard pasteboardWithName:NSFindPboard];
[findPboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
[findPboard setString:string forType:NSStringPboardType];
NSWorkspace *workspace=[NSWorkspace sharedWorkspace];
NSString *query = [self resolvedURL:searchURL forString:string];
NSURL *url = [NSURL URLWithString:query];
if ([[url scheme]isEqualToString:@"qss-http"]){
query = [query stringByReplacingOccurrencesOfString:@"qss-http" withString:@"http"];
[workspace openURL:[NSURL URLWithString:query]];
}
else if ([[url scheme] isEqualToString:@"qss-https"]) {
query = [query stringByReplacingOccurrencesOfString:@"qss-https" withString:@"https"];
[workspace openURL:[NSURL URLWithString:query]];
}
else if ([[NSArray arrayWithObjects:@"qssp-http",@"http-post", nil] containsObject:[url scheme]]){
[self openPOSTURL:[NSURL URLWithString:[query stringByReplacingOccurrencesOfString:[url scheme] withString:@"http"]]];
return;
}
else if ([[NSArray arrayWithObjects:@"qssp-https",@"https-post",nil] containsObject:[url scheme]]) {
[self openPOSTURL:[NSURL URLWithString:[query stringByReplacingOccurrencesOfString:[url scheme] withString:@"https"]]];
return;
}
else{
NSURL *queryURL=[NSURL URLWithString:query];
[workspace openURL:queryURL];
}
}
- (void)openPOSTURL:(NSURL *)searchURL{
NSMutableString *form=[NSMutableString stringWithCapacity:100];
[form appendString:@"<html><head><title>Quicksilver Search Submitter</title></head><body onLoad=\"document.qsform.submit()\">"];
[form appendFormat:@"<form name=\"qsform\" action=\"%@\" method=\"POST\">",[[[searchURL absoluteString]componentsSeparatedByString:@"?"]objectAtIndex:0]];
NSString *component;
NSEnumerator *queryEnumerator=[[[searchURL query]componentsSeparatedByString:@"&"]objectEnumerator];
@try {
while (component = [queryEnumerator nextObject]){
NSArray *nameAndValue=[component componentsSeparatedByString:@"="];
[form appendFormat:@"<input type=\"hidden\" name=\"%@\" value=\"%@\" />",
[[[nameAndValue objectAtIndex:0] URLDecoding ] stringByReplacingOccurrencesOfString:@"+" withString:@" "],
[[[nameAndValue objectAtIndex:1] URLDecoding ] stringByReplacingOccurrencesOfString:@"+" withString:@" "]];
}
}
@catch (NSException *exception) {
QSShowAppNotifWithAttributes(@"QSWebSearchPlugin", NSLocalizedStringFromTableInBundle(@"Post URL Error",nil,[NSBundle bundleForClass:[self class]],@"Title for error on creating POST search"),NSLocalizedStringFromTableInBundle(@"Could not parse POST URL. See Console.app for more info.", nil, [NSBundle bundleForClass:[self class]], @"message for error on creating POST search"));
NSLog(@"%@",exception);
return;
}
[form appendString:@"</form></body></html>"];
NSString *postFile=[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"QSPOST-%@.html",[NSString uniqueString]]];
[form writeToFile:postFile atomically:NO encoding:NSUTF8StringEncoding error:nil];
[[NSWorkspace sharedWorkspace] openFile:postFile];
int64_t delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
NSError *err= nil;
if (![[NSFileManager defaultManager] removeItemAtPath:postFile error:&err]) {
NSLog(@"Error removing %@, %@",postFile, err);
}
});
}
- (IBAction)submitWebSearch:(id)sender {
if ([[webSearchField stringValue]length]){
[self searchURL:webSearch forString:[webSearchField stringValue]];
[self setWebSearch:nil];
[[self window] orderOut:self];
}
}
- (IBAction) showSearchView:sender {
NSPasteboard *findPboard=[NSPasteboard pasteboardWithName:NSFindPboard];
NSString *webSearchString=[findPboard stringForType:NSStringPboardType];
if (webSearchString) [webSearchField setStringValue:webSearchString];
[[self window] orderFront:self];
}
- (void)windowDidResignKey:(NSNotification *)aNotification {
[[self window] orderOut:self];
}
- (id)webSearch {
return [[webSearch retain] autorelease];
}
- (void)setWebSearch:(id)newWebSearch {
[webSearch release];
webSearch = [newWebSearch retain];
}
@end