Revision: 3855
http://skim-app.svn.sourceforge.net/skim-app/?rev=3855&view=rev
Author: hofman
Date: 2008-05-06 09:46:09 -0700 (Tue, 06 May 2008)
Log Message:
-----------
Add functions to add/swizzle class methods. Avoid redefining
newlineCharacterSet on Leopard.
Modified Paths:
--------------
trunk/NSCharacterSet_SKExtensions.h
trunk/NSCharacterSet_SKExtensions.m
trunk/PDFDisplayView_SKExtensions.m
trunk/SKUtilities.h
trunk/SKUtilities.m
Modified: trunk/NSCharacterSet_SKExtensions.h
===================================================================
--- trunk/NSCharacterSet_SKExtensions.h 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/NSCharacterSet_SKExtensions.h 2008-05-06 16:46:09 UTC (rev 3855)
@@ -40,7 +40,6 @@
@interface NSCharacterSet (SKExtensions)
-+ (id)newlineCharacterSet;
+ (id)nonWhitespaceCharacterSet;
+ (id)nonWhitespaceAndNewlineCharacterSet;
@end
Modified: trunk/NSCharacterSet_SKExtensions.m
===================================================================
--- trunk/NSCharacterSet_SKExtensions.m 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/NSCharacterSet_SKExtensions.m 2008-05-06 16:46:09 UTC (rev 3855)
@@ -37,11 +37,12 @@
*/
#import "NSCharacterSet_SKExtensions.h"
+#import "SKUtilities.h"
@implementation NSCharacterSet (SKExtensions)
-+ (id)newlineCharacterSet {
++ (id)replacementNewlineCharacterSet {
static NSCharacterSet *newlineCharacterSet = nil;
if (newlineCharacterSet == nil) {
NSMutableCharacterSet *tmpSet = [[NSCharacterSet
whitespaceCharacterSet] mutableCopy];
@@ -67,4 +68,9 @@
return nonWhitespaceAndNewlineCharacterSet;
}
++ (void)load {
+ if ([self respondsToSelector:@selector(newlineCharacterSet)] == NO)
+ SKRegisterClassMethodImplementationWithSelector(self,
@selector(newlineCharacterSet), @selector(replacementNewlineCharacterSet));
+}
+
@end
Modified: trunk/PDFDisplayView_SKExtensions.m
===================================================================
--- trunk/PDFDisplayView_SKExtensions.m 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/PDFDisplayView_SKExtensions.m 2008-05-06 16:46:09 UTC (rev 3855)
@@ -267,13 +267,13 @@
if ([self
instancesRespondToSelector:@selector(accessibilityFocusedUIElement)])
originalAccessibilityFocusedUIElement =
SKReplaceMethodImplementationWithSelector(self,
@selector(accessibilityFocusedUIElement),
@selector(replacementAccessibilityFocusedUIElement));
if ([self
instancesRespondToSelector:@selector(accessibilityRangeForPositionAttributeForParameter:)]
== NO)
- SKAddMethodImplementationWithSelector(self,
@selector(accessibilityRangeForPositionAttributeForParameter:),
@selector(replacementAccessibilityRangeForPositionAttributeForParameter:));
+ SKRegisterMethodImplementationWithSelector(self,
@selector(accessibilityRangeForPositionAttributeForParameter:),
@selector(replacementAccessibilityRangeForPositionAttributeForParameter:));
if ([self
instancesRespondToSelector:@selector(accessibilityRTFForRangeAttributeForParameter:)]
== NO)
- SKAddMethodImplementationWithSelector(self,
@selector(accessibilityRTFForRangeAttributeForParameter:),
@selector(replacementAccessibilityRTFForRangeAttributeForParameter:));
+ SKRegisterMethodImplementationWithSelector(self,
@selector(accessibilityRTFForRangeAttributeForParameter:),
@selector(replacementAccessibilityRTFForRangeAttributeForParameter:));
if ([self
instancesRespondToSelector:@selector(accessibilityAttributedStringForRangeAttributeForParameter:)]
== NO)
- SKAddMethodImplementationWithSelector(self,
@selector(accessibilityAttributedStringForRangeAttributeForParameter:),
@selector(replacementAccessibilityAttributedStringForRangeAttributeForParameter:));
+ SKRegisterMethodImplementationWithSelector(self,
@selector(accessibilityAttributedStringForRangeAttributeForParameter:),
@selector(replacementAccessibilityAttributedStringForRangeAttributeForParameter:));
if ([self
instancesRespondToSelector:@selector(accessibilityStyleRangeForIndexAttributeForParameter:)]
== NO)
- SKAddMethodImplementationWithSelector(self,
@selector(accessibilityStyleRangeForIndexAttributeForParameter:),
@selector(replacementAccessibilityStyleRangeForIndexAttributeForParameter:));
+ SKRegisterMethodImplementationWithSelector(self,
@selector(accessibilityStyleRangeForIndexAttributeForParameter:),
@selector(replacementAccessibilityStyleRangeForIndexAttributeForParameter:));
}
@end
Modified: trunk/SKUtilities.h
===================================================================
--- trunk/SKUtilities.h 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/SKUtilities.h 2008-05-06 16:46:09 UTC (rev 3855)
@@ -17,9 +17,11 @@
#import <objc/objc-class.h>
#import <objc/objc-runtime.h>
-IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp);
+IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp, BOOL
isInstance);
IMP SKReplaceMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL
impSelector);
-void SKAddMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL
impSelector);
+IMP SKReplaceClassMethodImplementationWithSelector(Class aClass, SEL
aSelector, SEL impSelector);
+IMP SKRegisterMethodImplementationWithSelector(Class aClass, SEL aSelector,
SEL impSelector);
+IMP SKRegisterClassMethodImplementationWithSelector(Class aClass, SEL
aSelector, SEL impSelector);
#define OBINITIALIZE \
do { \
Modified: trunk/SKUtilities.m
===================================================================
--- trunk/SKUtilities.m 2008-05-06 12:43:51 UTC (rev 3854)
+++ trunk/SKUtilities.m 2008-05-06 16:46:09 UTC (rev 3855)
@@ -19,6 +19,11 @@
// wrappers around 10.5 only functions, use 10.4 API when the function is not
defined
+static Class SK_object_getClass(id object)
+{
+ return object_getClass != NULL ? object_getClass(object) : object->isa;
+}
+
static IMP SK_method_getImplementation(Method aMethod)
{
return method_getImplementation != NULL ?
method_getImplementation(aMethod) : aMethod->method_imp;
@@ -63,21 +68,28 @@
}
}
-IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp)
+static Method SK_class_getMethod(Class aClass, SEL aSelector, BOOL isInstance)
{
- Method localMethod, superMethod = NULL;
+ return isInstance ? class_getInstanceMethod(aClass, aSelector) :
class_getClassMethod(aClass, aSelector);
+}
+
+IMP SKReplaceMethodImplementation(Class aClass, SEL aSelector, IMP anImp, BOOL
isInstance)
+{
+ Method superMethod = NULL;
+ Method localMethod = SK_class_getMethod(aClass, aSelector, isInstance);
IMP oldImp = NULL;
Class superCls = Nil;
+ Class realClass = isInstance ? aClass : SK_object_getClass(aClass);
extern void _objc_flush_caches(Class);
- if ((localMethod = class_getInstanceMethod(aClass, aSelector))) {
+ if (localMethod) {
if (superCls = SK_class_getSuperclass(aClass))
- superMethod = class_getInstanceMethod(superCls, aSelector);
+ superMethod = SK_class_getMethod(superCls, aSelector, isInstance);
if (superMethod == localMethod) {
// We are inheriting this method from the superclass. We do *not*
want to clobber the superclass's Method structure as that would replace the
implementation on a greater scope than the caller wanted. In this case,
install a new method at this class and return the superclass's implementation
as the old implementation (which it is).
oldImp = SK_method_getImplementation(localMethod);
- SK_class_addMethod(aClass, aSelector, anImp,
SK_method_getTypeEncoding(localMethod));
+ SK_class_addMethod(realClass, aSelector, anImp,
SK_method_getTypeEncoding(localMethod));
} else {
// Replace the method in place
oldImp = SK_method_setImplementation(localMethod, anImp);
@@ -85,7 +97,7 @@
// Flush the method cache, deprecated on 10.5
if (_objc_flush_caches != NULL)
- _objc_flush_caches(aClass);
+ _objc_flush_caches(realClass);
}
return oldImp;
@@ -93,11 +105,36 @@
IMP SKReplaceMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL
impSelector)
{
- return SKReplaceMethodImplementation(aClass, aSelector,
SK_method_getImplementation(class_getInstanceMethod(aClass, impSelector)));
+ return SKReplaceMethodImplementation(aClass, aSelector,
SK_method_getImplementation(class_getInstanceMethod(aClass, impSelector)), YES);
}
-void SKAddMethodImplementationWithSelector(Class aClass, SEL aSelector, SEL
impSelector)
+IMP SKReplaceClassMethodImplementationWithSelector(Class aClass, SEL
aSelector, SEL impSelector)
{
+ return SKReplaceMethodImplementation(aClass, aSelector,
SK_method_getImplementation(class_getClassMethod(aClass, impSelector)), NO);
+}
+
+IMP SKRegisterMethodImplementationWithSelector(Class aClass, SEL aSelector,
SEL impSelector)
+{
+ IMP imp = NULL;
Method method = class_getInstanceMethod(aClass, impSelector);
- SK_class_addMethod(aClass, aSelector, SK_method_getImplementation(method),
SK_method_getTypeEncoding(method));
+
+ if (method) {
+ imp = SK_method_getImplementation(method);
+ SK_class_addMethod(aClass, aSelector, imp,
SK_method_getTypeEncoding(method));
+ }
+
+ return imp;
}
+
+IMP SKRegisterClassMethodImplementationWithSelector(Class aClass, SEL
aSelector, SEL impSelector)
+{
+ IMP imp = NULL;
+ Method method = class_getClassMethod(aClass, impSelector);
+
+ if (method) {
+ imp = SK_method_getImplementation(method);
+ SK_class_addMethod(SK_object_getClass(aClass), aSelector, imp,
SK_method_getTypeEncoding(method));
+ }
+
+ return imp;
+}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit