@@ -26,18 +26,15 @@ of this software and associated documentation files (the "Software"), to deal
26
26
27
27
#import " CTFMenubarMenuController.h"
28
28
#import " CTFWhitelistWindowController.h"
29
- #import < OSAKit/OSAKit.h>
30
- #import < WebKit/WebKit.h>
31
29
30
+ #import " Plugin.h"
32
31
33
32
NSString * kCTFLoadAllFlashViews = @" CTFLoadAllFlashViews" ;
34
33
NSString * kCTFLoadFlashViewsForWindow = @" CTFLoadFlashViewsForWindow" ;
35
34
NSString * kCTFLoadInvisibleFlashViewsForWindow = @" CTFLoadInvisibleFlashViewsForWindow" ;
36
- NSString *sCTFNewViewNotification = @" CTFNewFlashView" ;
37
- NSString *sCTFDestroyedViewNotification = @" CTFDestroyedFlashView" ;
35
+
38
36
NSUInteger maxInvisibleDimension = 50 ;
39
37
40
- static CTFMenubarMenuController* sSingleton = nil ;
41
38
42
39
static NSString * kApplicationsToInstallMenuInto [] = {
43
40
@" com.apple.Safari" ,
@@ -116,6 +113,9 @@ - (int) applicationMenuPrefsInsertionLocation
116
113
#pragma mark Lifetime management
117
114
118
115
116
+ static CTFMenubarMenuController* sSingleton = nil ;
117
+
118
+
119
119
- (id ) init
120
120
{
121
121
if ( sSingleton ) {
@@ -130,27 +130,19 @@ - (id) init
130
130
if ( self ) {
131
131
if ( ! [ NSBundle loadNibNamed: @" MenubarMenu" owner: self ] )
132
132
NSLog ( @" ClickToFlash: Could not load menubar menu nib" );
133
+
134
+ _views = NSCreateHashTable ( NSNonRetainedObjectHashCallBacks , 0 );
133
135
}
134
136
135
- NSNotificationCenter * center = [NSNotificationCenter defaultCenter ];
136
- [center addObserver: self
137
- selector: @selector ( _trackNewView: )
138
- name: sCTFNewViewNotification
139
- object: nil ];
140
-
141
- [center addObserver: self
142
- selector: @selector ( _stopTrackingView: )
143
- name: sCTFDestroyedViewNotification
144
- object: nil ];
145
-
146
137
return self;
147
138
}
148
139
149
140
150
141
- (void ) dealloc
151
142
{
152
143
[ _whitelistWindowController release ];
153
-
144
+ NSFreeHashTable ( _views );
145
+
154
146
[ super dealloc ];
155
147
}
156
148
@@ -196,167 +188,69 @@ + (CTFMenubarMenuController*) sharedController
196
188
#pragma mark -
197
189
#pragma mark View Management
198
190
199
- - (void ) _trackNewView : (NSNotification *) notification
200
- {
201
- NSMutableDictionary *flashViewsDict = nil ;
202
- if ([self flashViews ])
203
- flashViewsDict = [[self flashViews ] copy ];
204
-
205
- if (! flashViewsDict) flashViewsDict = [NSMutableDictionary dictionary ];
206
-
207
- NSString *newViewBaseURL = [[[notification userInfo ] objectForKey: @" baseURL" ] absoluteString ];
208
- NSString *newViewSrc = [[notification userInfo ] objectForKey: @" src" ];
209
- NSNumber *newViewHeight = [[notification userInfo ] objectForKey: @" height" ];
210
- NSNumber *newViewWidth = [[notification userInfo ] objectForKey: @" width" ];
211
- id newTarget = [notification object ];
212
-
213
- NSDictionary *newTargetDict = [NSDictionary dictionaryWithObjectsAndKeys: newTarget,@" target" ,newViewSrc,@" src" ,newViewHeight,@" height" ,newViewWidth,@" width" ,nil ];
214
-
215
- NSMutableArray *baseURLArray = [flashViewsDict objectForKey: newViewBaseURL];
216
-
217
- if (! baseURLArray) {
218
- baseURLArray = [NSMutableArray arrayWithObject: newTargetDict];
219
- [flashViewsDict setObject: baseURLArray forKey: newViewBaseURL];
220
- } else {
221
- [baseURLArray addObject: newTargetDict];
222
- }
223
-
224
- [self setFlashViews: flashViewsDict];
225
-
226
- // not sure why, but the following lines causes crashes and unexpected behavior
227
- // [flashViewsDict release];
228
- }
229
191
230
- - (void ) _stopTrackingView : (NSNotification *) notification
192
+ - (void ) registerView : (NSView *) view
231
193
{
232
- NSMutableDictionary *flashViewsDict = nil ;
233
- if ([self flashViews ])
234
- flashViewsDict = [[self flashViews ] copy ];
235
-
236
- if (! flashViewsDict) flashViewsDict = [NSMutableDictionary dictionary ];
237
-
238
- NSString *baseURL = [[notification userInfo ] objectForKey: @" baseURL" ];
239
- NSMutableArray *baseURLArray = [flashViewsDict objectForKey: baseURL];
240
- id flashView = [notification object ];
241
-
242
- if (! baseURLArray) {
243
- // we're apparently not tracking this view
244
- return ;
245
- }
246
-
247
- NSDictionary *currentDictionary;
248
- BOOL foundView = NO ;
249
- for (currentDictionary in baseURLArray) {
250
- if ([currentDictionary objectForKey: @" target" ] == flashView) {
251
- foundView = YES ;
252
- break ;
253
- }
254
- }
255
-
256
- if (foundView) {
257
- // only do this stuff if we actually find the view we want to stop tracking
258
-
259
- [baseURLArray removeObject: currentDictionary];
260
- if ([baseURLArray count ] == 0 ) [flashViewsDict removeObjectForKey: baseURL];
261
- [self setFlashViews: flashViewsDict];
262
- }
194
+ NSHashInsertIfAbsent ( _views, view );
263
195
}
264
196
265
- - (NSString *)_baseURLOfKeyWindow ;
266
- {
267
- // [[NSBundle mainBundle] bundleIdentifier|executablePath|bundlePath] all return stuff for Safari
268
- // even if called from WebKit
269
-
270
- // the following line crashes WebKit, so we can't use the Scripting Bridge until that is fixed
271
- // SafariApplication *safari = [SBApplication applicationWithProcessIdentifier:getpid()];
272
-
273
- NSString *webKitFrameworkBundlePath = [[NSBundle bundleForClass: [WebView class ]] bundlePath ];
274
-
275
- BOOL isWebKit = NO ;
276
- if (! [webKitFrameworkBundlePath hasPrefix: @" /System/Library/Frameworks" ]) {
277
- // we're not using the system version of WebKit, so it's the WebKit app
278
- isWebKit = YES ;
279
- };
280
-
281
- // the following line doesn't seem to work reliably
282
- // BOOL isWebKit = [[[NSProcessInfo processInfo] arguments] containsObject:@"-WebKitDeveloperExtras"];
283
- NSString *appString = @" " ;
284
- if (isWebKit) {
285
- appString = @" WebKit" ;
286
- } else {
287
- appString = @" Safari" ;
288
- }
289
-
290
- NSString *appleScriptSourceString = [NSString stringWithFormat: @" tell application \" %@ \"\n URL of current tab of front window\n end tell" ,appString];
291
-
292
-
293
- // I didn't want to bring OSACrashyScript into this, but I had to; sorry guys, Scripting Bridge
294
- // just totally crashes WebKit and that's unacceptable
295
-
296
- NSDictionary *errorDict = nil ;
297
- OSAScript *browserNameScript = [[OSAScript alloc ] initWithSource: appleScriptSourceString];
298
- NSAppleEventDescriptor *aeDesc = [browserNameScript executeAndReturnError: &errorDict];
299
- [browserNameScript release ];
300
-
301
- NSString *baseURL = nil ;
302
-
303
- if (! errorDict) baseURL = [aeDesc stringValue ];
304
-
305
- return baseURL;
306
- }
307
197
308
- - (BOOL ) _atLeastOneFlashViewExists ;
198
+ - (void ) unregisterView : ( NSView *) view
309
199
{
310
- NSLog (@" %@ " ,[self flashViews ]);
311
- return ([[[self flashViews ] allKeys ] count ] >= 1 );
200
+ NSHashRemove ( _views, view );
312
201
}
313
202
314
203
315
- - (BOOL ) _flashViewExistsForKeyWindow ;
204
+ - (BOOL ) _atLeastOneFlashViewExists
316
205
{
317
- NSString *baseURL = [self _baseURLOfKeyWindow ];
318
-
319
- // if there's an array for the base URL, there is at least one view
320
- // with that base URL
321
- return ([[self flashViews ] objectForKey: baseURL] != nil );
206
+ return NSCountHashTable ( _views ) > 0 ;
322
207
}
323
208
324
- - (BOOL ) _invisibleFlashViewExistsForKeyWindow ;
209
+
210
+ - (BOOL ) _flashViewExistsForKeyWindowWithInvisibleOnly : (BOOL ) mustBeInvisible
325
211
{
326
- BOOL returnValue = NO ;
327
- NSString *baseURL = [self _baseURLOfKeyWindow ];
212
+ BOOL rslt = NO ;
328
213
329
- NSMutableArray *baseURLArray = [[ self flashViews ] objectForKey: baseURL ];
214
+ NSWindow * keyWindow = [ NSApp keyWindow ];
330
215
331
- if (baseURLArray) {
332
- NSDictionary *currentDictionary = nil ;
333
-
334
- for (currentDictionary in baseURLArray) {
335
- NSUInteger height = [[currentDictionary objectForKey: @" height" ] intValue ];
336
- NSUInteger width = [[currentDictionary objectForKey: @" width" ] intValue ];
337
-
338
- if ((height <= maxInvisibleDimension) && (width <= maxInvisibleDimension)) {
339
- returnValue = YES ;
216
+ NSHashEnumerator enumerator = NSEnumerateHashTable ( _views );
217
+ CTFClickToFlashPlugin* item;
218
+ while ( item = NSNextHashEnumeratorItem ( &enumerator ) ) {
219
+ if ( [ item window ] == keyWindow ) {
220
+ if ( !mustBeInvisible || [ item isConsideredInvisible ] ) {
221
+ rslt = YES ;
340
222
break ;
341
223
}
342
224
}
343
225
}
226
+ NSEndHashTableEnumeration ( &enumerator );
344
227
345
- return returnValue ;
228
+ return rslt ;
346
229
}
347
230
348
- - (BOOL )validateMenuItem : (NSMenuItem *)item {
349
- BOOL returnValue = YES ;
350
-
351
- if ([item action ] == @selector (loadAllFlash: )) {
352
- returnValue = [self _atLeastOneFlashViewExists ];
353
- } else if ([item action ] == @selector (loadKeyWindowFlash: )) {
354
- returnValue = [self _flashViewExistsForKeyWindow ];
355
- } else if ([item action ] == @selector (loadKeyWindowInvisibleFlash: )) {
356
- returnValue = [self _invisibleFlashViewExistsForKeyWindow ];
231
+ - (BOOL ) _flashViewExistsForKeyWindow
232
+ {
233
+ return [ self _flashViewExistsForKeyWindowWithInvisibleOnly: NO ];
234
+ }
235
+
236
+ - (BOOL ) _invisibleFlashViewExistsForKeyWindow ;
237
+ {
238
+ return [ self _flashViewExistsForKeyWindowWithInvisibleOnly: YES ];
239
+ }
240
+
241
+ - (BOOL ) validateMenuItem : (NSMenuItem *) item
242
+ {
243
+ if ( [ item action ] == @selector ( loadAllFlash: ) ) {
244
+ return [ self _atLeastOneFlashViewExists ];
245
+ }
246
+ else if ( [ item action ] == @selector ( loadKeyWindowFlash: ) ) {
247
+ return [ self _flashViewExistsForKeyWindow ];
248
+ }
249
+ else if ( [ item action ] == @selector (loadKeyWindowInvisibleFlash: ) ) {
250
+ return [ self _invisibleFlashViewExistsForKeyWindow ];
357
251
}
358
252
359
- return returnValue ;
253
+ return YES ;
360
254
}
361
255
362
256
#pragma mark -
@@ -408,6 +302,4 @@ - (IBAction) showSettingsWindow: (id) sender
408
302
[ _whitelistWindowController showWindow: sender ];
409
303
}
410
304
411
- @synthesize flashViews = _flashViews;
412
-
413
305
@end
0 commit comments