From 6d1803dfb903e87af13674d4944e4bcbb29df1a4 Mon Sep 17 00:00:00 2001 From: rentzsch Date: Sun, 17 May 2009 23:35:19 -0500 Subject: [PATCH] [NEW] Start restoring compatiblity with 10.4. This builds and works under 10.5, and works under 10.4 - except for a crash in -mouseDown (Symbol not found: _objc_assign_weak). The code also builds under 10.4, with a couple of tweaks, and does not crash in this case, but also is missing some features and will not build universal for some reason. (Michael Baltaks) --- ClickToFlash.xcodeproj/project.pbxproj | 30 +- MATrackingArea/MATrackingArea.h | 89 +++++ MATrackingArea/MATrackingArea.m | 426 +++++++++++++++++++++++ Plugin/CTFWhitelist.m | 12 +- Plugin/CTFsIFRSupport.m | 4 +- Plugin/Plugin.h | 29 +- Plugin/Plugin.m | 449 +++++++++++++++++++------ README.markdown | 9 + SparkleManager.h | 3 +- SparkleManager.m | 11 +- 10 files changed, 939 insertions(+), 123 deletions(-) mode change 100644 => 100755 ClickToFlash.xcodeproj/project.pbxproj create mode 100755 MATrackingArea/MATrackingArea.h create mode 100755 MATrackingArea/MATrackingArea.m mode change 100644 => 100755 Plugin/CTFWhitelist.m mode change 100644 => 100755 Plugin/CTFsIFRSupport.m mode change 100644 => 100755 Plugin/Plugin.h mode change 100644 => 100755 Plugin/Plugin.m mode change 100644 => 100755 SparkleManager.h mode change 100644 => 100755 SparkleManager.m diff --git a/ClickToFlash.xcodeproj/project.pbxproj b/ClickToFlash.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index b2cf946c..f1b65620 --- a/ClickToFlash.xcodeproj/project.pbxproj +++ b/ClickToFlash.xcodeproj/project.pbxproj @@ -34,6 +34,8 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 0038DE240FC0CCF0007B54E9 /* MATrackingArea.m in Sources */ = {isa = PBXBuildFile; fileRef = 0038DE230FC0CCF0007B54E9 /* MATrackingArea.m */; }; + 0038DE320FC0CE7B007B54E9 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0038DE310FC0CE7B007B54E9 /* Carbon.framework */; }; 072189BE0F30D9C3008C8944 /* ContextualMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 072189BA0F30D9C3008C8944 /* ContextualMenu.xib */; }; 072189BF0F30D9C3008C8944 /* WhitelistPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 072189BC0F30D9C3008C8944 /* WhitelistPanel.xib */; }; 55EB70480E04A8850016593D /* Plugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 55EB703D0E04A84F0016593D /* Plugin.m */; }; @@ -124,6 +126,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0038DE220FC0CCF0007B54E9 /* MATrackingArea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MATrackingArea.h; sourceTree = ""; }; + 0038DE230FC0CCF0007B54E9 /* MATrackingArea.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MATrackingArea.m; sourceTree = ""; }; + 0038DE310FC0CE7B007B54E9 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; 072189BB0F30D9C3008C8944 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Plugin/English.lproj/ContextualMenu.xib; sourceTree = ""; }; 072189BD0F30D9C3008C8944 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Plugin/English.lproj/WhitelistPanel.xib; sourceTree = ""; }; 55EB703C0E04A84F0016593D /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = Plugin/Plugin.h; sourceTree = ""; }; @@ -167,6 +172,7 @@ files = ( 55EB70580E04A8B80016593D /* Cocoa.framework in Frameworks */, 55EB70590E04A8B80016593D /* WebKit.framework in Frameworks */, + 0038DE320FC0CE7B007B54E9 /* Carbon.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -180,9 +186,19 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0038DE210FC0CCF0007B54E9 /* MATrackingArea */ = { + isa = PBXGroup; + children = ( + 0038DE220FC0CCF0007B54E9 /* MATrackingArea.h */, + 0038DE230FC0CCF0007B54E9 /* MATrackingArea.m */, + ); + path = MATrackingArea; + sourceTree = ""; + }; 55EB70300E04A8410016593D = { isa = PBXGroup; children = ( + 0038DE210FC0CCF0007B54E9 /* MATrackingArea */, 55EB70540E04A89C0016593D /* Plugin */, B5CFF1810F40EF98005DB9CC /* Debugging Harness */, 55EB70550E04A8A40016593D /* Frameworks */, @@ -233,6 +249,7 @@ 55EB70550E04A8A40016593D /* Frameworks */ = { isa = PBXGroup; children = ( + 0038DE310FC0CE7B007B54E9 /* Carbon.framework */, 55EB70560E04A8B80016593D /* Cocoa.framework */, 55EB70570E04A8B80016593D /* WebKit.framework */, ); @@ -436,6 +453,7 @@ 845704550F4792320017F3F4 /* CTFWhitelist.m in Sources */, 8457045A0F47BC170017F3F4 /* CTFUtilities.m in Sources */, 79E2EB930F86AAD3005CF170 /* SparkleManager.m in Sources */, + 0038DE240FC0CCF0007B54E9 /* MATrackingArea.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -514,10 +532,13 @@ 55EB70330E04A8410016593D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; COPY_PHASE_STRIP = NO; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_SIGN_COMPARE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.4; PRODUCT_VERSION = 1.4.1; WARNING_CFLAGS = "-Wall"; }; @@ -526,10 +547,13 @@ 55EB70340E04A8410016593D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; COPY_PHASE_STRIP = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_SIGN_COMPARE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.4; PRODUCT_VERSION = 1.4.1; WARNING_CFLAGS = "-Wall"; }; @@ -538,6 +562,8 @@ 55EB70450E04A8640016593D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)"; GCC_DYNAMIC_NO_PIC = NO; @@ -561,8 +587,8 @@ 55EB70460E04A8640016593D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)"; diff --git a/MATrackingArea/MATrackingArea.h b/MATrackingArea/MATrackingArea.h new file mode 100755 index 00000000..56eb3ecd --- /dev/null +++ b/MATrackingArea/MATrackingArea.h @@ -0,0 +1,89 @@ +// +// MATrackingArea.h +// MATrackingArea +// +// Created by Matt Gemmell on 25/09/2007. +// + +#import + +/* + Type of tracking area. You must specify one or more types from this list in the + MATrackingAreaOptions argument of -initWithRect:options:owner:userInfo: + */ +enum { + // Owner receives mouseEntered when mouse enters area, and mouseExited when mouse leaves area. + MATrackingMouseEnteredAndExited = 0x01, + + // Owner receives mouseMoved while mouse is within area. Note that mouseMoved events do not + // contain userInfo. + MATrackingMouseMoved = 0x02, +}; + +/* + When the tracking area is active. You must specify exactly one of the following in the + MATrackingAreaOptions argument of -initWithRect:options:owner:userInfo: + */ +enum { + // Owner receives mouseEntered/Exited or mouseMoved when view is first responder. + MATrackingActiveWhenFirstResponder = 0x10, + + // Owner receives mouseEntered/Exited or mouseMoved when view is in key window. + MATrackingActiveInKeyWindow = 0x20, + + // Owner receives mouseEntered/Exited or mouseMoved when app is active. + MATrackingActiveInActiveApp = 0x40, + + // Owner receives mouseEntered/Exited or mouseMoved regardless of activation. + MATrackingActiveAlways = 0x80, +}; + +/* + Behavior of tracking area. You may specify any number of the following in the + MATrackingAreaOptions argument of -initWithRect:options:owner:userInfo: + */ +enum { + // If set, generate mouseExited event when mouse leaves area (same as assumeInside argument + // in NSView's addtrackingArea:owner:userData:assumeInside: method). + MATrackingAssumeInside = 0x100, + + // If set, tracking occurs in visibleRect of view and rect is ignored. + MATrackingInVisibleRect = 0x200, + + // If set, mouseEntered events will be generated as mouse is dragged. If not set, mouseEntered + // events will be generated as mouse is moved, and on mouseUp after a drag. mouseExited + // events are paired with mouseEntered events so their delivery is affected indirectly. + // That is, if a mouseEntered event is generated and the mouse subsequently moves out of the + // trackingArea, a mouseExited event will be generated whether the mouse is being moved or + // dragged, independent of this flag. + MATrackingEnabledDuringMouseDrag = 0x400 +}; + +typedef unsigned int MATrackingAreaOptions; + +@interface MATrackingArea : NSObject +{ + @private + NSRect _rect; + MATrackingAreaOptions _options; + __weak id _owner; + NSDictionary * _userInfo; + NSPoint _lastMovedPoint; + BOOL _inside; +} + ++ (void)addTrackingArea:(MATrackingArea *)trackingArea toView:(NSView *)view; ++ (void)removeTrackingArea:(MATrackingArea *)trackingArea fromView:(NSView *)view; ++ (NSArray *)trackingAreasForView:(NSView *)view; + +- (MATrackingArea *)initWithRect:(NSRect)rect + options:(MATrackingAreaOptions)options + owner:(id)owner + userInfo:(NSDictionary *)userInfo; +- (NSRect)rect; +- (void)setRect:(NSRect)newRect; +- (MATrackingAreaOptions)options; +- (id)owner; +- (NSDictionary *)userInfo; + +@end diff --git a/MATrackingArea/MATrackingArea.m b/MATrackingArea/MATrackingArea.m new file mode 100755 index 00000000..15c01800 --- /dev/null +++ b/MATrackingArea/MATrackingArea.m @@ -0,0 +1,426 @@ +// +// MATrackingArea.m +// MATrackingArea +// +// Created by Matt Gemmell on 25/09/2007. +// Copyright 2007 Magic Aubergine. +// + +#import "MATrackingArea.h" +#import + +#define MA_POLLING_INTERVAL 0.1 + +static NSTimer *_pollingTimer; +static NSMutableArray *_views; +static NSMutableArray *_trackingAreas; // 2-dimensional + +/* NSWindow category by Jonathan 'Wolf' Rentzsch http://rentzsch.com */ +@interface NSWindow (liveFrame) +- (NSRect)liveFrame; +- (NSRect)convertLiveBaseRectToScreen:(NSRect)rect; +@end +@implementation NSWindow (liveFrame) +// This method is because -[NSWindow frame] isn't updated continually during a drag. +- (NSRect)liveFrame { + Rect qdRect; + GetWindowBounds([self windowRef], kWindowStructureRgn, &qdRect); + + return NSMakeRect(qdRect.left, + (float)CGDisplayPixelsHigh(kCGDirectMainDisplay) - qdRect.bottom, + qdRect.right - qdRect.left, + qdRect.bottom - qdRect.top); +} +- (NSRect)convertLiveBaseRectToScreen:(NSRect)rect { + NSRect liveFrame = [self liveFrame]; + return NSMakeRect(liveFrame.origin.x + rect.origin.x, + liveFrame.origin.y + rect.origin.y, + rect.size.width, + rect.size.height); +} +@end + +@interface MATrackingArea (PrivateMethods) + ++ (void)checkMouseLocation:(NSTimer *)theTimer; +- (NSPoint)_lastMovedPoint; +- (void)_setLastMovedPoint:(NSPoint)pt; +- (BOOL)_inside; +- (void)_setInside:(BOOL)inside; +- (void)_setNotInside; + +@end + +@implementation MATrackingArea + + +#pragma mark Class methods + + ++ (void)initialize +{ + _views = [[NSMutableArray alloc] initWithCapacity:0]; + _trackingAreas = [[NSMutableArray alloc] initWithCapacity:0]; +} + + ++ (void)checkMouseLocation:(NSTimer*)theTimer +{ + // This is where the action happens. + NSPoint mouseLoc = [NSEvent mouseLocation]; + NSEnumerator *viewsEnumerator = [_views objectEnumerator]; + NSView *view; + int index = 0; + + while ((view = [viewsEnumerator nextObject])) { + NSWindow *window = [view window]; + if (!window) { + // Pointer can't be inside a view with no window. + int viewIndex = [_views indexOfObject:view]; + [[_trackingAreas objectAtIndex:viewIndex] makeObjectsPerformSelector:@selector(_setNotInside)]; + continue; + } + + NSPoint mouseInWindow = [window convertScreenToBase:mouseLoc]; + NSPoint mouseInView = [view convertPoint:mouseInWindow fromView:nil]; + NSEnumerator *trackingAreaEnumerator = [[_trackingAreas objectAtIndex:index] objectEnumerator]; + MATrackingArea *area; + + while ((area = [trackingAreaEnumerator nextObject])) { + MATrackingAreaOptions options = [area options]; + NSRect trackingRect = (options & MATrackingInVisibleRect) + ? [view visibleRect] + : [area rect]; + BOOL nowInside = NSPointInRect(mouseLoc, [window convertLiveBaseRectToScreen:[view convertRect:trackingRect toView:nil]]); + BOOL wasInside = [area _inside]; + NSEventType eventType = NSApplicationDefined; + + // Determine whether to inform the view. + if (!(options & MATrackingActiveAlways)) { + if (options & MATrackingActiveInActiveApp) { + if (![NSApp isActive]) { + continue; + } + } else if (options & MATrackingActiveInKeyWindow) { + if (![NSApp isActive] || ![window isKeyWindow]) { + continue; + } + } else if (options & MATrackingActiveWhenFirstResponder) { + if (![NSApp isActive] || ![window isKeyWindow] || + !([window firstResponder] == view)) { + continue; + } + } + } + // Check whether the mouse is currently being dragged + UInt32 state; + BOOL dragging = NO; + if ([NSApp isActive]) { + state = GetCurrentEventButtonState(); + } else { + state = GetCurrentButtonState(); + } + if ((state & 0x01) || (state & 0x02) || (state & 0x03)) { + dragging = YES; + } + if (!(options & MATrackingEnabledDuringMouseDrag) && dragging) { + continue; + } + + // Determine what happened. + if (nowInside && !wasInside && (options & MATrackingMouseEnteredAndExited)) { + // Entered + eventType = NSMouseEntered; + [area _setInside:YES]; + } else if (!nowInside && wasInside && (options & MATrackingMouseEnteredAndExited)) { + // Exited + eventType = NSMouseExited; + [area _setInside:NO]; + } else if (nowInside && (options & MATrackingMouseMoved)) { + if (wasInside && !NSEqualPoints(mouseInView, [area _lastMovedPoint])) { + // Moved + eventType = NSMouseMoved; + [area _setLastMovedPoint:mouseInView]; + } else if (!wasInside) { + // Make sure we get a moved event next time + [area _setInside:YES]; + } + } + + // Construct an appropriate event. + NSEvent *event = nil; + switch (eventType) { + case NSMouseEntered: + case NSMouseExited: + event = [NSEvent enterExitEventWithType:eventType + location:mouseInWindow + modifierFlags:eventType + timestamp:0 + windowNumber:[window windowNumber] + context:nil + eventNumber:0 + trackingNumber:0 + userData:[area userInfo]]; + break; + case NSMouseMoved: + event = [NSEvent mouseEventWithType:eventType + location:mouseInWindow + modifierFlags:eventType + timestamp:0 + windowNumber:[window windowNumber] + context:nil + eventNumber:0 + clickCount:0 + pressure:0.0]; + break; + } + + // Send event. + id owner = [area owner]; + switch (eventType) { + case NSMouseEntered: + [owner mouseEntered:event]; + break; + case NSMouseExited: + [owner mouseExited:event]; + break; + case NSMouseMoved: + [owner mouseMoved:event]; + break; + } + } + + index++; + } +} + + ++ (void)addTrackingArea:(MATrackingArea *)trackingArea toView:(NSView *)view +{ + if (!trackingArea || !view) { + return; + } + + // Validate options + MATrackingAreaOptions options = [trackingArea options]; + if (!(options & MATrackingMouseEnteredAndExited) && + !(options & MATrackingMouseMoved)) { + // trackingArea's options don't contain any of the 'type' masks. + return; + } else if (!(options & MATrackingActiveAlways) && + !(options & MATrackingActiveInActiveApp) && + !(options & MATrackingActiveInKeyWindow) && + !(options & MATrackingActiveWhenFirstResponder)) { + // trackingArea's options don't contain any of the 'when' masks. + return; + } + + int index = [_views indexOfObject:view]; + if (index == NSNotFound) { + // Add view to _views and create appropriate entry in _trackingAreas. + [_views addObject:view]; + NSMutableArray *trackingAreasForView = [NSMutableArray arrayWithCapacity:1]; + [trackingAreasForView addObject:trackingArea]; + [_trackingAreas addObject:trackingAreasForView]; + } else { + // Add trackingArea to appropriate entry in _trackingAreas. + NSMutableArray *trackingAreasForView = [_trackingAreas objectAtIndex:index]; + if (![trackingAreasForView containsObject:trackingArea]) { + [trackingAreasForView addObject:trackingArea]; + } + } + + // Support for MATrackingAssumeInside + if (options & MATrackingAssumeInside) { + [trackingArea _setInside:YES]; + } + + // Create Polling Timer Of Extreme Evil if appropriate. + if (!_pollingTimer) { + _pollingTimer = [[NSTimer scheduledTimerWithTimeInterval:MA_POLLING_INTERVAL + target:[self class] + selector:@selector(checkMouseLocation:) + userInfo:nil + repeats:YES] retain]; + } +} + + ++ (void)removeTrackingArea:(MATrackingArea *)trackingArea fromView:(NSView *)view +{ + if (!trackingArea || !view) { + return; + } + + int index = [_views indexOfObject:view]; + if (index == NSNotFound) { + // We don't have any trackingAreas for that view. + return; + } + + NSMutableArray *trackingAreasForView = [_trackingAreas objectAtIndex:index]; + if (![trackingAreasForView containsObject:trackingArea]) { + // We don't know anything about that trackingArea. + return; + } else { + // Remove the trackingArea as requested. + [trackingAreasForView removeObject:trackingArea]; + } + + // If there are no more trackingAreas for this view, remove it. + if ([trackingAreasForView count] == 0) { + [_trackingAreas removeObjectAtIndex:index]; + [_views removeObjectAtIndex:index]; + } + + // Destroy timer if appropriate. + if ([_views count] == 0) { + [_pollingTimer invalidate]; + [_pollingTimer release]; + _pollingTimer = nil; + } +} + + ++ (NSArray *)trackingAreasForView:(NSView *)view +{ + if (view) { + int index = [_views indexOfObject:view]; + if (index != NSNotFound) { + return [NSArray arrayWithArray:[_trackingAreas objectAtIndex:index]]; + } + } + return nil; +} + + +#pragma mark Instance methods + + +- (MATrackingArea *)initWithRect:(NSRect)rect + options:(MATrackingAreaOptions)options + owner:(id)owner + userInfo:(NSDictionary *)userInfo +{ + if ((self = [super init])) { + _rect = rect; + _options = options; + _owner = owner; + _userInfo = [userInfo retain]; + _lastMovedPoint = NSZeroPoint; + _inside = NO; + } + return self; +} + + +- (void)dealloc +{ + [_userInfo release]; + [super dealloc]; +} + + +- (NSRect)rect +{ + return _rect; +} + + +- (void)setRect:(NSRect)newRect +{ + _rect = newRect; + [MATrackingArea checkMouseLocation:nil]; +} + + +- (MATrackingAreaOptions)options +{ + return _options; +} + + +- (id)owner +{ + return _owner; +} + + +- (NSDictionary *)userInfo +{ + return [[_userInfo retain] autorelease]; +} + + +- (NSPoint)_lastMovedPoint +{ + return _lastMovedPoint; +} + + +- (void)_setLastMovedPoint:(NSPoint)pt +{ + _lastMovedPoint = pt; +} + + +- (BOOL)_inside +{ + return _inside; +} + + +- (void)_setInside:(BOOL)inside +{ + _inside = inside; +} + + +- (void)_setNotInside +{ + [self _setInside:NO]; +} + + +#pragma mark NSCopying + + +- (id)copyWithZone:(NSZone *)zone +{ + MATrackingArea *copy = (MATrackingArea *)[[[self class] allocWithZone:zone] + initWithRect:[self rect] + options:[self options] + owner:[self owner] + userInfo:[self userInfo]]; + return copy; +} + + +#pragma mark NSCoding + + +- (id)initWithCoder:(NSCoder *)coder +{ + NSRect rect = [coder decodeRectForKey:@"_rect"]; + MATrackingAreaOptions options = [coder decodeIntForKey:@"_options"]; + NSDictionary *userInfo = [coder decodeObjectForKey:@"_userInfo"]; + id owner = [coder decodeObjectForKey:@"_owner"]; + + self = (MATrackingArea *)[[MATrackingArea alloc] initWithRect:rect + options:options + owner:owner + userInfo:userInfo]; + return self; +} + + +- (void)encodeWithCoder:(NSCoder *)coder +{ + [coder encodeRect:_rect forKey:@"_rect"]; + [coder encodeInt:_options forKey:@"_options"]; + [coder encodeObject:_userInfo forKey:@"_userInfo"]; + [coder encodeConditionalObject:_owner forKey:@"_owner"]; +} + + +@end diff --git a/Plugin/CTFWhitelist.m b/Plugin/CTFWhitelist.m old mode 100644 new mode 100755 index 59486a07..4c6913d0 --- a/Plugin/CTFWhitelist.m +++ b/Plugin/CTFWhitelist.m @@ -122,7 +122,7 @@ - (void) _abortAlert - (void) _askToAddCurrentSiteToWhitelist { NSString *title = NSLocalizedString(@"Always load Flash for this site?", @"Always load Flash for this site? alert title"); - NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Add %@ to the whitelist?", @"Add to the whitelist? alert message"), self.host]; + NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Add %@ to the whitelist?", @"Add to the whitelist? alert message"), [self host]]; NSAlert *alert = [[NSAlert alloc] init]; [alert addButtonWithTitle:NSLocalizedString(@"Add to Whitelist", @"Add to Whitelist button")]; @@ -150,12 +150,12 @@ - (void) _addToWhitelistAlertDidEnd: (NSAlert *)alert returnCode: (int)returnCod - (BOOL) _isHostWhitelisted { // Nil hosts whitelisted by default (e.g. Dashboard) - if (!self.host) + if (![self host]) { return YES; } - return [self _isWhiteListedForHostString: self.host]; + return [self _isWhiteListedForHostString: [self host]]; } - (BOOL) _isWhiteListedForHostString:(NSString *)hostString @@ -176,7 +176,7 @@ - (NSMutableArray *) _mutableSiteInfo - (void) _addHostToWhitelist { NSMutableArray *siteInfo = [self _mutableSiteInfo]; - [siteInfo addObject: whitelistItemForSite(self.host)]; + [siteInfo addObject: whitelistItemForSite([self host])]; [[NSUserDefaults standardUserDefaults] setObject: siteInfo forKey: sHostSiteInfoDefaultsKey]; [[NSNotificationCenter defaultCenter] postNotificationName: sCTFWhitelistAdditionMade object: self]; } @@ -184,7 +184,7 @@ - (void) _addHostToWhitelist - (void) _removeHostFromWhitelist { NSMutableArray *siteInfo = [self _mutableSiteInfo]; - NSUInteger foundIndex = indexOfItemForSite(siteInfo, self.host); + NSUInteger foundIndex = indexOfItemForSite(siteInfo, [self host]); if(foundIndex != NSNotFound) { [siteInfo removeObjectAtIndex: foundIndex]; @@ -212,7 +212,7 @@ - (IBAction) removeFromWhitelist: (id)sender return; NSString *title = NSLocalizedString(@"Stop always loading Flash?", @"Stop always loading Flash? alert title"); - NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Remove %@ from the whitelist?", @"Remove %@ from the whitelist? alert message"), self.host]; + NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Remove %@ from the whitelist?", @"Remove %@ from the whitelist? alert message"), [self host]]; NSAlert *alert = [[NSAlert alloc] init]; [alert addButtonWithTitle:NSLocalizedString(@"Remove from Whitelist", @"Remove from Whitelist button")]; diff --git a/Plugin/CTFsIFRSupport.m b/Plugin/CTFsIFRSupport.m old mode 100644 new mode 100755 index 9c75592c..5ded0e8e --- a/Plugin/CTFsIFRSupport.m +++ b/Plugin/CTFsIFRSupport.m @@ -46,7 +46,7 @@ @implementation CTFClickToFlashPlugin( sIFRSupport ) - (NSUInteger) _sifrVersionInstalled { // get the container's WebView - WebView *sifrWebView = self.webView; + WebView *sifrWebView = [self webView]; NSUInteger version = 0; if (sifrWebView) { @@ -79,7 +79,7 @@ - (BOOL) _shouldAutoLoadSIFR - (void) _disableSIFR { // get the container's WebView - WebView *sifrWebView = self.webView; + WebView *sifrWebView = [self webView]; // if sifr add-ons are not installed, load version-appropriate version into page if ([[sifrWebView stringByEvaluatingJavaScriptFromString: sSifrAddOnTest] isEqualToString: @"true"]) { diff --git a/Plugin/Plugin.h b/Plugin/Plugin.h old mode 100644 new mode 100755 index ad65c5b3..7c663ddb --- a/Plugin/Plugin.h +++ b/Plugin/Plugin.h @@ -32,7 +32,7 @@ THE SOFTWARE. DOMElement *_container; NSString *_host; NSDictionary* _flashVars; - NSTrackingArea *trackingArea; + id trackingArea; NSAlert* _activeAlert; NSString* _badgeText; BOOL mouseIsDown; @@ -53,15 +53,24 @@ THE SOFTWARE. - (id) initWithArguments:(NSDictionary *)arguments; -@property (nonatomic, retain) DOMElement *container; -@property (nonatomic, retain) NSString *host; -@property (nonatomic, retain) WebView *webView; -@property (retain) NSString *baseURL; -@property (nonatomic, retain) NSDictionary *attributes; -@property (retain) NSDictionary *originalOpacityAttributes; -@property (retain) NSString *src; -@property (retain) NSString *videoId; -@property (retain) NSString *launchedAppBundleIdentifier; +- (DOMElement *)container; +- (void)setContainer:(DOMElement *)newValue; +- (NSString *)host; +- (void)setHost:(NSString *)newValue; +- (WebView *)webView; +- (void)setWebView:(WebView *)newValue; +- (NSString *)baseURL; +- (void)setBaseURL:(NSString *)newValue; +- (NSDictionary *)attributes; +- (void)setAttributes:(NSDictionary *)newValue; +- (NSDictionary *)originalOpacityAttributes; +- (void)setOriginalOpacityAttributes:(NSDictionary *)newValue; +- (NSString *)src; +- (void)setSrc:(NSString *)newValue; +- (NSString *)videoId; +- (void)setVideoId:(NSString *)newValue; +- (NSString *)launchedAppBundleIdentifier; +- (void)setLaunchedAppBundleIdentifier:(NSString *)newValue; - (IBAction)loadFlash:(id)sender; - (IBAction)loadH264:(id)sender; diff --git a/Plugin/Plugin.m b/Plugin/Plugin.m old mode 100644 new mode 100755 index 923f341e..9c33fbbe --- a/Plugin/Plugin.m +++ b/Plugin/Plugin.m @@ -26,6 +26,7 @@ of this software and associated documentation files (the "Software"), to deal #import "Plugin.h" +#import "MATrackingArea.h" #import "CTFMenubarMenuController.h" #import "CTFsIFRSupport.h" #import "CTFUtilities.h" @@ -44,6 +45,14 @@ of this software and associated documentation files (the "Software"), to deal static NSString *sAutoLoadInvisibleFlashViewsKey = @"ClickToFlash_autoLoadInvisibleViews"; static NSString *sPluginEnabled = @"ClickToFlash_pluginEnabled"; +BOOL usingMATrackingArea = NO; + +@interface NSBezierPath(MRGradientFill) +-(void)linearGradientFill:(NSRect)thisRect + startColor:(NSColor *)startColor + endColor:(NSColor *)endColor; +@end + @interface CTFClickToFlashPlugin (Internal) - (void) _convertTypesForFlashContainer; - (void) _convertTypesForFlashContainerAfterDelay; @@ -105,11 +114,11 @@ - (id) initWithArguments:(NSDictionary *)arguments [[NSUserDefaults standardUserDefaults] setBool:YES forKey:sPluginEnabled]; } - self.launchedAppBundleIdentifier = [self launchedAppBundleIdentifier]; + [self setLaunchedAppBundleIdentifier:[self launchedAppBundleIdentifier]]; - self.webView = [[[arguments objectForKey:WebPlugInContainerKey] webFrame] webView]; + [self setWebView:[[[arguments objectForKey:WebPlugInContainerKey] webFrame] webView]]; - self.container = [arguments objectForKey:WebPlugInContainingElementKey]; + [self setContainer:[arguments objectForKey:WebPlugInContainingElementKey]]; [self _migrateWhitelist]; @@ -117,28 +126,28 @@ - (id) initWithArguments:(NSDictionary *)arguments // Get URL NSURL *base = [arguments objectForKey:WebPlugInBaseURLKey]; - self.baseURL = [base absoluteString]; - self.host = [base host]; + [self setBaseURL:[base absoluteString]]; + [self setHost:[base host]]; - self.attributes = [arguments objectForKey:WebPlugInAttributesKey]; - NSString *srcAttribute = [self.attributes objectForKey:@"src"]; + [self setAttributes:[arguments objectForKey:WebPlugInAttributesKey]]; + NSString *srcAttribute = [[self attributes] objectForKey:@"src"]; if (srcAttribute) { - self.src = srcAttribute; + [self setSrc:srcAttribute]; } else { - NSString *dataAttribute = [self.attributes objectForKey:@"data"]; - if (dataAttribute) self.src = dataAttribute; + NSString *dataAttribute = [[self attributes] objectForKey:@"data"]; + if (dataAttribute) [self setSrc:dataAttribute]; } // set tooltip - if (self.src) [self setToolTip:self.src]; + if ([self src]) [self setToolTip:[self src]]; // Read in flashvars (needed to determine YouTube videos) - NSString* flashvars = [ self.attributes objectForKey: @"flashvars" ]; + NSString* flashvars = [[self attributes] objectForKey: @"flashvars" ]; if( flashvars != nil ) _flashVars = [ [ self _flashVarDictionary: flashvars ] retain ]; @@ -149,25 +158,25 @@ - (id) initWithArguments:(NSDictionary *)arguments // check whether it's from YouTube and get the video_id - _fromYouTube = [self.host isEqualToString:@"www.youtube.com"] + _fromYouTube = [[self host] isEqualToString:@"www.youtube.com"] || ( flashvars != nil && [flashvars rangeOfString: @"www.youtube.com"].location != NSNotFound ) - || (self.src != nil && [self.src rangeOfString: @"youtube.com"].location != NSNotFound ); + || ([self src] != nil && [[self src] rangeOfString: @"youtube.com"].location != NSNotFound ); if (_fromYouTube) { NSString *videoId = [ self flashvarWithName: @"video_id" ]; if (videoId != nil) { - self.videoId = videoId; + [self setVideoId:videoId]; } else { // scrub the URL to determine the video_id NSString *videoIdFromURL = nil; - NSScanner *URLScanner = [[NSScanner alloc] initWithString:self.src]; + NSScanner *URLScanner = [[NSScanner alloc] initWithString:[self src]]; [URLScanner scanUpToString:@"youtube.com/v/" intoString:nil]; if ([URLScanner scanString:@"youtube.com/v/" intoString:nil]) { // URL is in required format, next characters are the id [URLScanner scanUpToString:@"&" intoString:&videoIdFromURL]; - if (videoIdFromURL) self.videoId = videoIdFromURL; + if (videoIdFromURL) [self setVideoId:videoIdFromURL]; } [URLScanner release]; } @@ -283,34 +292,34 @@ - (id) initWithArguments:(NSDictionary *)arguments NSMutableDictionary *originalOpacityDict = [NSMutableDictionary dictionary]; NSString *opacityResetString = @"; opacity: 1.000 !important; -moz-opacity: 1 !important; filter: alpha(opacity=1) !important;"; - NSString *originalWmode = [self.container getAttribute:@"wmode"]; - NSString *originalStyle = [self.container getAttribute:@"style"]; - NSString *originalParentWmode = [(DOMElement *)[self.container parentNode] getAttribute:@"wmode"]; - NSString *originalParentStyle = [(DOMElement *)[self.container parentNode] getAttribute:@"style"]; + NSString *originalWmode = [[self container] getAttribute:@"wmode"]; + NSString *originalStyle = [[self container] getAttribute:@"style"]; + NSString *originalParentWmode = [(DOMElement *)[[self container] parentNode] getAttribute:@"wmode"]; + NSString *originalParentStyle = [(DOMElement *)[[self container] parentNode] getAttribute:@"style"]; if (originalWmode != nil && [originalWmode length] > 0u && ![originalWmode isEqualToString:@"opaque"]) { [originalOpacityDict setObject:originalWmode forKey:@"self-wmode"]; - [self.container setAttribute:@"wmode" value:@"opaque"]; + [[self container] setAttribute:@"wmode" value:@"opaque"]; } if (originalStyle != nil && [originalStyle length] > 0u && ![originalStyle hasSuffix:opacityResetString]) { [originalOpacityDict setObject:originalStyle forKey:@"self-style"]; [originalOpacityDict setObject:[originalStyle stringByAppendingString:opacityResetString] forKey:@"modified-self-style"]; - [self.container setAttribute:@"style" value:[originalStyle stringByAppendingString:opacityResetString]]; + [[self container] setAttribute:@"style" value:[originalStyle stringByAppendingString:opacityResetString]]; } if (originalParentWmode != nil && [originalParentWmode length] > 0u && ![originalParentWmode isEqualToString:@"opaque"]) { [originalOpacityDict setObject:originalParentWmode forKey:@"parent-wmode"]; - [(DOMElement *)[self.container parentNode] setAttribute:@"wmode" value:@"opaque"]; + [(DOMElement *)[[self container] parentNode] setAttribute:@"wmode" value:@"opaque"]; } if (originalParentStyle != nil && [originalParentStyle length] > 0u && ![originalParentStyle hasSuffix:opacityResetString]) { [originalOpacityDict setObject:originalParentStyle forKey:@"parent-style"]; [originalOpacityDict setObject:[originalParentStyle stringByAppendingString:opacityResetString] forKey:@"modified-parent-style"]; - [(DOMElement *)[self.container parentNode] setAttribute:@"style" value:[originalParentStyle stringByAppendingString:opacityResetString]]; + [(DOMElement *)[[self container] parentNode] setAttribute:@"style" value:[originalParentStyle stringByAppendingString:opacityResetString]]; } - self.originalOpacityAttributes = originalOpacityDict; + [self setOriginalOpacityAttributes:originalOpacityDict]; } return self; @@ -325,11 +334,11 @@ - (void) dealloc // notify that this ClickToFlash plugin is going away [[CTFMenubarMenuController sharedController] unregisterView: self]; - self.container = nil; - self.host = nil; - self.webView = nil; - self.baseURL = nil; - self.attributes = nil; + [self setContainer:nil]; + [self setHost:nil]; + [self setWebView:nil]; + [self setBaseURL:nil]; + [self setAttributes:nil]; [_flashVars release]; [_badgeText release]; @@ -382,11 +391,25 @@ - (void) mouseDown:(NSEvent *)event [self setNeedsDisplay:YES]; // Track the mouse so that we can undo our pressed-in look if the user drags the mouse outside the view, and reinstate it if the user drags it back in. - trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] - options:NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow | NSTrackingEnabledDuringMouseDrag - owner:self - userInfo:nil]; - [self addTrackingArea:trackingArea]; + trackingArea = [NSClassFromString(@"NSTrackingArea") alloc]; + if (trackingArea != nil) + { + [trackingArea initWithRect:[self bounds] + options:MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag + owner:self + userInfo:nil]; + [self addTrackingArea:trackingArea]; + } + else + { + trackingArea = [NSClassFromString(@"MATrackingArea") alloc]; + [trackingArea initWithRect:[self bounds] + options:MATrackingMouseEnteredAndExited | MATrackingActiveInKeyWindow | MATrackingEnabledDuringMouseDrag + owner:self + userInfo:nil]; + [MATrackingArea addTrackingArea:trackingArea toView:self]; + usingMATrackingArea = YES; + } } } @@ -408,7 +431,14 @@ - (void) mouseUp:(NSEvent *)event [self display]; // We're done tracking. - [self removeTrackingArea:trackingArea]; + if (usingMATrackingArea) + { + [MATrackingArea removeTrackingArea:trackingArea fromView:self]; + } + else + { + [self removeTrackingArea:trackingArea]; + } [trackingArea release]; trackingArea = nil; @@ -429,15 +459,15 @@ - (BOOL) _isOptionPressed - (BOOL) isConsideredInvisible { - int height = (int)([self webView].frame.size.height); - int width = (int)([self webView].frame.size.width); + int height = (int)([[self webView] frame].size.height); + int width = (int)([[self webView] frame].size.width); if ( (height <= maxInvisibleDimension) && (width <= maxInvisibleDimension) ) { return YES; } - NSDictionary *attributes = self.attributes; + NSDictionary *attributes = [self attributes]; if ( attributes != nil ) { NSString *heightObject = [attributes objectForKey:@"height"]; @@ -496,7 +526,7 @@ - (BOOL) validateMenuItem: (NSMenuItem *)menuItem { NSString* title = [NSString stringWithFormat: NSLocalizedString(@"Add %@ to Whitelist", @"Add to Whitelist menu title"), - self.host]; + [self host]]; [menuItem setTitle: title]; if ([self _isHostWhitelisted]) enabled = NO; @@ -674,22 +704,27 @@ - (void) _drawBadgeWithPressed: (BOOL) pressed NSColor *startingColor = [NSColor colorWithDeviceWhite:1.0 alpha:1.0]; NSColor *endingColor = [NSColor colorWithDeviceWhite:1.0 alpha:0.0]; - NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:startingColor endingColor:endingColor]; - - NSPoint gearImageCenter = NSMakePoint(0 - viewWidth/2 + margin + gearImage.size.height/2, - viewHeight/2 - margin - gearImage.size.height/2); - - // draw gradient behind gear so that it's visible even on dark backgrounds - [gradient drawFromCenter:gearImageCenter - radius:0.0 - toCenter:gearImageCenter - radius:gearImage.size.height/2*1.5 - options:0]; - - [gradient release]; - + + NSPoint gearImageCenter = NSMakePoint(0 - viewWidth/2 + margin + [gearImage size].height/2, + viewHeight/2 - margin - [gearImage size].height/2); + + id gradient = [NSClassFromString(@"NSGradient") alloc]; + if (gradient != nil) + { + [gradient initWithStartingColor:startingColor endingColor:endingColor]; + + // draw gradient behind gear so that it's visible even on dark backgrounds + [gradient drawFromCenter:gearImageCenter + radius:0.0 + toCenter:gearImageCenter + radius:[gearImage size].height/2*1.5 + options:0]; + + [gradient release]; + } + // draw the gear image - [gearImage drawAtPoint:NSMakePoint(0 - viewWidth/2 + margin,viewHeight/2 - margin - gearImage.size.height) + [gearImage drawAtPoint:NSMakePoint(0 - viewWidth/2 + margin,viewHeight/2 - margin - [gearImage size].height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; @@ -712,19 +747,37 @@ - (void) _drawBackground NSColor *startingColor = [NSColor colorWithDeviceWhite:1.0 alpha:0.15]; NSColor *endingColor = [NSColor colorWithDeviceWhite:0.0 alpha:0.15]; - NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:startingColor endingColor:endingColor]; - + // When the mouse is up or outside the view, we want a convex look, so we draw the gradient downward (90+180=270 degrees). // When the mouse is down and inside the view, we want a concave look, so we draw the gradient upward (90 degrees). - [gradient drawInBezierPath:[NSBezierPath bezierPathWithRect:fillRect] angle:90.0 + ((mouseIsDown && mouseInside) ? 0.0 : 180.0)]; + id gradient = [NSClassFromString(@"NSGradient") alloc]; + if (gradient != nil) + { + [gradient initWithStartingColor:startingColor endingColor:endingColor]; + + [gradient drawInBezierPath:[NSBezierPath bezierPathWithRect:fillRect] angle:90.0 + ((mouseIsDown && mouseInside) ? 0.0 : 180.0)]; + + [gradient release]; + } + else + { + //tweak colors for better compatibility with linearGradientFill + startingColor = [NSColor colorWithDeviceWhite:0.633 alpha:0.15]; + endingColor = [NSColor colorWithDeviceWhite:0.333 alpha:0.15]; + NSBezierPath *path = [NSBezierPath bezierPath]; + + //Draw Gradient + [path linearGradientFill:fillRect + startColor:((mouseIsDown && mouseInside) ? endingColor : startingColor) + endColor:((mouseIsDown && mouseInside) ? startingColor : endingColor)]; + [path stroke]; + } // Draw stroke [[NSColor colorWithCalibratedWhite:0.0 alpha:0.50] set]; [NSBezierPath setDefaultLineWidth:2.0]; [NSBezierPath setDefaultLineCapStyle:NSSquareLineCapStyle]; [[NSBezierPath bezierPathWithRect:strokeRect] stroke]; - - [gradient release]; // Draw label [ self _drawBadgeWithPressed: mouseIsDown && mouseInside ]; @@ -772,7 +825,7 @@ - (NSString*) _videoHash - (BOOL) _hasH264Version { if( _fromYouTube ) - return self.videoId != nil && [ self _videoHash ] != nil; + return [self videoId] != nil && [ self _videoHash ] != nil; else return NO; } @@ -786,7 +839,7 @@ - (BOOL) _useH264Version - (void) _convertElementForMP4: (DOMElement*) element { - NSString* video_id = self.videoId; + NSString* video_id = [self videoId]; NSString* video_hash = [ self _videoHash ]; NSString* src = [ NSString stringWithFormat: @"http://www.youtube.com/get_video?fmt=18&video_id=%@&t=%@", @@ -818,7 +871,7 @@ - (void) _convertToMP4Container - (void) _convertToMP4ContainerAfterDelay { - DOMElement* newElement = (DOMElement*) [ self.container cloneNode: NO ]; + DOMElement* newElement = (DOMElement*) [ [self container] cloneNode: NO ]; [ self _convertElementForMP4: newElement ]; @@ -826,8 +879,8 @@ - (void) _convertToMP4ContainerAfterDelay [[self retain] autorelease]; // Replace self with element. - [self.container.parentNode replaceChild:newElement oldChild:self.container]; - self.container = nil; + [[[self container] parentNode] replaceChild:newElement oldChild:[self container]]; + [self setContainer:nil]; } - (NSString *)launchedAppBundleIdentifier @@ -868,14 +921,14 @@ - (NSString *)launchedAppBundleIdentifier - (IBAction)downloadH264:(id)sender { - NSString* video_id = self.videoId; + NSString* video_id = [self videoId]; NSString* video_hash = [ self _videoHash ]; NSString* src = [ NSString stringWithFormat: @"http://www.youtube.com/get_video?fmt=18&video_id=%@&t=%@", video_id, video_hash ]; [[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:[NSURL URLWithString:src]] - withAppBundleIdentifier:self.launchedAppBundleIdentifier + withAppBundleIdentifier:[self launchedAppBundleIdentifier] options:NSWorkspaceLaunchDefault additionalEventParamDescriptor:[NSAppleEventDescriptor nullDescriptor] launchIdentifiers:nil]; @@ -883,10 +936,10 @@ - (IBAction)downloadH264:(id)sender - (IBAction)loadYouTubePage:(id)sender { - NSString* YouTubePageURL = [ NSString stringWithFormat: @"http://www.youtube.com/watch?v=%@",self.videoId ]; + NSString* YouTubePageURL = [ NSString stringWithFormat: @"http://www.youtube.com/watch?v=%@", [self videoId] ]; [[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:[NSURL URLWithString:YouTubePageURL]] - withAppBundleIdentifier:self.launchedAppBundleIdentifier + withAppBundleIdentifier:[self launchedAppBundleIdentifier] options:NSWorkspaceLaunchDefault additionalEventParamDescriptor:[NSAppleEventDescriptor nullDescriptor] launchIdentifiers:nil]; @@ -928,24 +981,24 @@ - (void) _convertTypesForFlashContainerAfterDelay DOMNodeList *nodeList = nil; NSUInteger i; - [self _convertTypesForElement:self.container]; + [self _convertTypesForElement:[self container]]; - nodeList = [self.container getElementsByTagName:@"object"]; - for (i = 0; i < nodeList.length; i++) { + nodeList = [[self container] getElementsByTagName:@"object"]; + for (i = 0; i < [nodeList length]; i++) { [self _convertTypesForElement:(DOMElement *)[nodeList item:i]]; } - nodeList = [self.container getElementsByTagName:@"embed"]; - for (i = 0; i < nodeList.length; i++) { + nodeList = [[self container] getElementsByTagName:@"embed"]; + for (i = 0; i < [nodeList length]; i++) { [self _convertTypesForElement:(DOMElement *)[nodeList item:i]]; } // Remove & reinsert the node to persuade the plugin system to notice the type change: - id parent = self.container.parentNode; - id successor = self.container.nextSibling; - [parent removeChild:self.container]; - [parent insertBefore:self.container refChild:successor]; - self.container = nil; + id parent = [[self container] parentNode]; + id successor = [[self container] nextSibling]; + [parent removeChild:[self container]]; + [parent insertBefore:[self container] refChild:successor]; + [self setContainer:nil]; } - (void) _prepareForConversion @@ -960,41 +1013,235 @@ - (void) _prepareForConversion - (void) _revertToOriginalOpacityAttributes { - NSString *selfWmode = [self.originalOpacityAttributes objectForKey:@"self-wmode"]; + NSString *selfWmode = [[self originalOpacityAttributes] objectForKey:@"self-wmode"]; if (selfWmode != nil ) { - [self.container setAttribute:@"wmode" value:selfWmode]; + [[self container] setAttribute:@"wmode" value:selfWmode]; } - NSString *currentStyle = [self.container getAttribute:@"style"]; - NSString *originalSelfStyle = [self.originalOpacityAttributes objectForKey:@"self-style"]; + NSString *currentStyle = [[self container] getAttribute:@"style"]; + NSString *originalSelfStyle = [[self originalOpacityAttributes] objectForKey:@"self-style"]; if (originalSelfStyle != nil ) { - if ([currentStyle isEqualToString:[self.originalOpacityAttributes objectForKey:@"modified-self-style"]]) { - [self.container setAttribute:@"style" value:originalSelfStyle]; + if ([currentStyle isEqualToString:[[self originalOpacityAttributes] objectForKey:@"modified-self-style"]]) { + [[self container] setAttribute:@"style" value:originalSelfStyle]; } } - NSString *parentWmode = [self.originalOpacityAttributes objectForKey:@"parent-wmode"]; + NSString *parentWmode = [[self originalOpacityAttributes] objectForKey:@"parent-wmode"]; if (parentWmode != nil ) { - [(DOMElement *)[self.container parentNode] setAttribute:@"wmode" value:parentWmode]; + [(DOMElement *)[[self container] parentNode] setAttribute:@"wmode" value:parentWmode]; } - NSString *currentParentStyle = [(DOMElement *)[self.container parentNode] getAttribute:@"style"]; - NSString *originalParentStyle = [self.originalOpacityAttributes objectForKey:@"parent-style"]; + NSString *currentParentStyle = [(DOMElement *)[[self container] parentNode] getAttribute:@"style"]; + NSString *originalParentStyle = [[self originalOpacityAttributes] objectForKey:@"parent-style"]; if (originalParentStyle != nil ) { - if ([currentParentStyle isEqualToString:[self.originalOpacityAttributes objectForKey:@"modified-parent-style"]]) { - [(DOMElement *)[self.container parentNode] setAttribute:@"style" value:originalParentStyle]; + if ([currentParentStyle isEqualToString:[[self originalOpacityAttributes] objectForKey:@"modified-parent-style"]]) { + [(DOMElement *)[[self container] parentNode] setAttribute:@"style" value:originalParentStyle]; } } } -@synthesize webView = _webView; -@synthesize container = _container; -@synthesize host = _host; -@synthesize baseURL = _baseURL; -@synthesize attributes = _attributes; -@synthesize originalOpacityAttributes = _originalOpacityAttributes; -@synthesize src = _src; -@synthesize videoId = _videoId; -@synthesize launchedAppBundleIdentifier = _launchedAppBundleIdentifier; +- (WebView *)webView +{ + return _webView; +} +- (void)setWebView:(WebView *)newValue +{ + [newValue retain]; + [_webView release]; + _webView = newValue; +} + +- (DOMElement *)container +{ + return _container; +} +- (void)setContainer:(DOMElement *)newValue +{ + [newValue retain]; + [_container release]; + _container = newValue; +} + +- (NSString *)host +{ + return _host; +} +- (void)setHost:(NSString *)newValue +{ + [newValue retain]; + [_host release]; + _host = newValue; +} + +- (NSString *)baseURL +{ + return _baseURL; +} +- (void)setBaseURL:(NSString *)newValue +{ + [newValue retain]; + [_baseURL release]; + _baseURL = newValue; +} + +- (NSDictionary *)attributes +{ + return _attributes; +} +- (void)setAttributes:(NSDictionary *)newValue +{ + [newValue retain]; + [_attributes release]; + _attributes = newValue; +} + +- (NSDictionary *)originalOpacityAttributes +{ + return _originalOpacityAttributes; +} +- (void)setOriginalOpacityAttributes:(NSDictionary *)newValue +{ + [newValue retain]; + [_originalOpacityAttributes release]; + _originalOpacityAttributes = newValue; +} + +- (NSString *)src +{ + return _src; +} +- (void)setSrc:(NSString *)newValue +{ + [newValue retain]; + [_src release]; + _src = newValue; +} + +- (NSString *)videoId +{ + return _videoId; +} +- (void)setVideoId:(NSString *)newValue +{ + [newValue retain]; + [_videoId release]; + _videoId = newValue; +} + +- (void)setLaunchedAppBundleIdentifier:(NSString *)newValue +{ + [newValue retain]; + [_launchedAppBundleIdentifier release]; + _launchedAppBundleIdentifier = newValue; +} + +@end + + +//### globals +float start_red, +start_green, +start_blue, +start_alpha; +float end_red, +end_green, +end_blue, +end_alpha; +float d_red, +d_green, +d_blue, +d_alpha; + +@implementation NSBezierPath(MRGradientFill) + +static void +evaluate(void *info, const float *in, float *out) +{ + // red + *out++ = start_red + *in * d_red; + + // green + *out++ = start_green + *in * d_green; + + // blue + *out++ = start_blue + *in * d_blue; + + //alpha + *out++ = start_alpha + *in * d_alpha; +} + +float absDiff(float a, float b); +float absDiff(float a, float b) +{ + return (a < b) ? b-a : a-b; +} + +-(void)linearGradientFill:(NSRect)thisRect + startColor:(NSColor *)startColor + endColor:(NSColor *)endColor +{ + CGColorSpaceRef colorspace = nil; + CGShadingRef shading; + static CGPoint startPoint = { 0, 0 }; + static CGPoint endPoint = { 0, 0 }; + //int k; + CGFunctionRef function; + //CGFunctionRef (*getFunction)(CGColorSpaceRef); + //CGShadingRef (*getShading)(CGColorSpaceRef, CGFunctionRef); + + // get my context + CGContextRef currentContext = + (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + + + NSColor *s = [startColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + NSColor *e = [endColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]; + // set up colors for gradient + start_red = [s redComponent]; + start_green = [s greenComponent]; + start_blue = [s blueComponent]; + start_alpha = [s alphaComponent]; + + end_red = [e redComponent]; + end_green = [e greenComponent]; + end_blue = [e blueComponent]; + end_alpha = [e alphaComponent]; + + d_red = absDiff(end_red, start_red); + d_green = absDiff(end_green, start_green); + d_blue = absDiff(end_blue, start_blue); + d_alpha = absDiff(end_alpha ,start_alpha); + + + // draw gradient + colorspace = CGColorSpaceCreateDeviceRGB(); + + size_t components; + static const float domain[2] = { 0.0, 1.0 }; + static const float range[10] = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; + static const CGFunctionCallbacks callbacks = { 0, &evaluate, NULL }; + + components = 1 + CGColorSpaceGetNumberOfComponents(colorspace); + function = CGFunctionCreate((void *)components, 1, domain, components, + range, &callbacks); + + // function = getFunction(colorspace); + startPoint.x = 0; + startPoint.y = thisRect.origin.y; + endPoint.x = 0; + endPoint.y = NSMaxY(thisRect); + + + shading = CGShadingCreateAxial(colorspace, + startPoint, endPoint, + function, + NO, NO); + + CGContextDrawShading(currentContext, shading); + + CGFunctionRelease(function); + CGShadingRelease(shading); + CGColorSpaceRelease(colorspace); +} @end diff --git a/README.markdown b/README.markdown index 2bbf2966..f1cf23fd 100644 --- a/README.markdown +++ b/README.markdown @@ -127,6 +127,12 @@ Want to chip in? [Here's what needs to be done](http://rentzsch.lighthouseapp.co * [DEV] Populate CFBundleVersion with ${PRODUCT_VERSION} instead of hard-coding with 700. (Dave Dribin) +* **1.3+tiger** [download tiger/leo version](http://portway-ave.com/clicktoflash/ClickToFlash-1.3+Tiger.zip) + * [NEW] Universal Tiger/Leo PPC/Intel Compatibility! (Well, its been tested on Tiger/PPC and Leo/Intel, but the plugin is now universal and should work everywhere) + * [NEW] The installer now also works on Tiger + * [FIX] Darkened gradient on Tiger for better visibility + * [FIX] Removed Copy address contextual menu as it was flakey + * **1.3** [download](http://s3.amazonaws.com/clicktoflash/ClickToFlash-1.3.zip) * [NEW] Flash badge is now drawn in code (vector image), and draws smaller in smaller flash boxes. [bug 12](http://rentzsch.lighthouseapp.com/projects/24342/tickets/12) @@ -145,6 +151,9 @@ flash boxes when whitelisting one ([bug 10](http://rentzsch.lighthouseapp.com/pr * [DEV] Make Rakefile honor build products directory. [bug 43](http://rentzsch.lighthouseapp.com/projects/24342/tickets/43) ([Chris Parker](http://github.com/tgaul/clicktoflash/commit/021eebfd274b4e415c31c2ac9e4bb2ffed569ee4)) +* **1.2+tiger** [download tiger version](http://portway-ave.com/clicktoflash/ClickToFlashTiger-1.2.zip) + * [NEW] Added copy address to clipboard ([Peter Hosey](http://github.com/boredzo/clicktoflash/commit/19cc5b9b25f1e9ad2e62e61d795a1b0e5368822b)) + * **1.2** [download](http://s3.amazonaws.com/clicktoflash/ClickToFlash-1.2.zip) * [NEW] Handle `` and `` that are missing a `type` attribute. That fixes a number of the broken sites. [bug #19](http://rentzsch.lighthouseapp.com/projects/24342/tickets/19-banner-ad-appears-without-whitelisting) ([Jason Foreman](http://github.com/threeve/clicktoflash/commit/e4a7ad83c312bcc3d7400562905122951ae85763)) diff --git a/SparkleManager.h b/SparkleManager.h old mode 100644 new mode 100755 index d3b0d649..bae08d13 --- a/SparkleManager.h +++ b/SparkleManager.h @@ -40,6 +40,7 @@ - (void)startAutomaticallyCheckingForUpdates; - (void)checkForUpdates; -@property (retain) NSString *pathToRelaunch; +- (NSString *)pathToRelaunch; +- (void)setPathToRelaunch:(NSString *)newValue; @end diff --git a/SparkleManager.m b/SparkleManager.m old mode 100644 new mode 100755 index 8793e580..ee09258d --- a/SparkleManager.m +++ b/SparkleManager.m @@ -120,6 +120,15 @@ - (NSString*)pathToRelaunchForUpdater:(SUUpdater*)updater { return _pathToRelaunch; } -@synthesize pathToRelaunch = _pathToRelaunch; +- (NSString *)pathToRelaunch +{ + return _pathToRelaunch; +} +- (void)setPathToRelaunch:(NSString *)newValue +{ + [newValue retain]; + [_pathToRelaunch release]; + _pathToRelaunch = newValue; +} @end