diff --git a/AppKit/CPPasteboard.j b/AppKit/CPPasteboard.j index 0e943dbaa..55dcad9a5 100644 --- a/AppKit/CPPasteboard.j +++ b/AppKit/CPPasteboard.j @@ -191,10 +191,12 @@ var CPPasteboards = nil, _owners = @{}; _provided = @{}; - var count = _types.length; - - while (count--) - [_owners setObject:anOwner forKey:_types[count]]; + if (anOwner) + { + var count = _types.length; + while (count--) + [_owners setObject:anOwner forKey:_types[count]]; + } if (_nativePasteboard && shouldUpdate) { @@ -205,6 +207,7 @@ var CPPasteboards = nil, _nativePasteboard.declareTypes_(nativeTypes); _changeCount = _nativePasteboard.changeCount(); } + return ++_changeCount; } diff --git a/AppKit/CPView.j b/AppKit/CPView.j index e597cb66a..e1aaaf325 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -2217,6 +2217,9 @@ setBoundsOrigin: var graphicsPort = CGBitmapGraphicsContextCreate(); #if PLATFORM(DOM) + var width = CGRectGetWidth(_frame), + height = CGRectGetHeight(_frame); + _DOMContentsElement = graphicsPort.DOMElement; _DOMContentsElement.style.zIndex = -100; @@ -2225,13 +2228,10 @@ setBoundsOrigin: _DOMContentsElement.style.position = "absolute"; _DOMContentsElement.style.visibility = "visible"; - _DOMContentsElement.width = ROUND(CGRectGetWidth(_frame)); - _DOMContentsElement.height = ROUND(CGRectGetHeight(_frame)); + CPDOMDisplayServerSetSize(_DOMContentsElement, width, height); - _DOMContentsElement.style.top = "0px"; - _DOMContentsElement.style.left = "0px"; - _DOMContentsElement.style.width = ROUND(CGRectGetWidth(_frame)) + "px"; - _DOMContentsElement.style.height = ROUND(CGRectGetHeight(_frame)) + "px"; + CPDOMDisplayServerSetStyleLeftTop(_DOMContentsElement, NULL, 0.0, 0.0); + CPDOMDisplayServerSetStyleSize(_DOMContentsElement, width, height); // The performance implications of this aren't clear, but without this subviews might not be redrawn when this // view moves. diff --git a/AppKit/Themes/Aristo2/Artwork/Aristo 11-06-07.psd b/AppKit/Themes/Aristo2/Artwork/Aristo 11-06-07.psd index ef95c237f..cc5464512 100755 Binary files a/AppKit/Themes/Aristo2/Artwork/Aristo 11-06-07.psd and b/AppKit/Themes/Aristo2/Artwork/Aristo 11-06-07.psd differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-center.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-center.png index d2db37444..39a0bb883 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-center.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-center.png differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-center.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-center.png index 44bafedc2..15d80d800 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-center.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-center.png differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-left.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-left.png index 2e4b4cffb..208848182 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-left.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-left.png differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-right.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-right.png index b45c2e146..6cd0f0838 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-right.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-disabled-right.png differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-center.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-center.png index 3bf8be6a2..7e8d49711 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-center.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-center.png differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-left.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-left.png index 75c5ee3d6..e51504da9 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-left.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-left.png differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-right.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-right.png index 5d71c7272..dc17dcd9e 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-right.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-focused-right.png differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-left.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-left.png index bdc11d31d..acc3a01f5 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-left.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-left.png differ diff --git a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-right.png b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-right.png index 52987fd2b..0f5244861 100644 Binary files a/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-right.png and b/AppKit/Themes/Aristo2/Resources/combobox-bezel-no-border-right.png differ diff --git a/AppKit/Themes/Aristo2/ThemeDescriptors.j b/AppKit/Themes/Aristo2/ThemeDescriptors.j index 384c61f57..050cb63d4 100644 --- a/AppKit/Themes/Aristo2/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo2/ThemeDescriptors.j @@ -745,7 +745,7 @@ var themedButtonValues = nil, [@"bezel-color-calendar", [CPColor whiteColor]], [@"bezel-color-calendar", [CPColor colorWithCalibratedRed:87.0 / 255.0 green:128.0 / 255.0 blue:216.0 / 255.0 alpha:1.0], CPThemeStateSelected], - [@"bezel-color-calendar", [CPColor colorWithCalibratedRed:87.0 / 255.0 green:128.0 / 255.0 blue:216.0 / 255.0 alpha:0.5], CPThemeStateSelected |CPThemeStateDisabled], + [@"bezel-color-calendar", [CPColor colorWithCalibratedRed:87.0 / 255.0 green:128.0 / 255.0 blue:216.0 / 255.0 alpha:0.5], CPThemeStateSelected | CPThemeStateDisabled], [@"bezel-color-clock", clockImageColor], [@"bezel-color-clock", clockImageColorDisabled, CPThemeStateDisabled], @@ -1008,10 +1008,19 @@ var themedButtonValues = nil, bezelNoBorderColor = PatternColor( "combobox-bezel-no-border{state}{position}.png", { - states: ["", "focused", "disabled"], - width: 6.0, - height: 29.0, - rightWidth: 24.0, + states: ["", "disabled"], + width: 4.0, + height: 25.0, + rightWidth: 25.0, + orientation: PatternIsHorizontal + }), + + bezelNoBorderFocusedColor = PatternColor( + "combobox-bezel-no-border-focused{position}.png", + { + width: 9.0, + height: 31.0, + rightWidth: 27.0, orientation: PatternIsHorizontal }), @@ -1022,16 +1031,20 @@ var themedButtonValues = nil, [@"bezel-color", bezelColor["disabled"], CPThemeStateBezeled | CPComboBoxStateButtonBordered | CPThemeStateDisabled], [@"bezel-color", bezelNoBorderColor["@"], CPThemeStateBezeled], - [@"bezel-color", bezelNoBorderColor["focused"], CPThemeStateBezeled | CPThemeStateEditing], + [@"bezel-color", bezelNoBorderFocusedColor, CPThemeStateBezeled | CPThemeStateEditing], [@"bezel-color", bezelNoBorderColor["disabled"], CPThemeStateBezeled | CPThemeStateDisabled], [@"border-inset", CGInsetMake(3.0, 3.0, 3.0, 3.0), CPThemeStateBezeled], - [@"bezel-inset", CGInsetMake(0.0, 1.0, 0.0, 1.0), CPThemeStateBezeled | CPThemeStateEditing], + [@"bezel-inset", CGInsetMake(0.0, 1.0, 0.0, 1.0), CPThemeStateBezeled | CPThemeStateEditing | CPComboBoxStateButtonBordered], + [@"bezel-inset", CGInsetMake(3.0, 4.0, 3.0, 4.0), CPThemeStateBezeled | CPThemeStateDisabled | CPComboBoxStateButtonBordered], + + [@"bezel-inset", CGInsetMake(0.0, 4.0, 0.0, 1.0), CPThemeStateBezeled | CPThemeStateEditing], + [@"bezel-inset", CGInsetMake(3.0, 5.0, 3.0, 4.0), CPThemeStateBezeled | CPThemeStateDisabled], // The right border inset has to make room for the focus ring and popup button [@"content-inset", CGInsetMake(9.0, 26.0, 7.0, 10.0), CPThemeStateBezeled | CPComboBoxStateButtonBordered], - [@"content-inset", CGInsetMake(9.0, 24.0, 7.0, 10.0), CPThemeStateBezeled], + [@"content-inset", CGInsetMake(9.0, 26.0, 7.0, 10.0), CPThemeStateBezeled], [@"content-inset", CGInsetMake(9.0, 24.0, 7.0, 10.0), CPThemeStateBezeled | CPThemeStateEditing], [@"popup-button-size", CGSizeMake(21.0, 23.0), CPThemeStateBezeled | CPComboBoxStateButtonBordered], diff --git a/AppKit/_CPPopUpList.j b/AppKit/_CPPopUpList.j index 67cfb7fb8..dc8a74227 100644 --- a/AppKit/_CPPopUpList.j +++ b/AppKit/_CPPopUpList.j @@ -858,7 +858,7 @@ var _CPPopUpListDataSourceKey = @"_CPPopUpListDataSourceKey", if (self = [super initWithContentRect:aContentRect styleMask:aStyleMask]) _constrainsToUsableScreen = NO; - [self _trapNextMouseDown]; + [self _trapNextMouseDown]; return self; } @@ -875,20 +875,20 @@ var _CPPopUpListDataSourceKey = @"_CPPopUpListDataSourceKey", - (void)orderFront:(id)sender { - [self _trapNextMouseDown]; - [super orderFront:sender]; + [self _trapNextMouseDown]; + [super orderFront:sender]; } - (void)_mouseWasClicked:(CPEvent)anEvent { - var mouseWindow = [anEvent window], - rect = [[[self delegate] dataSource] bounds], - point = [[[self delegate] dataSource] convertPoint:[anEvent locationInWindow] fromView:nil]; + var mouseWindow = [anEvent window], + rect = [[[self delegate] dataSource] bounds], + point = [[[self delegate] dataSource] convertPoint:[anEvent locationInWindow] fromView:nil]; - if (mouseWindow != self && !CGRectContainsPoint(rect, point)) - [[self delegate] close]; - else if ([mouseWindow firstResponder] == [[self delegate] dataSource]) - [self _trapNextMouseDown]; + if (mouseWindow != self && !CGRectContainsPoint(rect, point)) + [[self delegate] close]; + else if ([mouseWindow firstResponder] == [[self delegate] dataSource]) + [self _trapNextMouseDown]; } - (void)_trapNextMouseDown diff --git a/Foundation/CPLocale.j b/Foundation/CPLocale.j index 01945215c..219b5c690 100644 --- a/Foundation/CPLocale.j +++ b/Foundation/CPLocale.j @@ -23,47 +23,47 @@ @class CPDictionary -CPLocaleIdentifier = @"CPLocaleIdentifier"; -CPLocaleLanguageCode = @"CPLocaleLanguageCode"; -CPLocaleCountryCode = @"CPLocaleCountryCode"; -CPLocaleScriptCode = @"CPLocaleScriptCode"; -CPLocaleVariantCode = @"CPLocaleVariantCode"; -CPLocaleExemplarCharacterSet = @"CPLocaleExemplarCharacterSet"; -CPLocaleCalendar = @"CPLocaleCalendar"; -CPLocaleCollationIdentifier = @"CPLocaleCollationIdentifier"; -CPLocaleUsesMetricSystem = @"CPLocaleUsesMetricSystem"; -CPLocaleMeasurementSystem = @"CPLocaleMeasurementSystem"; -CPLocaleDecimalSeparator = @"CPLocaleDecimalSeparator"; -CPLocaleGroupingSeparator = @"CPLocaleGroupingSeparator"; -CPLocaleCurrencySymbol = @"CPLocaleCurrencySymbol"; -CPLocaleCurrencyCode = @"CPLocaleCurrencyCode"; -CPLocaleCollatorIdentifier = @"CPLocaleCollatorIdentifier"; -CPLocaleQuotationBeginDelimiterKey = @"CPLocaleQuotationBeginDelimiterKey"; -CPLocaleQuotationEndDelimiterKey = @"CPLocaleQuotationEndDelimiterKey"; +CPLocaleIdentifier = @"CPLocaleIdentifier"; +CPLocaleLanguageCode = @"CPLocaleLanguageCode"; +CPLocaleCountryCode = @"CPLocaleCountryCode"; +CPLocaleScriptCode = @"CPLocaleScriptCode"; +CPLocaleVariantCode = @"CPLocaleVariantCode"; +CPLocaleExemplarCharacterSet = @"CPLocaleExemplarCharacterSet"; +CPLocaleCalendar = @"CPLocaleCalendar"; +CPLocaleCollationIdentifier = @"CPLocaleCollationIdentifier"; +CPLocaleUsesMetricSystem = @"CPLocaleUsesMetricSystem"; +CPLocaleMeasurementSystem = @"CPLocaleMeasurementSystem"; +CPLocaleDecimalSeparator = @"CPLocaleDecimalSeparator"; +CPLocaleGroupingSeparator = @"CPLocaleGroupingSeparator"; +CPLocaleCurrencySymbol = @"CPLocaleCurrencySymbol"; +CPLocaleCurrencyCode = @"CPLocaleCurrencyCode"; +CPLocaleCollatorIdentifier = @"CPLocaleCollatorIdentifier"; +CPLocaleQuotationBeginDelimiterKey = @"CPLocaleQuotationBeginDelimiterKey"; +CPLocaleQuotationEndDelimiterKey = @"CPLocaleQuotationEndDelimiterKey"; CPLocaleAlternateQuotationBeginDelimiterKey = @"CPLocaleAlternateQuotationBeginDelimiterKey"; -CPLocaleAlternateQuotationEndDelimiterKey = @"CPLocaleAlternateQuotationEndDelimiterKey"; +CPLocaleAlternateQuotationEndDelimiterKey = @"CPLocaleAlternateQuotationEndDelimiterKey"; -CPGregorianCalendar = @"CPGregorianCalendar"; -CPBuddhistCalendar = @"CPBuddhistCalendar"; -CPChineseCalendar = @"CPChineseCalendar"; -CPHebrewCalendar = @"CPHebrewCalendar"; -CPIslamicCalendar = @"CPIslamicCalendar"; -CPIslamicCivilCalendar = @"CPIslamicCivilCalendar"; -CPJapaneseCalendar = @"CPJapaneseCalendar"; -CPRepublicOfChinaCalendar = @"CPRepublicOfChinaCalendar"; -CPPersianCalendar = @"CPPersianCalendar"; -CPIndianCalendar = @"CPIndianCalendar"; -CPISO8601Calendar = @"CPISO8601Calendar"; +CPGregorianCalendar = @"CPGregorianCalendar"; +CPBuddhistCalendar = @"CPBuddhistCalendar"; +CPChineseCalendar = @"CPChineseCalendar"; +CPHebrewCalendar = @"CPHebrewCalendar"; +CPIslamicCalendar = @"CPIslamicCalendar"; +CPIslamicCivilCalendar = @"CPIslamicCivilCalendar"; +CPJapaneseCalendar = @"CPJapaneseCalendar"; +CPRepublicOfChinaCalendar = @"CPRepublicOfChinaCalendar"; +CPPersianCalendar = @"CPPersianCalendar"; +CPIndianCalendar = @"CPIndianCalendar"; +CPISO8601Calendar = @"CPISO8601Calendar"; -CPLocaleLanguageDirectionUnknown = @"CPLocaleLanguageDirectionUnknown"; -CPLocaleLanguageDirectionLeftToRight = @"CPLocaleLanguageDirectionLeftToRight"; -CPLocaleLanguageDirectionRightToLeft = @"CPLocaleLanguageDirectionRightToLeft"; -CPLocaleLanguageDirectionTopToBottom = @"CPLocaleLanguageDirectionTopToBottom"; -CPLocaleLanguageDirectionBottomToTop = @"CPLocaleLanguageDirectionBottomToTop"; +CPLocaleLanguageDirectionUnknown = @"CPLocaleLanguageDirectionUnknown"; +CPLocaleLanguageDirectionLeftToRight = @"CPLocaleLanguageDirectionLeftToRight"; +CPLocaleLanguageDirectionRightToLeft = @"CPLocaleLanguageDirectionRightToLeft"; +CPLocaleLanguageDirectionTopToBottom = @"CPLocaleLanguageDirectionTopToBottom"; +CPLocaleLanguageDirectionBottomToTop = @"CPLocaleLanguageDirectionBottomToTop"; var countryCodes = [@"DE", @"FR", @"ES", @"GB", @"US"], languageCodes = [@"en", @"de", @"es", @"fr"], - availableLocaleIdentifiers = [@"de_DE", @"en_EN", @"en_US", @"es_ES", @"fr_FR"]; + availableLocaleIdentifiers = [@"de_DE", @"en_GB", @"en_US", @"es_ES", @"fr_FR"]; var sharedSystemLocale = nil, sharedCurrentLocale = nil; @@ -83,35 +83,36 @@ var sharedSystemLocale = nil, return sharedSystemLocale; } -/*! Return the current locale base on the navigator +/*! Return the current locale based on the navigator string. */ + (id)currentLocale { if (!sharedCurrentLocale) { - var localeIdentifier, + var localeIdentifier = @"en_US", language; - if (typeof navigator != "undefined") + if (typeof navigator !== "undefined") { - if (navigator.appVersion.indexOf("MSIE") >= 0) - language = navigator.browserLanguage.substring(0,2); - else - language = navigator.language.substring(0,2); + // userLanguage is an IE only property. + language = (typeof navigator.language !== "undefined") ? navigator.language : navigator.userLanguage; - language = [CPString stringWithFormat:@"%s_%s", [language lowercaseString], [language uppercaseString]]; + if (language) + { + // Browsers use locale strings such as "en-US", but CPLocale uses "en_US". + language = language.replace("-", "_").substring(0, 5); + // Some browsers have "en_us" at this point, while we want "en_US". + language = language.substring(0, 3).toLowerCase() + language.substring(3, 5).toUpperCase(); - if ([availableLocaleIdentifiers indexOfObject:language]) - localeIdentifier = language; + if ([availableLocaleIdentifiers indexOfObject:language] !== CPNotFound) + localeIdentifier = language; + } } - if (!localeIdentifier) - localeIdentifier = @"en_US"; - sharedCurrentLocale = [[CPLocale alloc] initWithLocaleIdentifier:localeIdentifier]; } - return sharedCurrentLocale + return sharedCurrentLocale; } /*! Return an array of the availableLocaleIdentifiers @@ -155,25 +156,25 @@ var sharedSystemLocale = nil, { if (self == [super init]) { - var parts = [anIdentifier componentsSeparatedByString:@"_"], - language = [parts objectAtIndex:0], - country = nil; + var parts = [anIdentifier componentsSeparatedByString:@"_"], + language = [parts objectAtIndex:0], + country = nil; if ([parts count] > 1) - country = [parts objectAtIndex:1]; + country = [parts objectAtIndex:1]; else - country = anIdentifier; + country = anIdentifier; _locale = [[CPDictionary alloc] init]; [_locale setObject:anIdentifier forKey:CPLocaleIdentifier]; [_locale setObject:language forKey:CPLocaleLanguageCode]; [_locale setObject:country forKey:CPLocaleCountryCode]; - if([[self class] respondsToSelector:@selector(_platformLocaleAdditionalDescriptionForIdentifier:)]) + if ([[self class] respondsToSelector:@selector(_platformLocaleAdditionalDescriptionForIdentifier:)]) { - // Use any platform specific method to fill the locale info if one is defined - var info = [[self class] performSelector:@selector(_platformLocaleAdditionalDescriptionForIdentifier:) withObject:anIdentifier]; - [_locale addEntriesFromDictionary:info]; + // Use any platform specific method to fill the locale info if one is defined + var info = [[self class] performSelector:@selector(_platformLocaleAdditionalDescriptionForIdentifier:) withObject:anIdentifier]; + [_locale addEntriesFromDictionary:info]; } else { diff --git a/Foundation/CPPredicate/CPComparisonPredicate.j b/Foundation/CPPredicate/CPComparisonPredicate.j index ffe374e7a..a7843308e 100644 --- a/Foundation/CPPredicate/CPComparisonPredicate.j +++ b/Foundation/CPPredicate/CPComparisonPredicate.j @@ -275,7 +275,7 @@ var CPComparisonPredicateModifier, if (self === anObject) return YES; - if (anObject.isa !== self.isa || _modifier !== [anObject comparisonPredicateModifier] || _type !== [anObject predicateOperatorType] || _options !== [anObject options] || _customSelector !== [anObject customSelector] || ![_left isEqual:[anObject leftExpression]] || ![_right isEqual:[anObject rightExpression]]) + if (anObject === nil || anObject.isa !== self.isa || _modifier !== [anObject comparisonPredicateModifier] || _type !== [anObject predicateOperatorType] || _options !== [anObject options] || _customSelector !== [anObject customSelector] || ![_left isEqual:[anObject leftExpression]] || ![_right isEqual:[anObject rightExpression]]) return NO; return YES; diff --git a/Foundation/CPPredicate/CPCompoundPredicate.j b/Foundation/CPPredicate/CPCompoundPredicate.j index 8eaeb709f..e36ceb0d0 100644 --- a/Foundation/CPPredicate/CPCompoundPredicate.j +++ b/Foundation/CPPredicate/CPCompoundPredicate.j @@ -215,7 +215,7 @@ var CPCompoundPredicateType; if (self === anObject) return YES; - if (anObject.isa !== self.isa || _type !== [anObject compoundPredicateType] || ![_predicates isEqualToArray:[anObject subpredicates]]) + if (anObject === nil || anObject.isa !== self.isa || _type !== [anObject compoundPredicateType] || ![_predicates isEqualToArray:[anObject subpredicates]]) return NO; return YES; diff --git a/Foundation/CPPredicate/_CPAggregateExpression.j b/Foundation/CPPredicate/_CPAggregateExpression.j index b010881a7..688166398 100644 --- a/Foundation/CPPredicate/_CPAggregateExpression.j +++ b/Foundation/CPPredicate/_CPAggregateExpression.j @@ -42,7 +42,7 @@ if (self === object) return YES; - if (object.isa !== self.isa || ![[object collection] isEqual:_aggregate]) + if (object === nil || object.isa !== self.isa || ![[object collection] isEqual:_aggregate]) return NO; return YES; diff --git a/Foundation/CPPredicate/_CPConstantValueExpression.j b/Foundation/CPPredicate/_CPConstantValueExpression.j index 5ffa9e07a..617c9b10a 100644 --- a/Foundation/CPPredicate/_CPConstantValueExpression.j +++ b/Foundation/CPPredicate/_CPConstantValueExpression.j @@ -45,7 +45,7 @@ if (self === object) return YES; - if (object.isa !== self.isa || ![[object constantValue] isEqual:_value]) + if (object === nil || object.isa !== self.isa || ![[object constantValue] isEqual:_value]) return NO; return YES; diff --git a/Foundation/CPPredicate/_CPFunctionExpression.j b/Foundation/CPPredicate/_CPFunctionExpression.j index 75b1619fc..394c93612 100644 --- a/Foundation/CPPredicate/_CPFunctionExpression.j +++ b/Foundation/CPPredicate/_CPFunctionExpression.j @@ -72,7 +72,7 @@ if (self === object) return YES; - if (object.isa !== self.isa || ![[object _function] isEqual:_selector] || ![[object operand] isEqual:_operand] || ![[object arguments] isEqualToArray:_arguments]) + if (object === nil || object.isa !== self.isa || ![[object _function] isEqual:_selector] || ![[object operand] isEqual:_operand] || ![[object arguments] isEqualToArray:_arguments]) return NO; return YES; diff --git a/Foundation/CPPredicate/_CPKeyPathExpression.j b/Foundation/CPPredicate/_CPKeyPathExpression.j index c0694b395..0f9ece8b6 100644 --- a/Foundation/CPPredicate/_CPKeyPathExpression.j +++ b/Foundation/CPPredicate/_CPKeyPathExpression.j @@ -51,7 +51,7 @@ if (object === self) return YES; - if (object.isa !== self.isa || ![[object keyPath] isEqualToString:[self keyPath]]) + if (object === nil || object.isa !== self.isa || ![[object keyPath] isEqualToString:[self keyPath]]) return NO; return YES; diff --git a/Foundation/CPPredicate/_CPPredicate.j b/Foundation/CPPredicate/_CPPredicate.j index d2d8544db..367b65f48 100644 --- a/Foundation/CPPredicate/_CPPredicate.j +++ b/Foundation/CPPredicate/_CPPredicate.j @@ -190,7 +190,7 @@ if (self === anObject) return YES; - if (self.isa !== anObject.isa || _value !== [anObject evaluateWithObject:nil]) + if (anObject === nil || self.isa !== anObject.isa || _value !== [anObject evaluateWithObject:nil]) return NO; return YES; diff --git a/Foundation/CPPredicate/_CPSetExpression.j b/Foundation/CPPredicate/_CPSetExpression.j index f7d4e673b..a0e9df3bb 100644 --- a/Foundation/CPPredicate/_CPSetExpression.j +++ b/Foundation/CPPredicate/_CPSetExpression.j @@ -47,7 +47,7 @@ if (self === object) return YES; - if (object.isa !== self.isa || ![[object leftExpression] isEqual:_left] || ![[object rightExpression] isEqual:_right]) + if (object === nil || object.isa !== self.isa || ![[object leftExpression] isEqual:_left] || ![[object rightExpression] isEqual:_right]) return NO; return YES; diff --git a/Foundation/CPPredicate/_CPSubqueryExpression.j b/Foundation/CPPredicate/_CPSubqueryExpression.j index 78b50be94..a94d88d2c 100644 --- a/Foundation/CPPredicate/_CPSubqueryExpression.j +++ b/Foundation/CPPredicate/_CPSubqueryExpression.j @@ -73,7 +73,7 @@ if (self === object) return YES; - if (object.isa !== self.isa || ![_collection isEqual:[object collection]] || ![_variableExpression isEqual:[object variableExpression]] || ![_subpredicate isEqual:[object predicate]]) + if (object === nil || object.isa !== self.isa || ![_collection isEqual:[object collection]] || ![_variableExpression isEqual:[object variableExpression]] || ![_subpredicate isEqual:[object predicate]]) return NO; return YES; diff --git a/Foundation/CPPredicate/_CPVariableExpression.j b/Foundation/CPPredicate/_CPVariableExpression.j index c426d6c60..910ef23d5 100644 --- a/Foundation/CPPredicate/_CPVariableExpression.j +++ b/Foundation/CPPredicate/_CPVariableExpression.j @@ -48,7 +48,7 @@ if (self === object) return YES; - if (object.isa !== self.isa || ![[object variable] isEqual:_variable]) + if (object === nil || object.isa !== self.isa || ![[object variable] isEqual:_variable]) return NO; return YES; diff --git a/Tests/AppKit/CPPasteboardTest.j b/Tests/AppKit/CPPasteboardTest.j new file mode 100644 index 000000000..eca98ee14 --- /dev/null +++ b/Tests/AppKit/CPPasteboardTest.j @@ -0,0 +1,17 @@ +@import + +@import + +@implementation CPPasteboardTest : OJTestCase +{ +} + +- (void)testSetString_forType_ +{ + var pboard = [CPPasteboard generalPasteboard]; + [pboard declareTypes:@[CPStringPboardType] owner:nil]; + [pboard setString:@"hello" forType:CPStringPboardType]; + [self assert:@"hello" equals:[pboard stringForType:CPStringPboardType]]; +} + +@end diff --git a/Tests/Foundation/CPObjectTest.j b/Tests/Foundation/CPObjectTest.j index 926a00238..c10293124 100644 --- a/Tests/Foundation/CPObjectTest.j +++ b/Tests/Foundation/CPObjectTest.j @@ -59,6 +59,13 @@ [self assertTrue:d.indexOf("access:") !== -1 message:"Can't find 'access:' in description of json " + d]; } +- (void)testCPObjectNotEqualToNil +{ + var anObject = [[CPObject alloc] init]; + + [self assert:anObject notEqual:nil]; +} + @end @implementation SuperReceiver : CPObject diff --git a/Tests/Foundation/CPPredicateTest.j b/Tests/Foundation/CPPredicateTest.j index 58d6066ae..114f440e9 100644 --- a/Tests/Foundation/CPPredicateTest.j +++ b/Tests/Foundation/CPPredicateTest.j @@ -9,6 +9,7 @@ - (id)init { self = [super init]; + if (self != nil) { var d, @@ -117,18 +118,18 @@ - (void)testVariableExpressionEvaluation { -// Replace with constant + // Replace with constant var expression = [CPExpression expressionForVariable:@"variable"], bindings = [CPDictionary dictionaryWithObject:20 forKey:@"variable"], eval = [expression expressionValueWithObject:@"variable" context:bindings]; [self assertTrue:(eval == 20) message:"'" + eval + "' should be 20"]; -// Replace with constant expression + // Replace with constant expression bindings = [CPDictionary dictionaryWithObject:[CPExpression expressionForConstantValue:10] forKey:@"variable"]; eval = [expression expressionValueWithObject:nil context:bindings]; [self assertTrue:(eval == 10) message:"'" + eval + "' should be 10"]; -// Replace with keypath expression + // Replace with keypath expression bindings = [CPDictionary dictionaryWithObject:[CPExpression expressionForKeyPath:@"Record1.Age"] forKey:@"variable"]; eval = [expression expressionValueWithObject:dict context:bindings]; [self assertTrue:(eval == 34) message:"'" + eval + "' should be 34"]; @@ -213,7 +214,7 @@ - (void)testNilComparisons { -// Custom Selector Predicate + // Custom Selector Predicate var pred = [[CPComparisonPredicate alloc] initWithLeftExpression:[CPExpression expressionForKeyPath:@"Record1.Name"] rightExpression:[CPExpression expressionForConstantValue:nil] customSelector:@selector(yes:)]; [self assertTrue:[pred evaluateWithObject:dict] message:"'" + [pred description] + "' should be true"]; @@ -226,7 +227,7 @@ [self assertFalse:[pred evaluateWithObject:dict] message:"'" + [pred description] + "' should be false"]; -// Predicates with operators + // Predicates with operators pred = [[CPComparisonPredicate alloc] initWithLeftExpression:[CPExpression expressionForKeyPath:@"Record1.Age"] rightExpression:[CPExpression expressionForConstantValue:nil] modifier:CPDirectPredicateModifier type:CPGreaterThanPredicateOperatorType options:0]; [self assertFalse:[pred evaluateWithObject:dict] message:"'" + [pred description] + "' should be false"]; @@ -243,7 +244,7 @@ - (void)testPredicateParsing { var predicate; -// TEST String + // TEST String predicate = [CPPredicate predicateWithFormat: @"%K == %@", @"Record1.Name", @"John"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; @@ -256,14 +257,14 @@ predicate = [CPPredicate predicateWithFormat: @"(%K == %@) AND (%K == %@)", @"Record1.Name", @"John", @"Record2.Name", @"Mary"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; -// TEST integer + // TEST integer predicate = [CPPredicate predicateWithFormat: @"%K == %d", @"Record1.Age", 34]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; predicate = [CPPredicate predicateWithFormat: @"%K < %d", @"Record1.Age", 40]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; - predicate = [CPPredicate predicateWithFormat: @"%K BETWEEN %@", @"Record1.Age", [CPArray arrayWithObjects:[CPNumber numberWithInt:20], [CPNumber numberWithInt:40]]]; + predicate = [CPPredicate predicateWithFormat: @"%K BETWEEN %@", @"Record1.Age", @[20, 40]]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; predicate = [CPPredicate predicateWithFormat: @"Record1.Age BETWEEN {%f,%f}", 20, 40]; @@ -272,14 +273,14 @@ predicate = [CPPredicate predicateWithFormat: @"(%K == %d) OR (%K == %d)", @"Record1.Age", 34, @"Record2.Age", 34]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; -// TEST float + // TEST float predicate = [CPPredicate predicateWithFormat: @"%K < %f", @"Record1.Age", 40.5]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; predicate = [CPPredicate predicateWithFormat: @"%f > %K", 40.5, @"Record1.Age"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; -// TEST KeyPath + // TEST KeyPath predicate = [CPPredicate predicateWithFormat: @"%@ IN %K", @"Kid1", @"Record1.Children"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; @@ -289,11 +290,11 @@ predicate = [CPPredicate predicateWithFormat: @"ANY %K == %@", @"Record2.Children", @"Girl1"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; -// Test Aggregate + // Test Aggregate predicate = [CPPredicate predicateWithFormat:@"{Record1.Name, Record1.Age} = {'John',34}"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; -// Test Symbolic token + // Test Symbolic token predicate = [CPPredicate predicateWithFormat:@"Record1.Children[ FIRST ] = 'Kid1'"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; @@ -303,7 +304,7 @@ predicate = [CPPredicate predicateWithFormat:@"Record1.Children[count:(Record1.Children) - 1] = 'Kid2'"]; [self assertTrue:[predicate evaluateWithObject:dict] message:[predicate description] + " should be true"]; -// Test arithm + // Test arithm var n = 2; predicate = [CPPredicate predicateWithFormat:@"SELF +1 = 3"]; [self assertTrue:[predicate evaluateWithObject:n] message:[predicate description] + " should be true"]; @@ -323,22 +324,22 @@ predicate = [CPPredicate predicateWithFormat:@"SELF** 3 = 8"]; [self assertTrue:[predicate evaluateWithObject:n] message:[predicate description] + " should be true"]; -// TEST Operator type + // TEST Operator type predicate = [CPPredicate predicateWithFormat: @"a CONTAINS[c] \"b\""]; [self assertTrue:([predicate predicateOperatorType] == CPContainsPredicateOperatorType) message:[predicate description] + " operator should be a CPContainsPredicateOperatorType"]; predicate = [CPPredicate predicateWithFormat: @"a BETWEEN {%f,%f}", 20, 40]; [self assertTrue:([predicate predicateOperatorType] == CPBetweenPredicateOperatorType) message:[predicate description] + " operator should be a CPBetweenPredicateOperatorType"]; -// TEST Empty string + // TEST Empty string predicate = [CPPredicate predicateWithFormat: @"a CONTAINS \"\""]; [self assertNotNull:predicate message:[predicate description] + " should not be nil"]; -// TEST variable + // TEST variable predicate = [CPPredicate predicateWithFormat: @"$x CONTAINS \"\""]; [self assertTrue:[[predicate leftExpression] expressionType] == CPVariableExpressionType message:"Left Expression should be a CPVariableExpressionType"]; -// TEST variable inside keypath + // TEST variable inside keypath predicate = [CPPredicate predicateWithFormat: @"Record1.$age = 34"]; var bindings = [CPDictionary dictionaryWithObject:@"Age" forKey:@"age"]; [self assertTrue:[predicate evaluateWithObject:dict substitutionVariables:bindings] message:"Predicate " + predicate + " should evaluate to TRUE"]; @@ -350,14 +351,14 @@ predicate = [CPPredicate predicateWithFormat: @"$record.$age = 34"]; [self assertTrue:[predicate evaluateWithObject:dict substitutionVariables:bindings] message:"Predicate " + predicate + " should evaluate to TRUE"]; -// TEST built-in functions + // TEST built-in functions predicate = [CPPredicate predicateWithFormat: @"sum:(1,1) = 2"]; [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should evaluate to TRUE"]; predicate = [CPPredicate predicateWithFormat: @"multiply:by:(5,3) = 15"]; [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should evaluate to TRUE"]; -// TEST custom functions + // TEST custom functions predicate = [CPPredicate predicateWithFormat:@"FUNCTION('a/path', 'lastPathComponent') = 'path'"]; [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should evaluate to TRUE"]; @@ -367,13 +368,13 @@ predicate = [CPPredicate predicateWithFormat:@"FUNCTION('toto', 'stringByReplacingOccurrencesOfString:withString:', 'o', 'a') == 'tata'"]; [self assertTrue:[predicate evaluateWithObject:nil] message:"Predicate " + predicate + " should be TRUE"]; -// TEST Subquery -- This means: search people who have 2 boys. + // TEST Subquery -- This means: search people who have 2 boys. predicate = [CPPredicate predicateWithFormat: @"SUBQUERY(Record1.Children, $x, $x BEGINSWITH 'Kid')[SIZE] = 2"]; [self assertTrue:[predicate evaluateWithObject:dict] message:"Predicate " + predicate + " should evaluate to TRUE"]; -// Test Set expressions -// Parsing is ok but the evaluation of this predicate will return NO because: -// - lhs will evaluate to a CPSet and rhs to a CPArray (aggregate exp). Comparing sets against arrays will always fail in CPComparisonPredicate. This is also cocoa behavior but i guess it's for historical reasons (set expressions are 10.5+) and should be changed in capp in my opinion. + // Test Set expressions + // Parsing is ok but the evaluation of this predicate will return NO because: + // - lhs will evaluate to a CPSet and rhs to a CPArray (aggregate exp). Comparing sets against arrays will always fail in CPComparisonPredicate. This is also cocoa behavior but i guess it's for historical reasons (set expressions are 10.5+) and should be changed in capp in my opinion. var object = [CPDictionary dictionaryWithObject:[CPSet setWithObjects:@"a"] forKey:"a"], result = [CPSet setWithObjects:@"a",@"b"]; @@ -400,8 +401,8 @@ exp2 = [CPExpression expressionForVariable:"toto"]; [self assert:exp1 equals:exp2]; - var left = [CPExpression expressionForConstantValue:[CPSet setWithObjects:@"a",@"b",@"c"]], - right = [CPExpression expressionForConstantValue:[CPArray arrayWithObjects:@"a",@"b",@"d"]]; + var left = [CPExpression expressionForConstantValue:[CPSet setWithObjects:@"a", @"b", @"c"]], + right = [CPExpression expressionForConstantValue:[CPArray arrayWithObjects:@"a", @"b", @"d"]]; exp1 = [CPExpression expressionForIntersectSet:left with:right]; exp2 = [CPExpression expressionForIntersectSet:[left copy] with:[right copy]]; @@ -440,6 +441,64 @@ [self assert:pred1 equals:pred2]; } +- (void)testExpressionAndPredicateIsNotEqualToNil +{ + var cexp1 = [CPExpression expressionForConstantValue:2], + cexp2 = [CPExpression expressionForConstantValue:2]; + [self assert:cexp1 notEqual:nil]; + + var exp1 = [CPExpression expressionForKeyPath:"path"]; + + [self assert:exp1 notEqual:nil]; + + exp1 = [CPExpression expressionForEvaluatedObject]; + + [self assert:exp1 notEqual:nil]; + + exp1 = [CPExpression expressionForVariable:"toto"]; + + [self assert:exp1 notEqual:nil]; + + var left = [CPExpression expressionForConstantValue:[CPSet setWithObjects:@"a",@"b",@"c"]], + right = [CPExpression expressionForConstantValue:[CPArray arrayWithObjects:@"a",@"b",@"d"]]; + + exp1 = [CPExpression expressionForIntersectSet:left with:right]; + + [self assert:exp1 notEqual:nil]; + + exp1 = [CPExpression expressionForFunction:cexp1 selectorName:@"isEqual:" arguments:[CPArray arrayWithObjects:cexp2]]; + + [self assert:exp1 notEqual:nil]; + + var aexp1 = [CPExpression expressionForAggregate:[CPArray arrayWithObjects:cexp1,cexp2]]; + + [self assert:aexp1 notEqual:nil]; + + exp1 = [CPExpression expressionForSubquery:right usingIteratorVariable:@"self" predicate:[CPPredicate predicateWithValue:YES]]; + + [self assert:exp1 notEqual:nil]; + + var pred1 = [CPPredicate predicateWithFormat:@"FUNCTION('toto', 'stringByReplacingOccurrencesOfString:withString:', 'o', 'a') == 'tata'"]; + + [self assert:pred1 notEqual:nil]; + + pred1 = [CPPredicate predicateWithFormat:@"$record.$age = 34"]; + + [self assert:pred1 notEqual:nil]; + + pred1 = [CPPredicate predicateWithFormat:@"SUBQUERY(Record1.Children, $x, $x BEGINSWITH 'Kid')[SIZE] = 2"]; + + [self assert:pred1 notEqual:nil]; + + pred1 = [CPPredicate predicateWithFormat:@"$x CONTAINS 'a'"]; + + [self assert:pred1 notEqual:nil]; + + pred1 = [CPPredicate predicateWithFormat:@"a = 'a' AND b = 'b'"]; + + [self assert:pred1 notEqual:nil]; +} + - (void)testProxyArrayFiltering { var proxyArray = [self mutableArrayValueForKey:@"simpleArray"], @@ -455,8 +514,8 @@ var data = [1, 2, 3], result; - var tpred = [CPPredicate predicateWithFormat:@"TRUEPREDICATE"]; - var ctpred = [CPCompoundPredicate andPredicateWithSubpredicates:[tpred]]; + var tpred = [CPPredicate predicateWithFormat:@"TRUEPREDICATE"], + ctpred = [CPCompoundPredicate andPredicateWithSubpredicates:[tpred]]; // fails if evaluateWithObject: isn't implemented in CPPredicate_BOOL result = [tpred evaluateWithObject:"gazonk"]; diff --git a/Tools/nib2cib/Nib2CibKeyedUnarchiver.j b/Tools/nib2cib/Nib2CibKeyedUnarchiver.j index c12cbcc7b..164b188c1 100644 --- a/Tools/nib2cib/Nib2CibKeyedUnarchiver.j +++ b/Tools/nib2cib/Nib2CibKeyedUnarchiver.j @@ -52,7 +52,10 @@ var FILE = require("file"); else if (!info.resourceDirectory) [CPException raise:Nib2CibException format:@"The framework “%@” specified by the image “%@@%@” has no Resources directory.", framework, aName, framework]; - return { path:[self _resourcePathForName:aName inDirectory:info.resourceDirectory], framework:framework }; + var path = [self _resourcePathForName:aName inDirectory:info.resourceDirectory]; + + if (path) + return { path:path, framework:framework }; } else { @@ -79,7 +82,7 @@ var FILE = require("file"); } } - return nil; + [CPException raise:Nib2CibException format:@"The image “%@” cannot be found.", aName]; } - (CPString)_resourcePathForName:(CPString)aName inDirectory:(CPString)directory @@ -107,7 +110,7 @@ var FILE = require("file"); } } - [CPException raise:Nib2CibException format:@"The image “%@” cannot be found in %@.", aName, directory]; + return nil; } @end