diff --git a/AppKit/CPTheme.j b/AppKit/CPTheme.j index acbe1cee5e..76f08eb068 100644 --- a/AppKit/CPTheme.j +++ b/AppKit/CPTheme.j @@ -305,4 +305,9 @@ var CPThemeNameKey = @"CPThemeNameKey", return _bundle; } +- (BOOL)awakenCustomResources +{ + return YES; +} + @end diff --git a/AppKit/CPThemedAttribute.j b/AppKit/CPThemedAttribute.j index 9ab810f764..17dc3ffc48 100644 --- a/AppKit/CPThemedAttribute.j +++ b/AppKit/CPThemedAttribute.j @@ -30,18 +30,16 @@ var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*0010 @implementation CPThemedAttribute : CPObject { - BOOL _isSingularObject; - - JSObject _cache; + JSObject _cache; - CPString _name; - id _defaultValue; + CPString _name; + id _defaultValue; - CPTheme _theme; - Class _themedClass; + CPTheme _theme; + Class _themedClass; - id _values; - id _valueFromTheme; + CPDictionary _values; + CPThemedAttribute _attributeFromTheme; } - (id)initWithName:(CPString)aName defaultValue:(id)aDefaultValue theme:(CPTheme)aTheme class:(Class)aClass @@ -59,9 +57,8 @@ var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*0010 _theme = aTheme; _themedClass = aClass; - _isSingularObject = YES; - _values = nil; - _valueFromTheme = [_theme valueForAttributeName:_name inClass:_themedClass]; + _values = [CPDictionary dictionary]; + _attributeFromTheme = nil;//[_theme valueForAttributeName:_name inClass:_themedClass]; } return self; @@ -90,7 +87,7 @@ var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*0010 _cache = {}; _theme = aTheme; - _valueFromTheme = [_theme valueForAttributeName:_name inClass:_themedClass]; + _attributeFromTheme = nil;//[_theme valueForAttributeName:_name inClass:_themedClass]; } - (void)setThemedClass:(Class)aClass @@ -98,15 +95,19 @@ var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*0010 if (_themedClass === aClass) return; + _cache = {}; _themedClass = aClass; - _valueFromTheme = [_theme valueForAttributeName:_name inClass:_themedClass]; + _attributeFromTheme = nil;//[_theme valueForAttributeName:_name inClass:_themedClass]; } - (void)setValue:(id)aValue { _cache = {}; - _isSingularObject = YES; - _values = aValue; + + if (aValue === undefined || aValue === nil) + _values = [CPDictionary dictionary]; + else + _values = [CPDictionary dictionaryWithObject:aValue forKey:String(CPControlStateNormal)]; } - (id)value @@ -116,84 +117,61 @@ var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*0010 - (void)setValue:(id)aValue forControlState:(CPControlState)aState { + //delete _cache[aState]; _cache = {}; - if (aState !== CPControlStateNormal) - { - if (_isSingularObject) - { - var normalValue = _values; - - _isSingularObject = NO; - - _values = {}; - - if (normalValue) - _values[CPControlStateNormal] = normalValue; - } - - _values[aState] = aValue; - } - - else if (_isSingularObject) - _values = aValue; - + if ((aValue === undefined) || (aValue === nil)) + [_values removeObjectForKey:String(aState)]; else - _values[CPControlStateNormal] = aValue; + [_values setObject:aValue forKey:String(aState)]; } - (id)valueForControlState:(CPControlState)aState { var value = _cache[aState]; - if (value !== undefined && value !== nil) + // This can be nil. + if (value !== undefined) return value; - if (_isSingularObject) - var value = _values; + value = [_values objectForKey:String(aState)]; - else + // If we don't have a value, and we have a non-normal state... + if ((value === undefined || value === nil) && aState > 0) { - var value = _values[aState]; - - // If we don't have a value, and we have a non-normal state... - if ((value === undefined || value === nil) && aState > 0) + // If this is a composite state, find the closest partial subset match. + if (aState & (aState - 1)) { - // If this is a composite state, find the closest partial subset match. - if (aState & (aState - 1)) + var highestBitCount = 0, + states = [_values allKeys], + count = states.length; + + while (count--) { - var highestBitCount = 0; + // state is a string! + state = Number(states[count]); - for (state in _values) + // A & B = A iff A < B + if ((state & aState) === state) { - if (!_values.hasOwnProperty(state)) - continue; - - // state is a string! - state = Number(state); + var bitCount = (state < BIT_COUNT.length) ? BIT_COUNT[state] : bit_count(state); - // A & B = A iff A < B - if ((state & aState) === state) + if (bitCount > highestBitCount) { - var bitCount = (state < BIT_COUNT.length) ? BIT_COUNT[state] : bit_count(state); - - if (bitCount > highestBitCount) - { - highestBitCount = bitCount; - value = _values[state]; - } + highestBitCount = bitCount; + value = [_values objectForKey:String(state)]; } } } - - // Still don't have a value? OK, let's use the normal value. - if (value === undefined || value === nil) - value = _values[CPControlStateNormal]; } + + // Still don't have a value? OK, let's use the normal value. + if (value === undefined || value === nil) + value = [_values objectForKey:String(CPControlStateNormal)]; } if (value === undefined || value === nil) - value = [_valueFromTheme valueForControlState:aState]; + value = [_attributeFromTheme valueForControlState:aState]; if (value === undefined || value === nil) value = _defaultValue; @@ -205,36 +183,12 @@ var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*0010 - (CPThemedAttribute)themedAttributeMergedWithThemedAttribute:(CPThemedAttribute)aThemedAttribute { - var themedAttribute = CPThemedAttributeMake(_name, _defaultValue, _theme, _themedClass); + var mergedAttribute = CPThemedAttributeMake(_name, _defaultValue, _theme, _themedClass); - themedAttribute._isSingularObject = NO; - themedAttribute._values = {}; - - if (_isSingularObject) - themedAttribute._values[CPControlStateNormal] = _values; - - else - { - var values = _values; - - for (state in _values) - if (_values.hasOwnProperty(state)) - themedAttribute._values[state] = _values[state]; - } + mergedAttribute._values = [_values copy]; + [mergedAttribute._values addEntriesFromDictionary:aThemedAttribute._values]; - if (aThemedAttribute._isSingularObject) - themedAttribute._values[CPControlStateNormal] = aThemedAttribute._values; - - else - { - var values = aThemedAttribute._values; - - for (state in values) - if (values.hasOwnProperty(state)) - themedAttribute._values[state] = values[state]; - } - - return themedAttribute; + return mergedAttribute; } - (id)initWithCoder:(CPCoder)aCoder @@ -244,26 +198,7 @@ var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*0010 if (self) { _cache = {}; - _isSingularObject = [aCoder containsValueForKey:@"value"]; - - if (_isSingularObject) - _values = [aCoder decodeObjectForKey:"value"]; - - else - { - _values = {}; - - var statesAndValues = [aCoder decodeObjectForKey:"statesAndValues"]; - count = [statesAndValues count]; - - while (count--) - { - var value = statesAndValues[count--], - state = statesAndValues[count]; - - _values[state] = value; - } - } + _values = [aCoder decodeObjectForKey:@"values"]; } return self; @@ -271,25 +206,7 @@ var BIT_COUNT = [ 0 /*00000*/, 1 /*00001*/, 1 /*00010*/, 2 /*00011*/, 1 /*0010 - (void)encodeWithCoder:(CPCoder)aCoder { - if (_isSingularObject) - { - [aCoder encodeObject:_values forKey:@"value"]; - - return; - } - - var statesAndValues = []; - - for (state in _values) - { - if (!_values.hasOwnProperty(state)) - continue; - - statesAndValues.push(state); - statesAndValues.push(_values[state]); - } - - [aCoder encodeObject:statesAndValues forKey:@"statesAndValues"]; + [aCoder encodeObject:_values forKey:@"values"]; } @end @@ -301,14 +218,18 @@ function CPThemedAttributeMake(aName, aDefaultValue, aTheme, aClass) function CPThemedAttributeEncode(aCoder, aThemedAttribute) { - if (aThemedAttribute._isSingularObject) + var values = aThemedAttribute._values, + count = [values count]; + + if (count === 1) { - var actualValue = aThemedAttribute._values; + var key = [values allKeys][0]; - if (aThemedAttribute._values) - [aCoder encodeObject:actualValue forKey:"$a" + [aThemedAttribute name]]; + if (Number(key) === 0) + return [aCoder encodeObject:[values objectForKey:key] forKey:"$a" + [aThemedAttribute name]]; } - else + + if (count >= 1) [aCoder encodeObject:aThemedAttribute forKey:"$a" + [aThemedAttribute name]]; } diff --git a/AppKit/Cib/CPCib.j b/AppKit/Cib/CPCib.j index cae1ced632..1a358c022e 100644 --- a/AppKit/Cib/CPCib.j +++ b/AppKit/Cib/CPCib.j @@ -42,6 +42,7 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey"; { CPData _data; CPBundle _bundle; + BOOL _awakenCustomResources; } - (id)initWithContentsOfURL:(CPURL)aURL @@ -49,7 +50,10 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey"; self = [super init]; if (self) + { _data = [CPURLConnection sendSynchronousRequest:[CPURLRequest requestWithURL:aURL] returningResponse:nil error:nil]; + _awakenCustomResources = YES; + } return self; } @@ -66,9 +70,19 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey"; return self; } +- (void)_setAwakenCustomResources:(BOOL)shouldAwakenCustomResources +{ + _awakenCustomResources = shouldAwakenCustomResources; +} + +- (BOOL)_awakenCustomResources +{ + return _awakenCustomResources; +} + - (BOOL)instantiateCibWithExternalNameTable:(CPDictionary)anExternalNameTable { - var unarchiver = [[_CPCibKeyedUnarchiver alloc] initForReadingWithData:_data bundle:_bundle], + var unarchiver = [[_CPCibKeyedUnarchiver alloc] initForReadingWithData:_data bundle:_bundle awakenCustomResources:_awakenCustomResources], replacementClasses = [anExternalNameTable objectForKey:CPCibReplacementClasses]; if (replacementClasses) diff --git a/AppKit/Cib/_CPCibCustomResource.j b/AppKit/Cib/_CPCibCustomResource.j index ec34cc3493..d010763f04 100644 --- a/AppKit/Cib/_CPCibCustomResource.j +++ b/AppKit/Cib/_CPCibCustomResource.j @@ -80,7 +80,8 @@ var _CPCibCustomResourceClassNameKey = @"_CPCibCustomResourceClassNameKey", - (id)awakeAfterUsingCoder:(CPCoder)aCoder { - if ([aCoder respondsToSelector:@selector(bundle)]) + if ([aCoder respondsToSelector:@selector(bundle)] && + (![aCoder respondsToSelector:@selector(awakenCustomResources)] || [aCoder awakenCustomResources])) if (_className === @"CPImage") return [[CPImage alloc] initWithContentsOfFile:[[aCoder bundle] pathForResource:_resourceName] size:[_properties objectForKey:@"size"]]; diff --git a/AppKit/Cib/_CPCibKeyedUnarchiver.j b/AppKit/Cib/_CPCibKeyedUnarchiver.j index 1268f35d02..bd0fb31af0 100644 --- a/AppKit/Cib/_CPCibKeyedUnarchiver.j +++ b/AppKit/Cib/_CPCibKeyedUnarchiver.j @@ -5,15 +5,17 @@ @implementation _CPCibKeyedUnarchiver : CPKeyedUnarchiver { CPBundle _bundle; + BOOL _awakenCustomResources; } -- (id)initForReadingWithData:(CPData)data bundle:(CPBundle)aBundle +- (id)initForReadingWithData:(CPData)data bundle:(CPBundle)aBundle awakenCustomResources:(BOOL)shouldAwakenCustomResources { self = [super initForReadingWithData:data]; if (self) { _bundle = aBundle; + _awakenCustomResources = shouldAwakenCustomResources; [self setDelegate:self]; } @@ -26,6 +28,11 @@ return _bundle; } +- (BOOL)awakenCustomResources +{ + return _awakenCustomResources; +} + - (void)replaceObjectAtUID:(int)aUID withObject:(id)anObject { _objects[aUID] = anObject; diff --git a/Foundation/CPDictionary.j b/Foundation/CPDictionary.j index 62026ac137..48cbe59e5d 100755 --- a/Foundation/CPDictionary.j +++ b/Foundation/CPDictionary.j @@ -459,12 +459,14 @@ if (!aDictionary) return; - var allKeys = [aDictionary allKeys]; + var keys = [aDictionary allKeys], + count = [keys count]; - for (var i=0, count = [allKeys count]; i + diff --git a/Tools/objj/objj.js b/Tools/objj/objj.js index 1130121b13..c1bb61a255 100644 --- a/Tools/objj/objj.js +++ b/Tools/objj/objj.js @@ -31,18 +31,25 @@ try { if (args.length > 0) { + // Convert all arguments to JavaScript-style Strings. + var count = args.length; + + while (count--) + args[count] = String(args[count]); + + // Grab the location of the objj file to run. var mainFilePath = args.shift(); - + // convert from relative to absolute path if (this.Packages) - mainFilePath = (new Packages.java.io.File(mainFilePath)).getAbsolutePath(); + mainFilePath = String((new Packages.java.io.File(mainFilePath)).getAbsolutePath()); if (debug) print("Loading: " + mainFilePath); - objj_import(mainFilePath, YES); + objj_import(mainFilePath, YES); - serviceTimeouts(); + serviceTimeouts(); if (debug) print("Done!");