diff --git a/AppKit/AppKit.j b/AppKit/AppKit.j index 9c820be65..95bbe6201 100644 --- a/AppKit/AppKit.j +++ b/AppKit/AppKit.j @@ -88,3 +88,4 @@ @import "CPWebView.j" @import "CPWindow.j" @import "CPWindowController.j" +@import "CPArrayController.j" diff --git a/AppKit/CPArrayController.j b/AppKit/CPArrayController.j index c11206f79..4953c3016 100644 --- a/AppKit/CPArrayController.j +++ b/AppKit/CPArrayController.j @@ -154,7 +154,7 @@ value = [value]; var oldSelection = nil, - oldSelectionIndexes = [[self selectionIndexes] copy]; + oldSelectionIndexes = [self selectionIndexes]; if ([self preservesSelection]) oldSelection = [self selectedObjects]; diff --git a/AppKit/CPControl.j b/AppKit/CPControl.j index 7de6719c4..db8a22cd9 100644 --- a/AppKit/CPControl.j +++ b/AppKit/CPControl.j @@ -545,6 +545,7 @@ var CPControlBlackColor = [CPColor blackColor]; return; [self _reverseSetBinding]; + [[CPNotificationCenter defaultCenter] postNotificationName:CPControlTextDidEndEditingNotification object:self userInfo:[CPDictionary dictionaryWithObject:[note object] forKey:"CPFieldEditor"]]; } diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 7950ac5ba..ec1245de8 100755 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -838,7 +838,7 @@ // Now theme the tableview var sortImage = [_CPCibCustomResource imageResourceWithName:"tableview-headerview-ascending.png" size:CGSizeMake(9.0, 8.0)], sortImageReversed = [_CPCibCustomResource imageResourceWithName:"tableview-headerview-descending.png" size:CGSizeMake(9.0, 8.0)], - alternatingRowColors = [[CPColor whiteColor], [CPColor colorWithHexString:@"e4e7ff"]], + alternatingRowColors = [[CPColor whiteColor], [CPColor colorWithRed:245.0 / 255.0 green:249.0 / 255.0 blue:252.0 / 255.0 alpha:1.0]], gridColor = [CPColor colorWithHexString:@"dce0e2"], selectionColor = [CPColor colorWithHexString:@"5f83b9"], sourceListSelectionColor = [CPDictionary dictionaryWithObjects: [ CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), [89.0/255.0, 153.0/255.0, 209.0/255.0,1.0, 33.0/255.0, 94.0/255.0, 208.0/255.0,1.0], [0,1], 2), diff --git a/Foundation/CPKeyValueCoding.j b/Foundation/CPKeyValueCoding.j index 104a6931f..1449899e4 100644 --- a/Foundation/CPKeyValueCoding.j +++ b/Foundation/CPKeyValueCoding.j @@ -33,6 +33,9 @@ CPUndefinedKeyException = @"CPUndefinedKeyException"; CPTargetObjectUserInfoKey = @"CPTargetObjectUserInfoKey"; CPUnknownUserInfoKey = @"CPUnknownUserInfoKey"; +var CPObjectAccessorsForClassKey = @"$CPObjectAccessorsForClassKey", + CPObjectModifiersForClassKey = @"$CPObjectModifiersForClassKey"; + @implementation CPObject (CPKeyValueCoding) + (BOOL)accessInstanceVariablesDirectly @@ -43,26 +46,18 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey"; /* @ignore */ + (SEL)_accessorForKey:(CPString)aKey { - if (!CPObjectAccessorsForClass) - CPObjectAccessorsForClass = [CPDictionary dictionary]; - - var UID = [isa UID], - selector = nil, - accessors = [CPObjectAccessorsForClass objectForKey:UID]; + var selector = nil, + accessors = isa[CPObjectAccessorsForClassKey]; if (accessors) { - selector = [accessors objectForKey:aKey]; + selector = accessors[aKey]; if (selector) return selector === [CPNull null] ? nil : selector; } else - { - accessors = [CPDictionary dictionary]; - - [CPObjectAccessorsForClass setObject:accessors forKey:UID]; - } + accessors = isa[CPObjectAccessorsForClassKey] = {}; var capitalizedKey = aKey.charAt(0).toUpperCase() + aKey.substr(1); @@ -73,12 +68,12 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey"; [self instancesRespondToSelector:selector = CPSelectorFromString("_" + aKey)] || [self instancesRespondToSelector:selector = CPSelectorFromString("_is" + capitalizedKey)]) { - [accessors setObject:selector forKey:aKey]; + accessors[aKey] = selector; return selector; } - [accessors setObject:[CPNull null] forKey:aKey]; + accessors[aKey] = [CPNull null]; return nil; } @@ -156,7 +151,7 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey"; - (id)valueForKey:(CPString)aKey { var theClass = [self class], - selector = [theClass _accessorForKey:aKey]; + selector = _accessorForKey(theClass, aKey); if (selector) return objj_msgSend(self, selector); @@ -264,6 +259,41 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey"; @end +var Null = [CPNull null]; +var _accessorForKey = function(theClass, aKey) +{ + var selector = nil, + accessors = theClass.isa[CPObjectAccessorsForClassKey]; + + if (accessors) + { + selector = accessors[aKey]; + + if (selector) + return selector === Null ? nil : selector; + } + else + accessors = theClass.isa[CPObjectAccessorsForClassKey] = {}; + + var capitalizedKey = aKey.charAt(0).toUpperCase() + aKey.substr(1); + + if ([theClass instancesRespondToSelector:selector = CPSelectorFromString("get" + capitalizedKey)] || + [theClass instancesRespondToSelector:selector = CPSelectorFromString(aKey)] || + [theClass instancesRespondToSelector:selector = CPSelectorFromString("is" + capitalizedKey)] || + [theClass instancesRespondToSelector:selector = CPSelectorFromString("_get" + capitalizedKey)] || + [theClass instancesRespondToSelector:selector = CPSelectorFromString("_" + aKey)] || + [theClass instancesRespondToSelector:selector = CPSelectorFromString("_is" + capitalizedKey)]) + { + accessors[aKey] = selector; + + return selector; + } + + accessors[aKey] = Null; + + return nil; +} + @implementation CPDictionary (KeyValueCoding) - (id)valueForKey:(CPString)aKey diff --git a/Foundation/CPKeyValueObserving.j b/Foundation/CPKeyValueObserving.j index 0ff9fdd26..6ea9c9a42 100644 --- a/Foundation/CPKeyValueObserving.j +++ b/Foundation/CPKeyValueObserving.j @@ -213,7 +213,6 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld, _targetObject = aTarget; _nativeClass = [aTarget class]; - _replacedKeys = [CPSet set]; _observersForKey = {}; _changesForKey = {}; _observersForKeyLength = 0; @@ -230,6 +229,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld, if (existingKVOClass) { _targetObject.isa = existingKVOClass; + _replacedKeys = existingKVOClass._replacedKeys; return; } @@ -237,6 +237,9 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld, objj_registerClassPair(kvoClass); + _replacedKeys = [CPSet set]; + kvoClass._replacedKeys = _replacedKeys; + //copy in the methods from our model subclass var methodList = _CPKVOModelSubclass.method_list, count = methodList.length, @@ -293,6 +296,7 @@ var kvoNewAndOld = CPKeyValueObservingOptionNew|CPKeyValueObservingOptionOld, var theMethod = class_getInstanceMethod(_nativeClass, theSelector); class_addMethod(_targetObject.isa, theSelector, theReplacementMethod(aKey, theMethod), ""); + [_replacedKeys addObject:aKey]; } }