Merge branch 'master' into Localization

This commit is contained in:
Alexandre Wilhelm committed 2015-08-27 15:16:12 -07:00
commit bb9408b5d0
326 files changed
+13070 -10224

No files matched your search

+3 -1
View File
@@ -26,6 +26,7 @@
@import "CPAccordionView.j"
@import "CPAlert.j"
@import "CPAnimation.j"
@import "CPAppearance.j"
@import "CPApplication.j"
@import "CPArrayController.j"
@import "CPBezierPath.j"
@@ -106,7 +107,8 @@
@import "CPView.j"
@import "CPViewAnimation.j"
@import "CPViewController.j"
@import "CPVisualEffectView.j"
@import "CPWebView.j"
@import "CPWindow.j"
@import "CPWindowController.j"
@import "CPWorkspace.j"
@import "CPWorkspace.j"
+162
View File
@@ -0,0 +1,162 @@
/*
* CPAppearance.j
* AppKit
*
* Created by Antoine Mercadal.
* Copyright 2015, Cappuccino Project.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/Foundation.j>
@import "CPTheme.j"
CPAppearanceNameAqua = @"CPAppearanceNameAqua";
CPAppearanceNameLightContent = @"CPAppearanceNameLightContent";
CPAppearanceNameVibrantDark = @"CPAppearanceNameVibrantDark";
CPAppearanceNameVibrantLight = @"CPAppearanceNameVibrantLight";
var _CPAppearanceCurrent = nil,
_CPAppearancesRegistry = @{};
@protocol CPAppearanceCustomization <CPObject>
@required
- (CPAppearance)appearance;
- (void)setAppearance:(CPAppearance)appearance;
- (CPAppearance)effectiveAppearance;
- (void)setEffectiveAppearance:(CPAppearance)appearance;
@end
CPThemeStateAppearanceAqua = CPThemeState("appearance-aqua");
CPThemeStateAppearanceLightContent = CPThemeState("appearance-light-content");
CPThemeStateAppearanceVibrantLight = CPThemeState("appearance-vibrant-light");
CPThemeStateAppearanceVibrantDark = CPThemeState("appearance-vibrant-dark");
/*!
@ingroup appkit
A CPAppareance represents the appearance of an to a subset of UI elements.
This is a very lightweight implementation of the NSAppearance system, but
We are using it for compliance, and especially for the CPVisualEffectView
*/
@implementation CPAppearance : CPObject
{
BOOL _allowsVibrancy @accessors(property=allowsVibrancy);
CPString _name;
}
#pragma mark -
#pragma mark Class Methods
/*! Returns the current default CPAppearance
*/
+ (CPAppearance)currentAppearance
{
if (!_CPAppearanceCurrent)
_CPAppearanceCurrent = [CPAppearance appearanceNamed:CPAppearanceNameAqua];
return _CPAppearanceCurrent;
}
/*! Sets the current default CPAppearance
@param appearance the new current appearance
*/
+ (void)setCurrentAppearance:(CPAppearance)anAppearance
{
_CPAppearanceCurrent = anAppearance;
}
/*! Returns the CPAppearance object with the given name
@param name the name of the appearance
*/
+ (CPAppearance)appearanceNamed:(CPString)aName
{
if (![_CPAppearancesRegistry containsKey:aName])
{
[_CPAppearancesRegistry setObject:[[CPAppearance alloc] initWithAppearanceNamed:aName bundle:nil]
forKey:aName];
}
return [_CPAppearancesRegistry objectForKey:aName];
}
#pragma mark -
#pragma mark Initialization
/*! Creates a CPAppearance object initialized to the specified appearance file in the specified bundle
This method does actually nothing special. It just creates a default appearance object
*/
- (id)initWithAppearanceNamed:(CPString)aName bundle:(CPBundle)bundle
{
if (self = [super init])
{
_name = aName;
_allowsVibrancy = YES;
if ([_CPAppearancesRegistry containsKey:aName])
[CPException raise:CPInternalInconsistencyException reason:"Appearance with name '" + aName + "' is already declared."];
[_CPAppearancesRegistry setObject:self forKey:aName];
}
return self;
}
#pragma mark -
#pragma mark Implementation
- (BOOL)isEqual:(id)anObject
{
if (![anObject isKindOfClass:CPAppearance])
return NO;
return self._name == anObject._name;
}
- (CPString)description
{
return @"<CPAppearance @" + [self UID] + @" name: " + _name + ">";
}
#pragma mark -
#pragma mark CPCoding
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super init])
{
_name = [aCoder decodeObjectForKey:@"_name"];
_allowsVibrancy = [aCoder decodeBoolForKey:@"_allowsVibrancy"];
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[aCoder encodeObject:_name forKey:@"_name"];
[aCoder encodeBool:_allowsVibrancy forKey:@"_allowsVibrancy"];
}
@end
+32 -6
View File
@@ -47,6 +47,8 @@ var CPMainCibFile = @"CPMainCibFile",
@protocol CPApplicationDelegate <CPObject>
@optional
- (CPApplicationTerminateReply)applicationShouldTerminate:(CPApplication)sender;
- (CPString)applicationShouldTerminateMessage:(CPApplication)sender;
- (void)applicationDidBecomeActive:(CPNotification)aNotification;
- (void)applicationDidChangeScreenParameters:(CPNotification)aNotification;
- (void)applicationDidFinishLaunching:(CPNotification)aNotification;
@@ -58,6 +60,9 @@ var CPMainCibFile = @"CPMainCibFile",
@end
var CPApplicationDelegate_applicationShouldTerminate_ = 1 << 0,
CPApplicationDelegate_applicationShouldTerminateMessage_ = 1 << 1;
/*!
@ingroup appkit
@class CPApplication
@@ -103,6 +108,8 @@ var CPMainCibFile = @"CPMainCibFile",
//
id <CPApplicationDelegate> _delegate;
CPInteger _implementedDelegateMethods;
BOOL _finishedLaunching;
BOOL _isActive;
@@ -165,6 +172,8 @@ var CPMainCibFile = @"CPMainCibFile",
if (_delegate == aDelegate)
return;
_implementedDelegateMethods = 0;
var defaultCenter = [CPNotificationCenter defaultCenter],
delegateNotifications =
[
@@ -205,6 +214,12 @@ var CPMainCibFile = @"CPMainCibFile",
if ([_delegate respondsToSelector:selector])
[defaultCenter addObserver:_delegate selector:selector name:notificationName object:self];
}
if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)])
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminate_
if ([_delegate respondsToSelector:@selector(applicationShouldTerminateMessage:)])
_implementedDelegateMethods |= CPApplicationDelegate_applicationShouldTerminateMessage_
}
/*!
@@ -426,12 +441,7 @@ var CPMainCibFile = @"CPMainCibFile",
{
// callback method for terminate:
if (didCloseAll)
{
if ([_delegate respondsToSelector:@selector(applicationShouldTerminate:)])
[self replyToApplicationShouldTerminate:[_delegate applicationShouldTerminate:self]];
else
[self replyToApplicationShouldTerminate:YES];
}
[self replyToApplicationShouldTerminate:[self _sendDelegateApplicationShouldTerminate]];
}
- (void)replyToApplicationShouldTerminate:(BOOL)terminate
@@ -1210,6 +1220,22 @@ var CPMainCibFile = @"CPMainCibFile",
userInfo:nil];
}
- (BOOL)_sendDelegateApplicationShouldTerminate
{
if (!(_implementedDelegateMethods & CPApplicationDelegate_applicationShouldTerminate_))
return YES;
return [_delegate applicationShouldTerminate:self];
}
- (CPString)_sendDelegateApplicationShouldTerminateMessage
{
if (!(_implementedDelegateMethods & CPApplicationDelegate_applicationShouldTerminateMessage_))
return @"You have attempted to leave this page. Are you sure you want to exit this page?";
return [_delegate applicationShouldTerminateMessage:self];
}
- (void)_didResignActive
{
if (self._activeMenu)
+1
View File
@@ -31,6 +31,7 @@ CPApplicationWillResignActiveNotification = @"CPApplicationWillResignA
CPApplicationDidResignActiveNotification = @"CPApplicationDidResignActiveNotification";
CPApplicationDidChangeScreenParametersNotification = @"CPApplicationDidChangeScreenParametersNotification";
@typedef CPApplicationTerminateReply
CPTerminateNow = YES;
CPTerminateCancel = NO;
CPTerminateLater = -1; // not currently supported
+2 -2
View File
@@ -665,10 +665,10 @@ CPButtonImageOffset = 3.0;
*/
- (void)sizeToFit
{
[self setFrameSize:[self _minimumFrameSize]];
[self layoutSubviews];
[self setFrameSize:[self _minimumFrameSize]];
if ([self ephemeralSubviewNamed:@"content-view"])
[self layoutSubviews];
}
+2
View File
@@ -112,6 +112,8 @@
- (void)awakeFromCib
{
[super awakeFromCib];
var view = [self superview],
subview = self;
+1 -1
View File
@@ -195,7 +195,7 @@
- (CGRect)documentVisibleRect
{
return [self convertRect:[self bounds] fromView:_documentView];
return [_documentView visibleRect];
}
@end
+2 -3
View File
@@ -60,6 +60,8 @@ var CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_
@end
var HORIZONTAL_MARGIN = 2;
/*!
@ingroup appkit
@class CPCollectionView
@@ -88,9 +90,6 @@ var CPCollectionViewDelegate_collectionView_acceptDrop_index_dropOperation_
@param indices the indices to obtain drag types
@return an array of drag types (CPString)
*/
var HORIZONTAL_MARGIN = 2;
@implementation CPCollectionView : CPView
{
CPArray _content;
+1 -1
View File
@@ -74,7 +74,7 @@ var CPComboBoxTextSubview = @"text",
BOOL _usesDataSource;
CGSize _intercellSpacing;
CPArray _items;
id<CPComboBoxDataSource> _dataSource;
id <CPComboBoxDataSource> _dataSource;
CPInteger _implementedDelegateComboBoxMethods;
CPString _selectedStringValue;
float _itemHeight;
+52 -8
View File
@@ -42,13 +42,6 @@
@end
@typedef CPTextAlignment
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
@typedef CPControlSize
CPRegularControlSize = 0;
CPSmallControlSize = 1;
@@ -126,6 +119,8 @@ var CPControlBlackColor = [CPColor blackColor];
CGPoint _previousTrackingLocation;
CPControlSize _controlSize;
CPWritingDirection _baseWritingDirection @accessors(property=baseWritingDirection);
}
+ (CPDictionary)themeAttributes
@@ -240,7 +235,7 @@ var CPControlBlackColor = [CPColor blackColor];
*/
- (ThemeState)_controlSizeThemeState
{
switch(_controlSize)
switch (_controlSize)
{
case CPSmallControlSize:
return CPThemeStateControlSizeSmall;
@@ -1016,6 +1011,49 @@ var CPControlBlackColor = [CPColor blackColor];
return [self hasThemeState:CPThemeStateHighlighted];
}
#pragma mark -
#pragma mark Base writing direction
/*!
Sets the initial writing direction of the receiver
@param writingDirection - It could be CPWritingDirectionNatural, CPWritingDirectionLeftToRight, CPWritingDirectionRightToLeft
*/
- (void)setBaseWritingDirection:(CPWritingDirection)writingDirection
{
if (writingDirection == _baseWritingDirection)
return;
[self willChangeValueForKey:@"baseWritingDirection"];
_baseWritingDirection = writingDirection;
[self didChangeValueForKey:@"baseWritingDirection"];
#if PLATFORM(DOM)
var style;
switch (_baseWritingDirection)
{
case CPWritingDirectionNatural:
style = "initial";
break;
case CPWritingDirectionLeftToRight:
style = "ltr";
break;
case CPWritingDirectionRightToLeft:
style = "rtl";
break;
default:
style = "initial";
}
_DOMElement.style.direction = style;
#endif
}
@end
var CPControlActionKey = @"CPControlActionKey",
@@ -1027,6 +1065,7 @@ var CPControlActionKey = @"CPControlActionKey",
CPControlSendsActionOnEndEditingKey = @"CPControlSendsActionOnEndEditingKey",
CPControlTargetKey = @"CPControlTargetKey",
CPControlValueKey = @"CPControlValueKey",
CPControlBaseWrittingDirectionKey = @"CPControlBaseWrittingDirectionKey";
__Deprecated__CPImageViewImageKey = @"CPImageViewImageKey";
@@ -1055,6 +1094,8 @@ var CPControlActionKey = @"CPControlActionKey",
[self setFormatter:[aCoder decodeObjectForKey:CPControlFormatterKey]];
[self setControlSize:[aCoder decodeIntForKey:CPControlControlSizeKey]];
[self setBaseWritingDirection:[aCoder decodeIntForKey:CPControlBaseWrittingDirectionKey]];
}
return self;
@@ -1089,6 +1130,9 @@ var CPControlActionKey = @"CPControlActionKey",
[aCoder encodeObject:_formatter forKey:CPControlFormatterKey];
[aCoder encodeInt:_controlSize forKey:CPControlControlSizeKey];
[aCoder encodeInt:_baseWritingDirection forKey:CPControlBaseWrittingDirectionKey];
}
@end
-8
View File
@@ -630,14 +630,6 @@ CPEraDatePickerElementFlag = 0x0100;
return [[_locale objectForKey:CPLocaleCountryCode] isEqualToString:@"US"];
}
/*! Check if we are in the english format or not. Depending on the locale
*/
- (BOOL)_isEnglishFormat
{
return [[_locale objectForKey:CPLocaleLanguageCode] isEqualToString:@"en"];
}
#pragma mark -
#pragma mark Key event
+1 -1
View File
@@ -139,7 +139,7 @@ var RADIANS = Math.PI / 180;
[_minuteHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"minute-hand-image"]];
[_secondHandLayer setImage:[_datePicker currentValueForThemeAttribute:@"second-hand-image"]];
if ([_datePicker _isEnglishFormat])
if ([_datePicker _isAmericanFormat])
{
if (dateValue.getHours() > 11)
[_PMAMTextField setStringValue:@"PM"]
+102 -75
View File
@@ -198,7 +198,6 @@ var CPZeroKeyCode = 48,
else
[self _selectTextField:_firstTextField];
}
}
/*! Select a textField
@@ -277,74 +276,99 @@ var CPZeroKeyCode = 48,
}
}
/*! performKeyEquivalent event
Used for moving in the textField
/*!
PerformKeyEquivalent event
We need to override that to handle the tab key
*/
- (BOOL)performKeyEquivalent:(CPEvent)anEvent
{
if (![self isEnabled] || !_currentTextField || [[self window] firstResponder] != _datePicker)
return NO;
var key = [anEvent charactersIgnoringModifiers];
if (key == CPUpArrowFunctionKey)
if ([anEvent charactersIgnoringModifiers] === CPTabCharacter)
{
[_currentTextField _invalidTimer];
[_stepper setDoubleValue:[_currentTextField intValue]];
[_stepper performClickUp:self];
if ([anEvent modifierFlags] & CPShiftKeyMask)
[self insertBacktab:self];
else
[self insertTab:self];
return YES;
}
if (key == CPDownArrowFunctionKey)
else if ([anEvent charactersIgnoringModifiers] === CPBackTabCharacter)
{
[_currentTextField _invalidTimer];
[_stepper setDoubleValue:[_currentTextField intValue]];
[_stepper performClickDown:self];
[self insertBacktab:self];
return YES;
}
if (key == CPLeftArrowFunctionKey || [anEvent keyCode] == CPTabKeyCode && [anEvent modifierFlags] & CPShiftKeyMask)
{
if (_currentTextField == _firstTextField && [anEvent keyCode] == CPTabKeyCode)
{
var previousValidKeyView = [_datePicker previousValidKeyView];
if (previousValidKeyView)
[[self window] makeFirstResponder:previousValidKeyView];
return YES;
}
[self _selectTextField:[_currentTextField previousTextField]];
return YES;
}
if (key == CPRightArrowFunctionKey || [anEvent keyCode] == CPTabKeyCode)
{
if (_currentTextField == _lastTextField && [anEvent keyCode] == CPTabKeyCode)
{
var nextValidKeyView = [_datePicker nextValidKeyView];
if (nextValidKeyView)
[[self window] makeFirstResponder:nextValidKeyView];
return YES;
}
[self _selectTextField:[_currentTextField nextTextField]];
return YES;
}
if ([anEvent keyCode] == CPReturnKeyCode)
{
[_currentTextField _endEditing];
return [super performKeyEquivalent:anEvent];
}
return [super performKeyEquivalent:anEvent];
}
- (void)insertTab:(id)sender
{
if (!_currentTextField)
return;
if (_currentTextField == _lastTextField)
[[self window] selectNextKeyView:self];
else
[self moveRight:sender];
}
- (void)moveRight:(id)sender
{
if (!_currentTextField)
return;
[self _selectTextField:[_currentTextField nextTextField]];
}
- (void)insertBacktab:(id)sender
{
if (!_currentTextField)
return;
if (_currentTextField == _firstTextField)
[[self window] selectPreviousKeyView:self];
else
[self moveLeft:sender];
}
- (void)moveLeft:(id)sender
{
if (!_currentTextField)
return;
[self _selectTextField:[_currentTextField previousTextField]];
}
- (void)moveDown:(id)sender
{
if (!_currentTextField)
return;
[_currentTextField _invalidTimer];
[_stepper setDoubleValue:[_currentTextField intValue]];
[_stepper performClickDown:self];
}
- (void)moveUp:(id)sender
{
if (!_currentTextField)
return;
[_currentTextField _invalidTimer];
[_stepper setDoubleValue:[_currentTextField intValue]];
[_stepper performClickUp:self];
}
- (void)insertNewline:(id)sender
{
if (!_currentTextField)
return;
[_currentTextField _endEditing];
}
/*! KeyDown event
We just care care about the event A/P and every numbers
*/
@@ -353,7 +377,9 @@ var CPZeroKeyCode = 48,
if (![self isEnabled])
return;
if ([_datePicker _isEnglishFormat] && [_currentTextField dateType] == CPAMPMDateType && ([anEvent keyCode] == CPAKeyCode || [anEvent keyCode] == CPPKeyCode || [anEvent keyCode] == CPMajAKeyCode || [anEvent keyCode] == CPMajPKeyCode))
[self interpretKeyEvents:[anEvent]];
if ([_datePicker _isAmericanFormat] && [_currentTextField dateType] == CPAMPMDateType && ([anEvent keyCode] == CPAKeyCode || [anEvent keyCode] == CPPKeyCode || [anEvent keyCode] == CPMajAKeyCode || [anEvent keyCode] == CPMajPKeyCode))
{
if ([anEvent keyCode] == CPAKeyCode || [anEvent keyCode] == CPMajAKeyCode)
[_currentTextField setStringValue:@"AM"];
@@ -368,6 +394,7 @@ var CPZeroKeyCode = 48,
[_currentTextField setValueForKeyEvent:anEvent];
}
#pragma mark -
#pragma mark Layout methods
@@ -725,7 +752,7 @@ var CPZeroKeyCode = 48,
if (hour != currentHour)
{
if (([_datePicker _isEnglishFormat] || [_datePicker _isAmericanFormat]))
if ([_datePicker _isAmericanFormat])
{
if (![self _isAMHour])
{
@@ -1050,7 +1077,7 @@ var CPZeroKeyCode = 48,
- (void)_updateHiddenTextFields
{
var datePickerElements = [_datePicker datePickerElements],
isEnglishFormat = [_datePicker _isEnglishFormat];
isAmericanFormat = [_datePicker _isAmericanFormat];
if (datePickerElements & CPYearMonthDatePickerElementFlag)
{
@@ -1083,7 +1110,7 @@ var CPZeroKeyCode = 48,
[_textFieldSeparatorThree setHidden:NO];
[_textFieldSeparatorFour setHidden:YES];
if (isEnglishFormat)
if (isAmericanFormat)
[_textFieldPMAM setHidden:NO];
else
[_textFieldPMAM setHidden:YES];
@@ -1115,9 +1142,9 @@ var CPZeroKeyCode = 48,
verticalInset = contentInset.top - contentInset.bottom,
firstTexField = _textFieldMonth,
secondTextField = _textFieldDay,
isEnglishFormat = [_datePicker _isEnglishFormat];
isAmericanFormat = [_datePicker _isAmericanFormat];
if (!isEnglishFormat)
if (!isAmericanFormat)
{
firstTexField = _textFieldDay;
secondTextField = _textFieldMonth;
@@ -1131,7 +1158,7 @@ var CPZeroKeyCode = 48,
else
[secondTextField setFrameOrigin:CGPointMake(CGRectGetMaxX([_textFieldSeparatorOne frame]) + separatorContentInset.right, verticalInset)];
if (isEnglishFormat && [secondTextField isHidden])
if (isAmericanFormat && [secondTextField isHidden])
[_textFieldSeparatorTwo setFrameOrigin:CGPointMake(CGRectGetMaxX([firstTexField frame]) + separatorContentInset.left, verticalInset)];
else
[_textFieldSeparatorTwo setFrameOrigin:CGPointMake(CGRectGetMaxX([secondTextField frame]) + separatorContentInset.left, verticalInset)];
@@ -1206,7 +1233,7 @@ var CPZeroKeyCode = 48,
{
var datePickerElements = [_datePicker datePickerElements];
if ([_datePicker _isEnglishFormat])
if ([_datePicker _isAmericanFormat])
{
if (datePickerElements & CPYearMonthDayDatePickerElementFlag || datePickerElements & CPYearMonthDatePickerElementFlag)
[[self superview] setFirstTextField:_textFieldMonth];
@@ -1249,9 +1276,9 @@ var CPZeroKeyCode = 48,
var datePickerElements = [_datePicker datePickerElements],
firstTexField = _textFieldMonth,
secondTextField = _textFieldDay,
isEnglishFormat = [_datePicker _isEnglishFormat];
isAmericanFormat = [_datePicker _isAmericanFormat];
if (!isEnglishFormat)
if (!isAmericanFormat)
{
firstTexField = _textFieldDay;
secondTextField = _textFieldMonth;
@@ -1266,7 +1293,7 @@ var CPZeroKeyCode = 48,
if (datePickerElements & CPHourMinuteSecondDatePickerElementFlag || datePickerElements & CPHourMinuteDatePickerElementFlag)
[_textFieldYear setNextTextField:_textFieldHour];
else if (isEnglishFormat || (datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
else if (isAmericanFormat || (datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
[_textFieldYear setNextTextField:firstTexField];
else
[_textFieldYear setNextTextField:secondTextField];
@@ -1275,7 +1302,7 @@ var CPZeroKeyCode = 48,
if ((datePickerElements & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)
[_textFieldMinute setNextTextField:_textFieldSecond];
else if (isEnglishFormat)
else if (isAmericanFormat)
[_textFieldMinute setNextTextField:_textFieldPMAM];
else if ((datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
[_textFieldMinute setNextTextField:firstTexField];
@@ -1284,7 +1311,7 @@ var CPZeroKeyCode = 48,
else
[_textFieldMinute setNextTextField:_textFieldHour];
if (isEnglishFormat)
if (isAmericanFormat)
[_textFieldSecond setNextTextField:_textFieldPMAM];
else if ((datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
[_textFieldSecond setNextTextField:firstTexField];
@@ -1304,9 +1331,9 @@ var CPZeroKeyCode = 48,
var datePickerElements = [_datePicker datePickerElements],
firstTexField = _textFieldMonth,
secondTextField = _textFieldDay,
isEnglishFormat = [_datePicker _isEnglishFormat];
isAmericanFormat = [_datePicker _isAmericanFormat];
if (!isEnglishFormat)
if (!isAmericanFormat)
{
firstTexField = _textFieldDay;
secondTextField = _textFieldMonth;
@@ -1322,14 +1349,14 @@ var CPZeroKeyCode = 48,
if (datePickerElements & CPYearMonthDatePickerElementFlag)
[_textFieldHour setPreviousTextField:_textFieldYear];
else if (isEnglishFormat)
else if (isAmericanFormat)
[_textFieldHour setPreviousTextField:_textFieldPMAM];
else if ((datePickerElements & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)
[_textFieldHour setPreviousTextField:_textFieldSecond];
else
[_textFieldHour setPreviousTextField:_textFieldMinute];
if (!isEnglishFormat)
if (!isAmericanFormat)
[_textFieldYear setPreviousTextField:_textFieldMonth];
else if ((datePickerElements & CPYearMonthDayDatePickerElementFlag) == CPYearMonthDayDatePickerElementFlag)
[_textFieldYear setPreviousTextField:_textFieldDay];
@@ -1338,7 +1365,7 @@ var CPZeroKeyCode = 48,
[secondTextField setPreviousTextField:firstTexField];
if (isEnglishFormat && datePickerElements & CPHourMinuteDatePickerElementFlag)
if (isAmericanFormat && datePickerElements & CPHourMinuteDatePickerElementFlag)
[firstTexField setPreviousTextField:_textFieldPMAM];
else if ((datePickerElements & CPHourMinuteSecondDatePickerElementFlag) == CPHourMinuteSecondDatePickerElementFlag)
[firstTexField setPreviousTextField:_textFieldSecond];
@@ -1530,7 +1557,7 @@ var CPMonthDateType = 0,
}
}
if (parseInt(newValue) > [self _maxNumberWithMaxDate] || ([_datePicker _isEnglishFormat] && _dateType == CPHourDateType && parseInt(newValue) > 12))
if (parseInt(newValue) > [self _maxNumberWithMaxDate] || ([_datePicker _isAmericanFormat] && _dateType == CPHourDateType && parseInt(newValue) > 12))
return;
_firstEvent = NO;
@@ -1549,7 +1576,7 @@ var CPMonthDateType = 0,
if ([stringValue length])
{
if ([_datePicker _isEnglishFormat] && [self dateType] == CPHourDateType)
if ([_datePicker _isAmericanFormat] && [self dateType] == CPHourDateType)
{
var isAMHour = [[self superview] _isAMHour];
@@ -1593,7 +1620,7 @@ var CPMonthDateType = 0,
if (![objectValue length])
objectValue = [self objectValue];
if ([_datePicker _isEnglishFormat] && [self dateType] == CPHourDateType)
if ([_datePicker _isAmericanFormat] && [self dateType] == CPHourDateType)
{
var isAMHour = [[self superview] _isAMHour];
@@ -1621,7 +1648,7 @@ var CPMonthDateType = 0,
}
else if (_dateType != CPAMPMDateType)
{
if (_dateType == CPHourDateType && [_datePicker _isEnglishFormat])
if (_dateType == CPHourDateType && [_datePicker _isAmericanFormat])
{
var value = parseInt(aStringValue);
+1 -1
View File
@@ -182,7 +182,7 @@ var CPBindingOperationAnd = 0,
allBindings = [bindingsForObject allKeys],
count = [allBindings count];
while(count--)
while (count--)
{
if ([[anObject class] isBindingExclusive:allBindings[count]])
return NO;
+2 -2
View File
@@ -26,6 +26,8 @@
CPOKButton = 1;
CPCancelButton = 0;
CPDocModalWindowMask = 1 << 6;
/*!
@ingroup appkit
@class CPPanel
@@ -51,8 +53,6 @@ CPCancelButton = 0;
@global
@class CPWindow
*/
CPDocModalWindowMask = 1 << 6;
@implementation CPPanel : CPWindow
{
BOOL _becomesKeyOnlyIfNeeded;
+55
View File
@@ -86,6 +86,9 @@ var CPProgressIndicatorSpinningStyleColors = [];
@"spinning-mini-gif": [CPNull null],
@"spinning-small-gif": [CPNull null],
@"spinning-regular-gif": [CPNull null],
@"circular-border-color": [CPNull null],
@"circular-border-size": 1,
@"circular-color": [CPNull null]
};
}
@@ -368,6 +371,7 @@ var CPProgressIndicatorSpinningStyleColors = [];
- (void)drawBar
{
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
- (CPView)createEphemeralSubviewNamed:(CPString)aName
@@ -413,6 +417,9 @@ var CPProgressIndicatorSpinningStyleColors = [];
{
if (_style == CPProgressIndicatorSpinningStyle)
{
if (!_indeterminate)
return;
// This will cause the bar view to go away due to having a nil rect when _style == CPProgressIndicatorSpinningStyle.
[self layoutEphemeralSubviewNamed:"bar-view"
positioned:CPWindowBelow
@@ -438,6 +445,54 @@ var CPProgressIndicatorSpinningStyleColors = [];
[self setBackgroundColor:nil];
}
- (void)drawRect:(CGRect)aRect
{
if (_style == CPProgressIndicatorSpinningStyle && !_indeterminate)
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
rect = CGRectMakeCopy(aRect),
borderSize = [self currentValueForThemeAttribute:@"circular-border-size"];
rect.origin.x += borderSize;
rect.origin.y += borderSize;
rect.size.width = rect.size.width - borderSize * 2;
rect.size.height = rect.size.height - borderSize * 2;
if ([self doubleValue] > [self minValue] && [self doubleValue] < [self maxValue])
{
var midX = CGRectGetMidX(rect),
midY = CGRectGetMidY(rect),
endAngle = Math.PI * 2 * (([self doubleValue] - [self minValue]) / ([self maxValue] - [self minValue])) - Math.PI / 2,
radius = MIN(rect.size.width / 2, rect.size.height / 2)
CGContextBeginPath(context);
CGContextSetLineWidth(context, borderSize);
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"])
CGContextMoveToPoint(context, midX, midY);
CGContextAddArc(context, midX, midY, radius, 3 * Math.PI / 2, endAngle, YES)
CGContextAddLineToPoint(context, midX, midY);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextStrokePath(context);
}
else if ([self doubleValue] == [self maxValue])
{
CGContextBeginPath(context);
CGContextSetFillColor(context, [self currentValueForThemeAttribute:@"circular-color"])
CGContextAddEllipseInRect(context, rect);
CGContextClosePath(context);
CGContextFillPath(context);
}
CGContextBeginPath(context);
CGContextSetStrokeColor(context , [self currentValueForThemeAttribute:@"circular-border-color"]);
CGContextSetLineWidth(context, borderSize);
CGContextAddEllipseInRect(context, rect);
CGContextClosePath(context);
CGContextStrokePath(context);
}
}
@end
+4 -6
View File
@@ -29,6 +29,7 @@
@global CPApp
CPRadioImageOffset = 4.0;
/*!
@ingroup appkit
@@ -67,9 +68,6 @@
option.
*/
CPRadioImageOffset = 4.0;
@implementation CPRadio : CPButton
{
CPRadioGroup _radioGroup;
@@ -269,9 +267,9 @@ var CPRadioRadioGroupKey = @"CPRadioRadioGroupKey";
- (BOOL)selectRadioWithTag:(int)tag
{
var index = [_radios indexOfObjectPassingTest:function(radio)
{
return [radio tag] === tag;
}];
{
return [radio tag] === tag;
}];
if (index !== CPNotFound)
{
@@ -487,9 +487,9 @@ CPTransformableAttributeType = 1800;
- (id)copy
{
var views = [CPArray array];
var views = [CPArray array],
copy = [[[self class] alloc] init];
var copy = [[[self class] alloc] init];
[copy _setTemplateType:_templateType];
[copy _setOptions:_predicateOptions];
[copy _setModifier:_predicateModifier];
+9 -9
View File
@@ -86,15 +86,6 @@ var _isBrowserUsingOverlayScrollers = function()
#endif
};
/*!
@ingroup appkit
@class CPScrollView
Used to display views that are too large for the viewing area. the CPScrollView
places scroll bars on the side of the view to allow the user to scroll and see the entire
contents of the view.
*/
var TIMER_INTERVAL = 0.2,
CPScrollViewDelegate_scrollViewWillScroll_ = 1 << 0,
CPScrollViewDelegate_scrollViewDidScroll_ = 1 << 1,
@@ -104,7 +95,14 @@ var TIMER_INTERVAL = 0.2,
var CPScrollerStyleGlobal = CPScrollerStyleOverlay,
CPScrollerStyleGlobalChangeNotification = @"CPScrollerStyleGlobalChangeNotification";
/*!
@ingroup appkit
@class CPScrollView
Used to display views that are too large for the viewing area. the CPScrollView
places scroll bars on the side of the view to allow the user to scroll and see the entire
contents of the view.
*/
@implementation CPScrollView : CPView
{
CPClipView _contentView;
@@ -1584,6 +1582,8 @@ var CPScrollViewContentViewKey = @"CPScrollViewContentView",
*/
- (void)awakeFromCib
{
[super awakeFromCib];
[self _updateScrollerStyle];
[self _updateCornerAndHeaderView];
}
+5 -5
View File
@@ -50,11 +50,6 @@ CPNoScrollerParts = 0;
CPOnlyScrollerArrows = 1;
CPAllScrollerParts = 2;
/*!
@ingroup appkit
@class CPScroller
*/
var PARTS_ARRANGEMENT = [CPScrollerKnobSlot, CPScrollerDecrementLine, CPScrollerIncrementLine, CPScrollerKnob],
NAMES_FOR_PARTS = {},
PARTS_FOR_NAMES = {};
@@ -78,6 +73,11 @@ CPThemeStateScrollViewLegacy = CPThemeState("scroller-style-legacy");
CPThemeStateScrollerKnobLight = CPThemeState("scroller-knob-light");
CPThemeStateScrollerKnobDark = CPThemeState("scroller-knob-dark");
/*!
@ingroup appkit
@class CPScroller
*/
@implementation CPScroller : CPControl
{
CPUsableScrollerParts _usableParts;
+2 -3
View File
@@ -34,9 +34,8 @@ CPSearchFieldRecentsMenuItemTag = 1001;
CPSearchFieldClearRecentsMenuItemTag = 1002;
CPSearchFieldNoRecentsMenuItemTag = 1003;
var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification";
var RECENT_SEARCH_PREFIX = @" ";
var CPAutosavedRecentsChangedNotification = @"CPAutosavedRecentsChangedNotification",
RECENT_SEARCH_PREFIX = @" ";
/*!
@ingroup appkit
+1 -1
View File
@@ -504,7 +504,7 @@ CPSegmentSwitchTrackingMomentary = 2;
*/
- (void)drawSegmentBezel:(int)aSegment highlight:(BOOL)shouldHighlight
{
if(aSegment < _themeStates.length)
if (aSegment < _themeStates.length)
{
if (shouldHighlight)
_themeStates[aSegment] = _themeStates[aSegment].and(CPThemeStateHighlighted);
+44 -35
View File
@@ -55,7 +55,9 @@ var CPSplitViewDelegate_splitView_canCollapseSubview_
CPSplitViewDelegate_splitView_constrainMaxCoordinate_ofSubviewAt_ = 1 << 5,
CPSplitViewDelegate_splitView_constrainMinCoordinate_ofSubviewAt_ = 1 << 6,
CPSplitViewDelegate_splitView_constrainSplitPosition_ofSubviewAt_ = 1 << 7,
CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_ = 1 << 8;
CPSplitViewDelegate_splitView_resizeSubviewsWithOldSize_ = 1 << 8,
CPSplitViewDelegate_splitViewDidResizeSubviews_ = 1 << 9,
CPSplitViewDelegate_splitViewWillResizeSubviews_ = 1 << 10;
#define SPLIT_VIEW_MAYBE_POST_WILL_RESIZE() \
if ((_suppressResizeNotificationsMask & DidPostWillResizeNotification) === 0) \
@@ -967,26 +969,14 @@ The sum of the views and the sum of the dividers should be equal to the size of
if (_delegate === aDelegate)
return;
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewDidResizeSubviewsNotification object:self];
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
[[CPNotificationCenter defaultCenter] removeObserver:_delegate name:CPSplitViewWillResizeSubviewsNotification object:self];
_implementedDelegateMethods |= CPSplitViewDelegate_splitViewWillResizeSubviews_;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
[[CPNotificationCenter defaultCenter] addObserver:_delegate
selector:@selector(splitViewDidResizeSubviews:)
name:CPSplitViewDidResizeSubviewsNotification
object:self];
if ([_delegate respondsToSelector:@selector(splitViewWillResizeSubviews:)])
[[CPNotificationCenter defaultCenter] addObserver:_delegate
selector:@selector(splitViewWillResizeSubviews:)
name:CPSplitViewWillResizeSubviewsNotification
object:self];
if ([_delegate respondsToSelector:@selector(splitViewDidResizeSubviews:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitViewDidResizeSubviews_;
if ([_delegate respondsToSelector:@selector(splitView:canCollapseSubview:)])
_implementedDelegateMethods |= CPSplitViewDelegate_splitView_canCollapseSubview_;
@@ -1064,27 +1054,12 @@ The sum of the views and the sum of the dividers should be equal to the size of
- (void)_postNotificationWillResize
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification
object:self
userInfo:userInfo];
[self _sendDelegateSplitViewWillResizeSubviews];
}
- (void)_postNotificationDidResize
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification
object:self
userInfo:userInfo];
[self _sendDelegateSplitViewDidResizeSubviews];
// TODO Cocoa always autosaves on "viewDidEndLiveResize". If Cappuccino adds support for this we
// should do the same.
@@ -1369,6 +1344,40 @@ The sum of the views and the sum of the dividers should be equal to the size of
[_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
}
/*!
@ignore
Call the delegate splitViewWillResizeSubviews:
*/
- (void)_sendDelegateSplitViewWillResizeSubviews
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
if (_implementedDelegateMethods & CPSplitViewDelegate_splitViewWillResizeSubviews_)
[_delegate splitViewWillResizeSubviews:[[CPNotification alloc] initWithName:CPSplitViewWillResizeSubviewsNotification object:self userInfo:userInfo]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewWillResizeSubviewsNotification object:self userInfo:userInfo];
}
/*!
@ignore
Call the delegate splitViewDidResizeSubviews:
*/
- (void)_sendDelegateSplitViewDidResizeSubviews
{
var userInfo = nil;
if (_currentDivider !== CPNotFound)
userInfo = @{ @"CPSplitViewDividerIndex": _currentDivider };
if (_implementedDelegateMethods & CPSplitViewDelegate_splitViewDidResizeSubviews_)
[_delegate splitViewDidResizeSubviews:[[CPNotification alloc] initWithName:CPSplitViewDidResizeSubviewsNotification object:self userInfo:userInfo]];
[[CPNotificationCenter defaultCenter] postNotificationName:CPSplitViewDidResizeSubviewsNotification object:self userInfo:userInfo];
}
@end
+2
View File
@@ -529,6 +529,8 @@ var CPTabViewItemsKey = "CPTabViewItemsKey",
- (void)awakeFromCib
{
[super awakeFromCib];
// This cannot be run in initWithCoder because it might call selectTabViewItem:, which is
// not safe to call before the views of the tab views items are fully decoded.
[self _updateItems];
+2 -2
View File
@@ -68,7 +68,7 @@
_textField = [[_CPImageAndTextView alloc] initWithFrame:
CGRectMake(5.0, 0.0, CGRectGetWidth([self bounds]) - 10.0, CGRectGetHeight([self bounds]))];
[_textField setAutoresizingMask:CPViewWidthSizable|CPViewHeightSizable];
[_textField setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
[_textField setLineBreakMode:CPLineBreakByTruncatingTail];
[_textField setTextColor:[CPColor colorWithRed:51.0 / 255.0 green:51.0 / 255.0 blue:51.0 / 255.0 alpha:1.0]];
@@ -196,7 +196,7 @@
maxX = CGRectGetMaxX(bounds) - 0.5;
CGContextSetLineWidth(context, 1);
CGContextSetStrokeColor(context, [CPColor colorWithWhite:192.0/255.0 alpha:1.0]);
CGContextSetStrokeColor(context, [CPColor colorWithWhite:192.0 / 255.0 alpha:1.0]);
CGContextBeginPath(context);
+20 -16
View File
@@ -2100,26 +2100,26 @@ NOT YET IMPLEMENTED
found = NO,
max_rec = 100;
while (max_rec--)
while (max_rec--)
{
if (!cellView || cellView === contentView)
{
if (!cellView || cellView === contentView)
found = NO;
break;
}
else
{
var superview = [cellView superview];
if ([superview isKindOfClass:[CPTableView class]])
{
found = NO;
found = YES;
break;
}
else
{
var superview = [cellView superview];
if ([superview isKindOfClass:[CPTableView class]])
{
found = YES;
break;
}
cellView = superview;
}
cellView = superview;
}
}
if (found)
{
@@ -3593,6 +3593,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[self setNeedsDisplay:YES];
}
if (!_isViewBased)
[self _setEditingState:NO forView:dataView];
[self _sendDelegateWillDisplayView:dataView forTableColumn:tableColumn row:row];
return dataView;
@@ -5091,7 +5094,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
_editingColumn = column;
_editingRow = row;
[aView addObserver:self forKeyPath:@"objectValue" options:CPKeyValueObservingOptionOld|CPKeyValueObservingOptionNew context:"editing"];
[aView addObserver:self forKeyPath:@"objectValue" options:CPKeyValueObservingOptionOld | CPKeyValueObservingOptionNew context:"editing"];
}
return aView;
@@ -5196,7 +5199,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
[self _notifyViewDidBecomeFirstResponder];
// This is for cell-based tables only. In view-based mode, we do not change the textfield apprearence during an edit.
if (!_isViewBased && _editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && [responder isEditable])
if (!_isViewBased && _editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && [responder isEditable] && [responder superview] == self)
{
[responder setBezeled:YES];
[self _registerForEndEditingNote:responder];
@@ -6391,6 +6394,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
- (void)awakeFromCib
{
[super awakeFromCib];
[self setThemeState:CPThemeStateTableDataView];
}
+13 -1
View File
@@ -38,4 +38,16 @@ CPLeftTextMovement = 19;
CPRightTextMovement = 20;
CPUpTextMovement = 21;
CPDownTextMovement = 22;
CPCancelTextMovement = 23;
CPCancelTextMovement = 23;
@typedef CPWritingDirection
CPWritingDirectionNatural = -1;
CPWritingDirectionLeftToRight = 0;
CPWritingDirectionRightToLeft = 1;
@typedef CPTextAlignment
CPLeftTextAlignment = 0;
CPRightTextAlignment = 1;
CPCenterTextAlignment = 2;
CPJustifiedTextAlignment = 3;
CPNaturalTextAlignment = 4;
+34 -5
View File
@@ -34,7 +34,6 @@
@global CPStringPboardType
@global CPCursor
@protocol CPTextFieldDelegate <CPControlTextEditingDelegate>
@end
@@ -66,7 +65,8 @@ var CPTextFieldDOMCurrentElement = nil,
CPTextFieldCachedSelectStartFunction = nil,
CPTextFieldCachedDragFunction = nil,
CPTextFieldBlurHandler = nil,
CPTextFieldInputFunction = nil;
CPTextFieldInputFunction = nil,
CPTexFieldCurrentCSSSelectableField = nil;
var CPSecureTextFieldCharacter = "\u2022";
@@ -376,7 +376,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
_sendActionOn = CPKeyUpMask | CPKeyDownMask;
[self setValue:CPLeftTextAlignment forThemeAttribute:@"alignment"];
[self setValue:CPNaturalTextAlignment forThemeAttribute:@"alignment"];
}
return self;
@@ -700,6 +700,21 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
return YES;
}
/*!
Set the selection css style for the DOM element of the textField
@ignore
*/
- (void)_setEnableCSSSelection:(BOOL)shouldEnable
{
#if PLATFORM (DOM)
if (CPTexFieldCurrentCSSSelectableField)
CPTexFieldCurrentCSSSelectableField._DOMElement.style[CPBrowserStyleProperty(@"user-select")] = @"none";
CPTexFieldCurrentCSSSelectableField = self;
_DOMElement.style[CPBrowserStyleProperty(@"user-select")] = shouldEnable ? @"text" : @"none";
#endif
}
/*!
Set the css style for the input element of the textField
@ignore
@@ -753,6 +768,10 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
element.style.textAlign = "right";
break;
case CPNaturalTextAlignment:
element.style.textAlign = "";
break;
default:
element.style.textAlign = "left";
}
@@ -989,6 +1008,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
else if ([self isSelectable])
{
[self _setEnableCSSSelection:YES];
if (document.attachEvent)
{
CPTextFieldCachedSelectStartFunction = [[self window] platformWindow]._DOMBodyElement.onselectstart;
@@ -1030,6 +1050,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
}
- (void)rightMouseDown:(CPEvent)anEvent
{
if ([self menuForEvent:anEvent] || [[self nextResponder] isKindOfClass:CPView])
[super rightMouseDown:anEvent];
else
[[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:YES];
}
- (void)mouseDragged:(CPEvent)anEvent
{
if (![self isEnabled] || !([self isSelectable] || [self isEditable]))
@@ -2002,7 +2030,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
{
previousContentViewBoundsOrigin = CGPointMakeCopy([[scrollView contentView] boundsOrigin]);
if(![[self superview] scrollRectToVisible:[self frame]])
if (![[self superview] scrollRectToVisible:[self frame]])
previousContentViewBoundsOrigin = nil;
}
@@ -2139,7 +2167,8 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
newValue = [self valueForBinding:aBinding],
value = [destination valueForKeyPath:keyPath];
if (CPIsControllerMarker(value) && newValue === nil) return;
if (CPIsControllerMarker(value) && newValue === nil)
return;
newValue = [self reverseTransformValue:newValue withOptions:options];
+99 -5
View File
@@ -26,6 +26,7 @@
@import "CGAffineTransform.j"
@import "CGGeometry.j"
@import "CPAppearance.j"
@import "CPColor.j"
@import "CPGraphicsContext.j"
@import "CPResponder.j"
@@ -131,7 +132,6 @@ var CPViewFlags = { },
var CPViewHighDPIDrawingEnabled = YES;
/*!
@ingroup appkit
@class CPView
@@ -240,6 +240,10 @@ var CPViewHighDPIDrawingEnabled = YES;
BOOL _toolTipInstalled;
BOOL _isObserving;
BOOL _allowsVibrancy @accessors(property=allowsVibrancy);
CPAppearance _appearance @accessors(getter=appearance);
CPAppearance _effectiveAppearance;
}
/*
@@ -327,6 +331,13 @@ var CPViewHighDPIDrawingEnabled = YES;
return nil;
}
- (void)awakeFromCib
{
[super awakeFromCib];
[self _recomputeAppearance];
}
- (id)init
{
return [self initWithFrame:CGRectMakeZero()];
@@ -839,9 +850,9 @@ var CPViewHighDPIDrawingEnabled = YES;
*/
- (void)viewDidMoveToSuperview
{
// if (_graphicsContext)
[self setNeedsDisplay:YES];
[self _recomputeAppearance];
[self setNeedsDisplay:YES];
}
/*!
@@ -1820,7 +1831,7 @@ var CPViewHighDPIDrawingEnabled = YES;
else if ([[self nextResponder] isKindOfClass:CPView])
[super rightMouseDown:anEvent];
else
[[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:YES];
[[[anEvent window] platformWindow] _propagateContextMenuDOMEvent:NO];
}
- (CPMenu)menuForEvent:(CPEvent)anEvent
@@ -3509,6 +3520,85 @@ setBoundsOrigin:
return (_ephemeralSubviewsForNames[aViewName] || nil);
}
@end
@implementation CPView (Appearance)
/*! Returns the receiver's appearance if any, or ask the superview and returns it.
*/
- (CPAppearance)effectiveAppearance
{
if (_appearance)
return _appearance;
return [_superview effectiveAppearance];
}
- (void)setAppearance:(CPAppearance)anAppearance
{
if ([_appearance isEqual:anAppearance])
return;
[self willChangeValueForKey:@"appearance"];
_appearance = anAppearance;
[self didChangeValueForKey:@"appearance"];
[self _recomputeAppearance];
}
/*! @ignore
*/
- (void)_recomputeAppearance
{
// if we don't have a themeState, it means
// the view is not decoding from a cib, so we just return.
// this method will be called again in awakeFromCib
if (!_themeState)
return;
var effectiveAppearance = [self effectiveAppearance];
if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameAqua]])
{
[self setThemeState:CPThemeStateAppearanceAqua];
[self unsetThemeState:CPThemeStateAppearanceLightContent];
[self unsetThemeState:CPThemeStateAppearanceVibrantLight];
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
}
else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameLightContent]])
{
[self unsetThemeState:CPThemeStateAppearanceAqua];
[self setThemeState:CPThemeStateAppearanceLightContent];
[self unsetThemeState:CPThemeStateAppearanceVibrantLight];
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
}
else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]])
{
[self unsetThemeState:CPThemeStateAppearanceAqua];
[self unsetThemeState:CPThemeStateAppearanceLightContent];
[self setThemeState:CPThemeStateAppearanceVibrantLight];
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
}
else if ([effectiveAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]])
{
[self unsetThemeState:CPThemeStateAppearanceAqua];
[self unsetThemeState:CPThemeStateAppearanceLightContent];
[self unsetThemeState:CPThemeStateAppearanceVibrantLight];
[self setThemeState:CPThemeStateAppearanceVibrantDark];
}
else
{
[self unsetThemeState:CPThemeStateAppearanceAqua];
[self unsetThemeState:CPThemeStateAppearanceLightContent];
[self unsetThemeState:CPThemeStateAppearanceVibrantLight];
[self unsetThemeState:CPThemeStateAppearanceVibrantDark];
}
[_subviews makeObjectsPerformSelector:@selector(_recomputeAppearance)];
}
@end
var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
@@ -3531,7 +3621,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPReuseIdentifierKey = @"CPReuseIdentifierKey",
CPViewScaleKey = @"CPViewScaleKey",
CPViewSizeScaleKey = @"CPViewSizeScaleKey",
CPViewIsScaledKey = @"CPViewIsScaledKey";
CPViewIsScaledKey = @"CPViewIsScaledKey",
CPViewAppearanceKey = @"CPViewAppearanceKey";
@implementation CPView (CPCoding)
@@ -3646,6 +3737,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_themeAttributes[attributeName] = CPThemeAttributeDecode(aCoder, attributeName, attributes[count], _theme, themeClass);
}
[self setAppearance:[aCoder decodeObjectForKey:CPViewAppearanceKey]];
[self setNeedsDisplay:YES];
[self setNeedsLayout];
}
@@ -3734,6 +3827,7 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
[aCoder encodeSize:[self scaleSize] forKey:CPViewScaleKey];
[aCoder encodeSize:[self _hierarchyScaleSize] forKey:CPViewSizeScaleKey];
[aCoder encodeBool:_isScaled forKey:CPViewIsScaledKey];
[aCoder encodeObject:_appearance forKey:CPViewAppearanceKey];
}
@end
+231
View File
@@ -0,0 +1,231 @@
/*
* CPVisualEffectView.j
* AppKit
*
* Created by Antoine Mercadal.
* Copyright 2015, 280 Cappuccino Project.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/Foundation.j>
@import "CPAppearance.j"
@import "CPView.j"
@typedef CPVisualEffectMaterial
CPVisualEffectMaterialAppearanceBased = 0;
CPVisualEffectMaterialLight = 1;
CPVisualEffectMaterialDark = 2;
CPVisualEffectMaterialTitlebar = 3;
@typedef CPVisualEffectBlendingMode
CPVisualEffectBlendingModeBehindWindow = 0;
CPVisualEffectBlendingModeWithinWindow = 1;
@typedef CPVisualEffectState
CPVisualEffectStateFollowsWindowActiveState = 0;
CPVisualEffectStateActive = 1;
CPVisualEffectStateInactive = 2;
/*! @ingroup appkit
Very naive implementation of CPVisualEffectView. This view allows
to use vibrancy effect. This is only working with Safari 9+ and the
support in Chrome/ium should come quite soon.
Using this class with a browser that doesn't support backdrop-filter
While still work, but you will not get the blurry effect.
*/
@implementation CPVisualEffectView : CPView
{
CPImage _maskImage @accessors(property=maskImage);
CPVisualEffectBlendingMode _blendingMode @accessors(property=blendingMode);
CPVisualEffectMaterial _material @accessors(property=material);
CPVisualEffectState _state @accessors(property=state);
}
#pragma mark -
#pragma mark Initialization
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
_material = CPVisualEffectMaterialAppearanceBased;
_blendingMode = CPVisualEffectBlendingModeWithinWindow;
_state = CPVisualEffectStateFollowsWindowActiveState;
_appearance = [CPAppearance appearanceNamed:CPAppearanceNameVibrantDark];
}
return self;
}
#pragma mark -
#pragma mark CPVisualEffectView API
/*! Sets the appearance of the CPVisualEffectView.
Only CPAppearance named CPAppearanceNameVibrantDark or CPAppearanceNameVibrantLight are valid
@param anAppearance the CPAppearance.
*/
- (void)setAppearance:(CPAppearance)anAppearance
{
if (![self _validAppearance:anAppearance])
[CPException raise:CPInvalidArgumentException reason:"Appearance can only be CPAppearanceNameVibrantDark or CPAppearanceNameVibrantLight in CPVisualEffectView, but is " + anAppearance];
[super setAppearance:anAppearance];
[self _applyVibrancyState];
}
/*! Sets the received effect state.
Possible values:
<pre>
CPVisualEffectStateFollowsWindowActiveState (default)
CPVisualEffectStateActive
CPVisualEffectStateInactive
</pre>
*/
- (void)setState:(CPVisualEffectState)aState
{
if (_state == aState)
return;
[self willChangeValueForKey:"state"];
_state = aState;
[self didChangeValueForKey:"state"];
[self _applyVibrancyState];
}
#pragma mark -
#pragma mark Utilities
- (void)_setEffectEnabled:(BOOL)shouldEnable
{
var dark = [[self appearance] isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]],
prop = CPBrowserStyleProperty("backdrop-filter"),
color = (dark ? [CPColor colorWithHexString:@"1e1e1e"] : [CPColor whiteColor]),
finalColor = shouldEnable ? [color colorWithAlphaComponent:0.6] : color;
[self setBackgroundColor:finalColor];
#if PLATFORM(DOM)
self._DOMElement.style[prop] = shouldEnable ? "blur(30px)" : nil;
#endif
}
- (void)_applyVibrancyState
{
switch (_state)
{
case CPVisualEffectStateFollowsWindowActiveState:
[self _setEffectEnabled:[self hasThemeState:CPThemeStateKeyWindow]];
break;
case CPVisualEffectStateActive:
[self _setEffectEnabled:YES];
break;
case CPVisualEffectStateInactive:
[self _setEffectEnabled:NO];
break;
}
}
- (BOOL)_validAppearance:(CPAppearance)anAppearance
{
return [anAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantDark]] || [anAppearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]];
}
#pragma mark -
#pragma mark Overrides
- (BOOL)setThemeState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
var r = [super setThemeState:aState];
if (r)
[self _applyVibrancyState];
return r;
}
- (BOOL)unsetThemeState:(ThemeState)aState
{
if (aState.isa && [aState isKindOfClass:CPArray])
aState = CPThemeState.apply(null, aState);
var r = [super unsetThemeState:aState];
if (r)
[self _applyVibrancyState];
return r;
}
- (void)viewDidMoveToSuperview
{
[super viewDidMoveToSuperview];
if (_superview)
[self _applyVibrancyState];
}
- (void)viewDidMoveToWindow
{
[super viewDidMoveToWindow];
if (_window)
[self _applyVibrancyState];
}
#pragma mark -
#pragma mark CPCoding
- (id)initWithCoder:(CPCoder)aCoder
{
if (self = [super initWithCoder:aCoder])
{
_blendingMode = [aCoder decodeIntForKey:@"_blendingMode"] || CPVisualEffectBlendingModeWithinWindow;
_maskImage = [aCoder decodeObjectForKey:@"_maskImage"];
_material = [aCoder decodeIntForKey:@"_material"] || CPVisualEffectMaterialAppearanceBased;
_state = [aCoder decodeIntForKey:@"_state"] || CPVisualEffectStateFollowsWindowActiveState;
}
return self;
}
- (void)encodeWithCoder:(CPCoder)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:_maskImage forKey:@"_maskImage"];
[aCoder encodeInt:_blendingMode forKey:@"_blendingMode"];
[aCoder encodeInt:_material forKey:@"_material"];
[aCoder encodeInt:_state forKey:@"_state"];
}
@end
+4 -4
View File
@@ -63,7 +63,7 @@
@optional
- (BOOL)windowShouldClose:(CPWindow)aWindow;
- (CPSize)windowWillResize:(CPWindow)sender toSize:(CPSize)aSize;
- (CGSize)windowWillResize:(CPWindow)sender toSize:(CGSize)aSize;
- (CPUndoManager)windowWillReturnUndoManager:(CPWindow)window;
- (void)windowDidBecomeKey:(CPNotification)aNotification;
- (void)windowDidBecomeMain:(CPNotification)aNotification;
@@ -80,7 +80,7 @@
@end
var CPWindowDelegate_windowShouldClose_ = 1 << 1
var CPWindowDelegate_windowShouldClose_ = 1 << 1,
CPWindowDelegate_windowWillReturnUndoManager_ = 1 << 2,
CPWindowDelegate_windowWillClose_ = 1 << 3,
CPWindowDelegate_windowWillResize_toSize_ = 1 << 4;
@@ -2780,7 +2780,7 @@ CPTexturedBackgroundWindowMask
[[CPNotificationCenter defaultCenter] removeObserver:self name:CPWindowDidEndSheetNotification object:self];
var sheet = _sheetContext[@"nextSheet"],
modalDelegate =_sheetContext[@"nextModalDelegate"],
modalDelegate = _sheetContext[@"nextModalDelegate"],
endSelector = _sheetContext[@"nextEndSelector"],
contextInfo = _sheetContext[@"nextContextInfo"];
@@ -3521,7 +3521,7 @@ var keyViewComparator = function(lhs, rhs, context)
@ignore
Call the delegate windowWillResize:toSize:
*/
- (CPSize)_sendDelegateWindowWillResizeToSize:(CPSize)aSize
- (CGSize)_sendDelegateWindowWillResizeToSize:(CGSize)aSize
{
if (!(_implementedDelegateMethods & CPWindowDelegate_windowWillResize_toSize_))
return aSize;
+2 -4
View File
@@ -26,7 +26,6 @@
@import "CGGradient.j"
@import "_CPWindowView.j"
@global CPPopoverAppearanceMinimal
var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
@@ -39,7 +38,6 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
{
float _arrowOffsetX @accessors(property=arrowOffsetX);
float _arrowOffsetY @accessors(property=arrowOffsetY);
int _appearance @accessors(property=appearance);
unsigned _preferredEdge @accessors(property=preferredEdge);
CGSize _cursorSize;
@@ -123,7 +121,7 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
{
_arrowOffsetX = 0.0;
_arrowOffsetY = 0.0;
_appearance = CPPopoverAppearanceMinimal;
_appearance = [CPAppearance appearanceNamed:CPAppearanceNameVibrantLight];
_cursorSize = CGSizeMakeCopy(_CPPopoverWindowViewDefaultCursorSize);
}
@@ -168,7 +166,7 @@ var _CPPopoverWindowViewDefaultCursorSize = CGSizeMake(16, 10);
gradient,
frame = [self bounds];
if (_appearance == CPPopoverAppearanceMinimal)
if ([_appearance isEqual:[CPAppearance appearanceNamed:CPAppearanceNameVibrantLight]])
{
gradient = [self valueForThemeAttribute:@"background-gradient"];
strokeColor = [self valueForThemeAttribute:@"stroke-color"];
+4 -4
View File
@@ -27,7 +27,8 @@
@import "CGContext.j"
@import "CGGeometry.j"
@import "CPColor.j"
@import "CPView.j"
#define DOM(aLayer) aLayer._DOMElement
@@ -494,11 +495,11 @@ var CALayerRegisteredRunLoopUpdates = nil;
*/
- (void)display
{
#if PLATFORM(DOM)
if (!_context)
{
_context = CGBitmapGraphicsContextCreate();
#if PLATFORM(DOM)
_DOMContentsElement = _context.DOMElement;
_DOMContentsElement.style.zIndex = -100;
@@ -516,7 +517,6 @@ var CALayerRegisteredRunLoopUpdates = nil;
_DOMContentsElement.style.height = ROUND(CGRectGetHeight(_backingStoreFrame)) + "px";
_DOMElement.appendChild(_DOMContentsElement);
#endif
}
if (USE_BUFFER)
@@ -534,6 +534,7 @@ var CALayerRegisteredRunLoopUpdates = nil;
[self drawInContext:CABackingStoreGetContext(_contents)];
}
#endif
[self composite];
}
@@ -796,7 +797,6 @@ if (_DOMContentsElement && aLayer._zPosition > _DOMContentsElement.style.zIndex)
if (mask & CALayerDisplayUpdateMask)
[layer display];
else if (mask & CALayerFrameSizeUpdateMask || mask & CALayerCompositeUpdateMask)
[layer composite];
-2
View File
@@ -1,8 +1,6 @@
require("../common.jake");
checkUlimit();
var framework = require("objective-j/jake").framework,
BundleTask = require("objective-j/jake").BundleTask;
+25
View File
@@ -48,10 +48,21 @@ var screenNeedsInitialization = NO,
document.documentElement.style.overflow = "hidden";
if ([CPPlatform isBrowser])
{
// This differ from cocoa, where shouldTerminate is called in the method terminate of CPApp
// Cappuccino acts like this because we can not close a window openend by the user with a script (so not possible in terminate), and we can only prevent the action in the method onbeforeunload in js.
window.onbeforeunload = function()
{
if ([CPApp _sendDelegateApplicationShouldTerminate] != CPTerminateNow)
return [CPApp _sendDelegateApplicationShouldTerminateMessage];
};
window.onunload = function()
{
[self closeAllPlatformWindows];
[CPApp terminate:nil];
};
}
}
+ (BOOL)isBrowser
@@ -138,4 +149,18 @@ var screenNeedsInitialization = NO,
object:self];
}
+ (void)closeAllPlatformWindows
{
var platformWindows = [CPPlatformWindow visiblePlatformWindows],
primaryPlatformWindow = [CPPlatformWindow primaryPlatformWindow],
platformWindowEnumerator = [platformWindows objectEnumerator],
platformWindow = nil;
while ((platformWindow = [platformWindowEnumerator nextObject]) !== nil)
{
if (platformWindow != primaryPlatformWindow)
[platformWindow orderOut:self];
}
}
@end
@@ -365,6 +365,7 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
_DOMBodyElement.style["-khtml-user-select"] = "none";
_DOMBodyElement.webkitTouchCallout = "none";
_DOMBodyElement.style[CPBrowserStyleProperty(@"user-select")] = @"none";
[self createDOMElements];
[self _addLayers];
+18
View File
@@ -2999,6 +2999,24 @@ var themedButtonValues = nil,
return progressBar;
}
+ (CPProgressIndicator)themedCircularProgressIndicator
{
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
[progressBar setStyle:CPProgressIndicatorSpinningStyle];
[progressBar setIndeterminate:NO];
var themeValues =
[
[@"circular-border-color", [CPColor colorWithHexString:@"C7C7C7"]],
[@"circular-border-size", 1],
[@"circular-color", [CPColor colorWithHexString:@"89B5CD"]]
];
[self registerThemeValues:themeValues forView:progressBar];
return progressBar;
}
+ (CPBox)themedBox
{
var box = [[CPBox alloc] initWithFrame:CGRectMake(0,0,100,100)],
+20 -1
View File
@@ -688,7 +688,8 @@ var themedButtonValues = nil,
[@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateEditable, CPThemeStateFirstResponder, CPThemeStateKeyWindow]],
[@"content-inset", CGInsetMake(7.0, 7.0, 5.0, 10.0), [CPThemeStateTableDataView, CPThemeStateEditable]],
[@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateEditing]],
[@"bezel-inset", CGInsetMake(-2.0, -2.0, -2.0, -2.0), [CPThemeStateTableDataView, CPThemeStateEditing]],
[@"bezel-inset", CGInsetMake(-2.0, -2.0, -2.0, -2.0), [CPThemeStateTableDataView, CPThemeStateEditable, CPThemeStateEditing]],
[@"bezel-inset", CGInsetMake(1.0, 1.0, 1.0, 1.0), [CPThemeStateTableDataView, CPThemeStateEditable]],
[@"text-color", [CPColor colorWithCalibratedWhite:125.0 / 255.0 alpha:1.0], [CPThemeStateTableDataView, CPThemeStateGroupRow]],
[@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]],
@@ -2499,6 +2500,24 @@ var themedButtonValues = nil,
return progressBar;
}
+ (CPProgressIndicator)themedCircularProgressIndicator
{
var progressBar = [[CPProgressIndicator alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
[progressBar setStyle:CPProgressIndicatorSpinningStyle];
[progressBar setIndeterminate:NO];
var themeValues =
[
[@"circular-border-color", [CPColor colorWithHexString:@"A0A0A0"]],
[@"circular-border-size", 1],
[@"circular-color", [CPColor colorWithHexString:@"5982DA"]]
];
[self registerThemeValues:themeValues forView:progressBar];
return progressBar;
}
+ (CPBox)themedBox
{
var box = [[CPBox alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
+27 -15
View File
@@ -141,7 +141,12 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
if (_appearance === anAppearance)
return;
[_windowView setAppearance:anAppearance];
_appearance = anAppearance;
var appearanceName = _appearance == CPPopoverAppearanceMinimal ? CPAppearanceNameVibrantLight : CPAppearanceNameVibrantDark,
viewAppearance = [CPAppearance appearanceNamed:appearanceName];
[_windowView setAppearance:viewAppearance];
}
- (void)setStyleMask:(unsigned)aStyleMask
@@ -548,29 +553,36 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
// Now set up the pop-in to normal size transition.
// Because we are watching the -webkit-transform, it will occur now.
[self setCSS3Property:@"Transform" value:@"scale(1)"];
[self setCSS3Property:@"Transition" value:CPBrowserCSSProperty('transform') + @" 50ms linear"];
_transitionCompleteFunction = function()
window.setTimeout(function()
{
[self setCSS3Property:@"Transform" value:@"scale(1)"];
[self setCSS3Property:@"Transition" value:CPBrowserCSSProperty('transform') + @" 50ms linear"];
_transitionCompleteFunction = function()
{
#if PLATFORM(DOM)
_DOMElement.removeEventListener(CPBrowserStyleProperty('transitionend'), _transitionCompleteFunction, YES);
_DOMElement.removeEventListener(CPBrowserStyleProperty('transitionend'), _transitionCompleteFunction, YES);
// Make sure to clear these properties when the animation is done. Without this,
// the window becomes blurry in Chrome, presumably because the browser composits
// a layer with a transform differently even when it's an identity transform.
[self setCSS3Property:@"Transform" value:nil];
[self setCSS3Property:@"TransformOrigin" value:nil];
[self setCSS3Property:@"Transition" value:nil];
// Make sure to clear these properties when the animation is done. Without this,
// the window becomes blurry in Chrome, presumably because the browser composits
// a layer with a transform differently even when it's an identity transform.
[self setCSS3Property:@"Transform" value:nil];
[self setCSS3Property:@"TransformOrigin" value:nil];
[self setCSS3Property:@"Transition" value:nil];
#endif
_isOpening = NO;
_isOpening = NO;
[_delegate _popoverWindowDidShow];
}
[_delegate _popoverWindowDidShow];
}
#if PLATFORM(DOM)
_DOMElement.addEventListener(CPBrowserStyleProperty('transitionend'), _transitionCompleteFunction, YES);
_DOMElement.addEventListener(CPBrowserStyleProperty('transitionend'), _transitionCompleteFunction, YES);
#endif
}, 0); // There are some weird random conditions happening in Chrome 44. If we don't put a timeout to 0 for the end of
// the transition, the popover is blinking. It happens on Opera as well...
// When the condition is met, the popover will lag a bit when opening...nothing crazy ;)
// An issue has been opened here : https://code.google.com/p/chromium/issues/detail?id=523044&thanks=523044&ts=1440095724
};
#if PLATFORM(DOM)
+25 -10
View File
@@ -366,23 +366,38 @@ function pressEnvironment(rootPath, outputFiles, environment, options) {
return {executable:includedBytes, data:dataBytes, mhtml:mhtmlBytes};
}
function pngcrushDirectory(directory) {
var directoryPath = FILE.path(directory);
var pngs = directoryPath.glob("**/*.png");
function pngcrushDirectory(directory)
{
var directoryPath = FILE.path(directory),
pngs = directoryPath.glob("**/*.png");
system.stderr.print("Running pngcrush on " + pngs.length + " pngs:");
pngs.forEach(function(dstPath) {
pngs.forEach(function(dstPath)
{
var tmpPath = FILE.path(dstPath+".tmp");
var p = OS.popen(["pngcrush", "-rem", "alla", "-reduce", /*"-brute",*/ dstPath, tmpPath]);
if (p.wait()) {
CPLog.warn("pngcrush failed. Ensure it's installed and on your PATH.");
try
{
var p = OS.popen(["pngcrush", "-rem", "alla", "-reduce", /*"-brute",*/ dstPath, tmpPath]);
if (p.wait())
{
CPLog.warn("pngcrush failed. Ensure it's installed and on your PATH.");
}
else
{
FILE.move(tmpPath, dstPath);
system.stderr.write(".").flush();
}
}
else {
FILE.move(tmpPath, dstPath);
system.stderr.write(".").flush();
finally
{
p.stdin.close();
p.stdout.close();
p.stderr.close();
}
});
system.stderr.print("");
}
+15 -5
View File
@@ -3,10 +3,20 @@ var OS = require("os");
exports.fontinfo = function(name, size)
{
var p = OS.popen(["fontinfo", "-n", name, size || 12]);
var result;
if (p.wait() === 0)
return JSON.parse(p.stdout.read());
else
return null;
try
{
var p = OS.popen(["fontinfo", "-n", name, size || 12]);
if (p.wait() === 0)
result = p.stdout.read();
}
finally
{
p.stdin.close();
p.stdout.close();
p.stderr.close();
}
return result ? JSON.parse(result) : null;
};
+15 -5
View File
@@ -3,10 +3,20 @@ var OS = require("os");
exports.imagesize = function(path)
{
var p = OS.popen(["imagesize", "-n", path]);
var result;
if (p.wait() === 0)
return JSON.parse(p.stdout.read());
else
return null;
try
{
var p = OS.popen(["imagesize", "-n", path]);
if (p.wait() === 0)
result = p.stdout.read();
}
finally
{
p.stdin.close();
p.stdout.close();
p.stderr.close();
}
return result ? JSON.parse(result) : null;
};
+8
View File
@@ -208,6 +208,14 @@ var concat = Array.prototype.concat,
_CPRaiseInvalidAbstractInvocation(self, _cmd);
}
/*!
Returns a hash for the object. Unlike Cocoa, the hash value does not take content into account, so two arrays with the same content (\c isEqual: === YES) will not generate the same hash.
*/
- (unsigned)hash
{
return [self UID];
}
/*!
Returns the first object in the array. If the array is empty, returns \c nil
*/
+2 -1
View File
@@ -196,7 +196,8 @@ var concat = Array.prototype.concat,
}
else
for (; index < count; ++index) {
for (; index < count; ++index)
{
var receiver = self[index];
receiver == nil ? nil : receiver.isa.objj_msgSend0(receiver, aSelector);
}
+2 -3
View File
@@ -26,9 +26,8 @@
@import "CPString.j"
// The default global behavior class, created lazily
var CPDefaultDcmHandler = nil;
var CPDecimalNumberUIDs = new CFMutableDictionary();
var CPDefaultDcmHandler = nil,
CPDecimalNumberUIDs = new CFMutableDictionary();
/*!
@class CPDecimalNumberHandler
+2 -2
View File
@@ -605,11 +605,11 @@
}
if ([self scanPredicateKeyword:@"TRUE"] || [self scanPredicateKeyword:@"YES"])
{
return [CPExpression expressionForConstantValue:[CPNumber numberWithBool:YES]];
return [CPExpression expressionForConstantValue:YES];
}
if ([self scanPredicateKeyword:@"FALSE"] || [self scanPredicateKeyword:@"NO"])
{
return [CPExpression expressionForConstantValue:[CPNumber numberWithBool:NO]];
return [CPExpression expressionForConstantValue:NO];
}
if ([self scanPredicateKeyword:@"SELF"])
{
+1 -1
View File
@@ -266,7 +266,7 @@ var abbreviationDictionary,
@"MST" : [@"Mountain Standard Time", @"MST", @"Mountain Daylight Time", @"MDT", @"Mountain Time", @"MT"],
@"PHT" : [@"Philippine Standard Time", @"GMT+08:00", @"Philippine Summer Time", @"GMT+08:00", @"Philippine Standard Time", @"Philippines Time"],
@"WET" : [@"Western European Standard Time", @"GMT", @"Western European Summer Time", @"GMT+01:00", @"Western European Time", @"Portugal Time (Lisbon)"]
};
};
var date = [CPDate date],
abbreviation = String(String(date).split("(")[1]).split(")")[0];
+41 -12
View File
@@ -26,6 +26,16 @@
@import "CPURLRequest.j"
@import "CPURLResponse.j"
@protocol CPURLConnectionDelegate <CPObject>
- (void)connection:(CPURLConnection)anURLConnection didFailWithError:(CPException)anError;
- (void)connection:(CPURLConnection)anURLConnection didReceiveData:(CPString)aData;
- (void)connection:(CPURLConnection)anURLConnection didReceiveResponse:(CPString)aResponse;
- (void)connectionDidFinishLoading:(CPURLConnection)anURLConnection;
- (void)connectionDidReceiveAuthenticationChallenge:(CPURLConnection)anURLConnection;
@end
@typedef HTTPRequest
var CPURLConnectionDelegate = nil;
@@ -76,16 +86,16 @@ var CPURLConnectionDelegate = nil;
*/
@implementation CPURLConnection : CPObject
{
CPURLRequest _originalRequest @accessors(readonly, getter=originalRequest);
CPURLRequest _request @accessors(readonly, getter=currentRequest);
id _delegate;
BOOL _isCanceled;
BOOL _isLocalFileConnection;
CPURLRequest _originalRequest @accessors(readonly, getter=originalRequest);
CPURLRequest _request @accessors(readonly, getter=currentRequest);
id <CPURLConnectionDelegate> _delegate;
BOOL _isCanceled;
BOOL _isLocalFileConnection;
HTTPRequest _HTTPRequest;
HTTPRequest _HTTPRequest;
}
+ (void)setClassDelegate:(id)delegate
+ (void)setClassDelegate:(id <CPURLConnectionDelegate>)delegate
{
CPURLConnectionDelegate = delegate;
}
@@ -145,7 +155,7 @@ var CPURLConnectionDelegate = nil;
@param shouldStartImmediately whether the \c -start method should be called from here
@return the initialized url connection
*/
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id <CPURLConnectionDelegate>)aDelegate startImmediately:(BOOL)shouldStartImmediately
{
self = [super init];
@@ -166,6 +176,7 @@ var CPURLConnectionDelegate = nil;
(window.location.protocol === "file:" || window.location.protocol === "app:"));
_HTTPRequest = new CFHTTPRequest();
_HTTPRequest.setTimeout([aRequest timeoutInterval] * 1000);
_HTTPRequest.setWithCredentials([aRequest withCredentials]);
if (shouldStartImmediately)
@@ -175,7 +186,7 @@ var CPURLConnectionDelegate = nil;
return self;
}
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate
- (id)initWithRequest:(CPURLRequest)aRequest delegate:(id <CPURLConnectionDelegate>)aDelegate
{
return [self initWithRequest:aRequest delegate:aDelegate startImmediately:YES];
}
@@ -200,6 +211,7 @@ var CPURLConnectionDelegate = nil;
_HTTPRequest.open([_request HTTPMethod], [[_request URL] absoluteString], YES);
_HTTPRequest.onreadystatechange = function() { [self _readyStateDidChange]; };
_HTTPRequest.ontimeout = function() { [self _didTimeout]; };
var fields = [_request allHTTPHeaderFields],
key = nil,
@@ -212,11 +224,16 @@ var CPURLConnectionDelegate = nil;
}
catch (anException)
{
if ([_delegate respondsToSelector:@selector(connection:didFailWithError:)])
[_delegate connection:self didFailWithError:anException];
[self _sendDelegateDidFailWithError:anException];
}
}
- (void)_sendDelegateDidFailWithError:(CPException)anException
{
if ([_delegate respondsToSelector:@selector(connection:didFailWithError:)])
[_delegate connection:self didFailWithError:anException];
}
/*
Cancels the current request.
*/
@@ -239,10 +256,22 @@ var CPURLConnectionDelegate = nil;
return _isLocalFileConnection;
}
/*!
@ignore
*/
- (void)_didTimeout
{
var exception = [CPException exceptionWithName:@"Timeout exception"
reason:"The request timed out."
userInfo:@{}];
[self _sendDelegateDidFailWithError:exception];
}
/* @ignore */
- (void)_readyStateDidChange
{
if (_HTTPRequest.readyState() === CFHTTPRequest.CompleteState)
if (_HTTPRequest.readyState() === CFHTTPRequest.CompleteState && !_HTTPRequest.isTimeoutRequest())
{
var statusCode = _HTTPRequest.status(),
URL = [_request URL];
+71 -9
View File
@@ -25,6 +25,12 @@
@import "CPString.j"
@import "CPURL.j"
@typedef CPURLRequestCachePolicy
CPURLRequestUseProtocolCachePolicy = 0;
CPURLRequestReloadIgnoringLocalCacheData = 1;
CPURLRequestReturnCacheDataElseLoad = 2;
CPURLRequestReturnCacheDataDontLoad = 3;
/*!
@class CPURLRequest
@ingroup foundation
@@ -35,14 +41,16 @@
*/
@implementation CPURLRequest : CPObject
{
CPURL _URL @accessors(property=URL);
CPURL _URL @accessors(property=URL);
// FIXME: this should be CPData
CPString _HTTPBody @accessors(property=HTTPBody);
CPString _HTTPMethod @accessors(property=HTTPMethod);
BOOL _withCredentials @accessors(property=withCredentials);
CPString _HTTPBody @accessors(property=HTTPBody);
CPString _HTTPMethod @accessors(property=HTTPMethod);
BOOL _withCredentials @accessors(property=withCredentials);
CPDictionary _HTTPHeaderFields @accessors(readonly, getter=allHTTPHeaderFields);
CPDictionary _HTTPHeaderFields @accessors(readonly, getter=allHTTPHeaderFields);
CPTimeInterval _timeoutInterval @accessors(readonly, getter=timeoutInterval);
CPURLRequestCachePolicy _cachePolicy @accessors(readonly, getter=cachePolicy);
}
/*!
@@ -55,6 +63,18 @@
return [[CPURLRequest alloc] initWithURL:aURL];
}
/*!
Creates a request with a specified URL, cachePolicy and timeoutInterval
@param aURL the URL of the request
@param aCachePolicy the cache policy of the request
@param aTimeoutInterval the timeoutInterval of the request
@return a CPURLRequest
*/
+ (id)requestWithURL:(CPURL)anURL cachePolicy:(CPURLRequestCachePolicy)aCachePolicy timeoutInterval:(CPTimeInterval)aTimeoutInterval
{
return [[CPURLRequest alloc] initWithURL:anURL cachePolicy:aCachePolicy timeoutInterval:aTimeoutInterval];
}
/*!
Equal to `[receiver initWithURL:nil]`.
*/
@@ -63,6 +83,25 @@
return [self initWithURL:nil];
}
/*!
Initializes the request with a URL. This is the designated initializer.
@param aURL the url to set
@param aCachePolicy the cache policy of the request
@param aTimeoutInterval the timeoutInterval of the request
@return the initialized CPURLRequest
*/
- (id)initWithURL:(CPURL)anURL cachePolicy:(CPURLRequestCachePolicy)aCachePolicy timeoutInterval:(CPTimeInterval)aTimeoutInterval
{
if (self = [self initWithURL:anURL])
{
_cachePolicy = aCachePolicy;
_timeoutInterval = aTimeoutInterval;
}
return self;
}
/*!
Initializes the request with a URL. This is the designated initializer.
@@ -71,9 +110,7 @@
*/
- (id)initWithURL:(CPURL)aURL
{
self = [super init];
if (self)
if (self = [super init])
{
[self setURL:aURL];
@@ -81,9 +118,34 @@
_HTTPMethod = @"GET";
_HTTPHeaderFields = @{};
_withCredentials = NO;
_timeoutInterval = 60.0;
_cachePolicy = CPURLRequestUseProtocolCachePolicy;
[self setValue:"Thu, 01 Jan 1970 00:00:00 GMT" forHTTPHeaderField:"If-Modified-Since"];
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
switch (_cachePolicy)
{
case CPURLRequestUseProtocolCachePolicy:
// TODO: implement everything about cache...
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
break;
case CPURLRequestReturnCacheDataElseLoad:
[self setValue:"max-stale=31536000" forHTTPHeaderField:"Cache-Control"];
break;
case CPURLRequestReturnCacheDataDontLoad:
[self setValue:"only-if-cached" forHTTPHeaderField:"Cache-Control"];
break;
case CPURLRequestReloadIgnoringLocalCacheData:
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
break;
default:
[self setValue:"no-cache" forHTTPHeaderField:"Cache-Control"];
}
[self setValue:"XMLHttpRequest" forHTTPHeaderField:"X-Requested-With"];
}
+109
View File
@@ -0,0 +1,109 @@
/*
* CPUserNotification.j
* Foundation
*
* Created by Alexandre Wilhelm.
* Copyright 2015, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPAttributedString.j"
@import "CPArray.j"
@import "CPDate.j"
@import "CPDictionary.j"
@import "CPObject.j"
@import "CPTimeZone.j"
// We need something from the AppKit in Foundation ???
@class CPImage
@typedef CPUserNotificationAction
@typedef CPUserNotificationActivationType
/*!
@global CPUserNotificationActivationType
@group CPUserNotificationActivationType
The user did not interact with the notification alert.
*/
CPUserNotificationActivationTypeNone = 0;
/*!
@global CPUserNotificationActivationType
@group CPUserNotificationActivationType
The user clicked on the contents of the notification alert.
*/
CPUserNotificationActivationTypeContentsClicked = 1;
/*!
@global CPUserNotificationActivationType
@group CPUserNotificationActivationType
The user clicked on the action button of the notification alert.
*/
CPUserNotificationActivationTypeActionButtonClicked = 2;
/*!
@global CPUserNotificationActivationType
@group CPUserNotificationActivationType
The user replied to the notification.
*/
CPUserNotificationActivationTypeReplied = 3,
/*!
@global CPUserNotificationActivationType
@group CPUserNotificationActivationType
The user clicked on the additional action button of the notification alert.
*/
CPUserNotificationActivationTypeAdditionalActionClicked = 4;
/*!
@class CPUserNotification
@ingroup foundation
@brief The CPUserNotification class is used to configure a notification that is scheduled for display by the UserNotificationCenter class.
*/
@implementation CPUserNotification : CPObject
{
BOOL _presented @accessors(getter=isPresented);
BOOL _remote @accessors(getter=isRemote);
CPDate _actualDeliveryDate @accessors(getter=actualDeliveryDate);
CPDate _deliveryDate @accessors(property=deliveryDate);
CPDictionary _userInfo @accessors(property=userInfo);
CPImage _contentImage @accessors(property=contentImage);
CPString _identifier @accessors(property=identifier);
CPString _informativeText @accessors(property=informativeText);
CPString _title @accessors(property=title);
CPTimeInterval _deliveryRepeatInterval @accessors(property=deliveryRepeatInterval);
CPTimeZone _deliveryTimeZone @accessors(property=deliveryTimeZone);
CPUserNotificationActivationType _activationType @accessors(getter=activationType);
}
#pragma mark -
#pragma mark Creating an user notification
- (id)init
{
self = [super init];
if (self)
{
_identifier = [self UID];
}
return self
}
@end
+293
View File
@@ -0,0 +1,293 @@
/*
* CPUserNotificationCenter.j
* Foundation
*
* Created by Alexandre Wilhelm.
* Copyright 2015, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "CPArray.j"
@import "CPObject.j"
@import "CPTimer.j"
@import "CPUserNotification.j"
@protocol CPUserNotificationCenterDelegate <CPObject>
@optional
- (BOOL)userNotificationCenter:(CPUserNotificationCenter)center shouldPresentNotification:(CPUserNotification)notification;
- (void)userNotificationCenter:(CPUserNotificationCenter)center didDeliverNotification:(CPUserNotification)notification;
- (void)userNotificationCenter:(CPUserNotificationCenter)center didActivateNotification:(CPUserNotification)notification;
@end
// Remove compiling warnings
@class Notification
@global CPApp
var CPUserNotificationCenterDelegate_userNotificationCenter_shouldPresentNotification_ = 1 << 0,
CPUserNotificationCenterDelegate_userNotificationCenter_didDeliverNotification_ = 1 << 1,
CPUserNotificationCenterDelegate_userNotificationCenter_didActivateNotification_ = 1 << 2;
var CPUserNotificationDefaultCenter = nil;
/*!
@class CPUserNotificationCenter
@ingroup foundation
@brief The CPUserNotificationCenter class delivers user notifications to the user from applications or helper applications.
*/
@implementation CPUserNotificationCenter : CPObject
{
CPArray _deliveredNotifications @accessors(property=deliveredNotifications);
CPArray _scheduledNotifications @accessors(property=scheduledNotifications);
id <CPUserNotificationCenterDelegate> _delegate;
CPInteger _implementedDelegateMethods;
CPMutableDictionary _timersForUserNotification;
}
#pragma mark -
#pragma mark Creating Default User Notification Center
/*!
Returns the user's notification center
*/
+ (CPNotificationCenter)defaultUserNotificationCenter
{
if (!CPUserNotificationDefaultCenter)
CPUserNotificationDefaultCenter = [[CPUserNotificationCenter alloc] init];
return CPUserNotificationDefaultCenter;
}
- (id)init
{
self = [super init];
if (self)
{
_deliveredNotifications = [];
_scheduledNotifications = [];
_timersForUserNotification = @{};
}
return self;
}
#pragma mark -
#pragma mark Getting and Setting the Delegate
- (void)setDelegate:(id <CPUserNotificationCenterDelegate>)aDelegate
{
if (_delegate === aDelegate)
return;
_delegate = aDelegate;
_implementedDelegateMethods = 0;
if ([_delegate respondsToSelector:@selector(userNotificationCenter:shouldPresentNotification:)])
_implementedDelegateMethods |= CPUserNotificationCenterDelegate_userNotificationCenter_shouldPresentNotification_;
if ([_delegate respondsToSelector:@selector(userNotificationCenter:didDeliverNotification:)])
_implementedDelegateMethods |= CPUserNotificationCenterDelegate_userNotificationCenter_didDeliverNotification_;
if ([_delegate respondsToSelector:@selector(userNotificationCenter:didActivateNotification:)])
_implementedDelegateMethods |= CPUserNotificationCenterDelegate_userNotificationCenter_didActivateNotification_;
}
#pragma mark -
#pragma mark Managing the Scheduled Notification Queue
/*!
Schedules the given user notification
@param anUserNotification the user notification
*/
- (void)scheduleNotification:(CPUserNotification)anUserNotification
{
var scheduledDate = [[anUserNotification deliveryDate] copy];
[scheduledDate _dateWithTimeZone:[anUserNotification deliveryTimeZone]];
var timer = [[CPTimer alloc] initWithFireDate:scheduledDate
interval:[anUserNotification deliveryRepeatInterval]
target:self
selector:@selector(_scheduledUserNotificationTimerDidFire:)
userInfo:anUserNotification
repeats:([anUserNotification deliveryRepeatInterval] ? YES : NO)];
[_scheduledNotifications addObject:anUserNotification];
_timersForUserNotification[[anUserNotification UID]] = timer;
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
}
- (void)_scheduledUserNotificationTimerDidFire:(CPTimer)aTimer
{
[self deliverNotification:[aTimer userInfo]];
}
/*!
Removes the given user notification for the scheduled notifications.
@param anUserNotification the user notification
*/
- (void)removeScheduledNotification:(CPUserNotification)anUserNotification
{
if ([_scheduledNotifications indexOfObject:anUserNotification] != CPNotFound)
{
[_scheduledNotifications removeObject:anUserNotification];
[_timersForUserNotification[[anUserNotification UID]] invalidate];
delete _timersForUserNotification[[anUserNotification UID]];
}
}
#pragma mark -
#pragma mark Managing the Delivered Notifications
/*!
Deliver the given user notification
@param aNotification the user notification
*/
- (void)deliverNotification:(CPUserNotification)aNotification
{
[self _launchUserNotification:aNotification];
}
/*!
Remove a delivered user notification from the user notification center.
@param aNotification the user notification
*/
- (void)removeDeliveredNotification:(CPUserNotification)aNotification
{
[_deliveredNotifications removeObject:aNotification];
}
/*!
Remove all delivered user notifications from the user notification center.
*/
- (void)removeAllDeliveredNotifications
{
[_deliveredNotifications removeAllObjects];
}
#pragma mark -
#pragma mark Permission Utilities
- (void)_askPermissionForUserNotification:(CPUserNotification)anUserNotification
{
Notification.requestPermission(function (permission) {
if (permission == "granted")
// We need to relaunch the notification if the permission are granted
[self _launchUserNotification:anUserNotification];
});
}
#pragma mark -
#pragma mark Notification Utilities
- (void)_launchUserNotification:(CPUserNotification)anUserNotification
{
// If the browser version is unsupported, remain silent.
if (!window || !'Notification' in window)
return;
if (Notification.permission === 'default')
[self _askPermissionForUserNotification:anUserNotification];
if (Notification.permission === 'granted')
{
if (([self _delegateRespondsToShouldPresentNotification] && [self _sendDelegateShouldPresentNotification:anUserNotification])
|| ![CPApp isActive])
{
var notification = new Notification(
[anUserNotification title],
{
'body': [anUserNotification informativeText],
'icon': [[anUserNotification contentImage] filename],
// ...prevent duplicate notifications
'tag' : [anUserNotification identifier]
}
);
anUserNotification._presented = YES;
notification.onclick = function () {
anUserNotification._activationType = CPUserNotificationActivationTypeContentsClicked;
[self _sendDelegateDidActivateNotification:anUserNotification];
// Remove the notification from Notification Center when clicked.
this.close();
};
// Callback function when the notification is closed.
notification.onclose = function () {
};
}
else
{
anUserNotification._presented = NO;
}
anUserNotification._activationType = CPUserNotificationActivationTypeNone;
anUserNotification._actualDeliveryDate = [CPDate date];
[_deliveredNotifications addObject:anUserNotification];
if (![anUserNotification deliveryRepeatInterval])
[self removeScheduledNotification:anUserNotification];
[self _sendDelegateDidDeliverNotification:anUserNotification];
}
}
@end
@implementation CPUserNotificationCenter (CPUserNotificationCenterDelegate)
- (BOOL)_delegateRespondsToShouldPresentNotification
{
return _implementedDelegateMethods & CPUserNotificationCenterDelegate_userNotificationCenter_shouldPresentNotification_;
}
- (BOOL)_sendDelegateShouldPresentNotification:(CPUserNotification)aNotification
{
return [_delegate userNotificationCenter:self shouldPresentNotification:aNotification];
}
- (void)_sendDelegateDidActivateNotification:(CPUserNotification)aNotification
{
if (!(_implementedDelegateMethods & CPUserNotificationCenterDelegate_userNotificationCenter_didActivateNotification_))
return;
[_delegate userNotificationCenter:self didActivateNotification:aNotification];
}
- (void)_sendDelegateDidDeliverNotification:(CPUserNotification)aNotification
{
if (!(_implementedDelegateMethods & CPUserNotificationCenterDelegate_userNotificationCenter_didDeliverNotification_))
return;
[_delegate userNotificationCenter:self didDeliverNotification:aNotification];
}
@end
+2
View File
@@ -78,6 +78,8 @@
@import "CPURLRequest.j"
@import "CPURLResponse.j"
@import "CPUserDefaults.j"
@import "CPUserNotification.j"
@import "CPUserNotificationCenter.j"
@import "CPUserSessionManager.j"
@import "CPValue.j"
@import "CPValueTransformer.j"
+14 -5
View File
@@ -128,12 +128,21 @@ function generateDocs(/* boolean */ noFrame)
// If the Doxygen application is installed on Mac OS X, use that
if (!doxygen && executableExists("mdfind"))
{
var p = OS.popen(["mdfind", "kMDItemContentType == 'com.apple.application-bundle' && kMDItemCFBundleIdentifier == 'org.doxygen'"]);
if (p.wait() === 0)
try
{
var doxygenApps = p.stdout.read().split("\n");
if (doxygenApps[0])
doxygen = FILE.join(doxygenApps[0], "Contents/Resources/doxygen");
var p = OS.popen(["mdfind", "kMDItemContentType == 'com.apple.application-bundle' && kMDItemCFBundleIdentifier == 'org.doxygen'"]);
if (p.wait() === 0)
{
var doxygenApps = p.stdout.read().split("\n");
if (doxygenApps[0])
doxygen = FILE.join(doxygenApps[0], "Contents/Resources/doxygen");
}
}
finally
{
p.stdin.close();
p.stdout.close();
p.stderr.close();
}
}
+47 -9
View File
@@ -112,7 +112,13 @@ GLOBAL(CFHTTPRequest) = function()
determineAndDispatchHTTPRequestEvents(self);
};
this._timeoutHandler = function()
{
dispatchTimeoutHTTPRequestEvents(self);
};
this._nativeRequest.onreadystatechange = this._stateChangeHandler;
this._nativeRequest.ontimeout = this._timeoutHandler;
if (CFHTTPRequest.AuthenticationDelegate !== nil)
this._eventDispatcher.addEventListener("HTTP403", function()
@@ -209,6 +215,16 @@ CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader)
return this._nativeRequest.getResponseHeader(aHeader);
};
CFHTTPRequest.prototype.setTimeout = function(/*int*/ aTimeout)
{
this._nativeRequest.timeout = aTimeout;
};
CFHTTPRequest.prototype.getTimeout = function(/*int*/ aTimeout)
{
return this._nativeRequest.timeout;
};
CFHTTPRequest.prototype.getAllResponseHeaders = function()
{
return this._nativeRequest.getAllResponseHeaders();
@@ -235,7 +251,10 @@ CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
if (!this._isOpen)
{
delete this._nativeRequest.onreadystatechange;
delete this._nativeRequest.ontimeout;
this._nativeRequest.open(this._method, this._URL, this._async, this._user, this._password);
this._nativeRequest.ontimeout = this._timeoutHandler;
this._nativeRequest.onreadystatechange = this._stateChangeHandler;
}
@@ -277,25 +296,35 @@ CFHTTPRequest.prototype.removeEventListener = function(/*String*/ anEventName, /
this._eventDispatcher.removeEventListener(anEventName, anEventListener);
};
CFHTTPRequest.prototype.setWithCredentials = function(/*Boolean*/ willSendWithCredentials)
CFHTTPRequest.prototype.setWithCredentials = function(/*Boolean*/ willSendWithCredentials)
{
this._nativeRequest.withCredentials = willSendWithCredentials;
};
CFHTTPRequest.prototype.withCredentials = function()
CFHTTPRequest.prototype.withCredentials = function()
{
return this._nativeRequest.withCredentials;
};
CFHTTPRequest.prototype.isTimeoutRequest = function()
{
// Can we consider that as a timeout ?
return !this.success() && !this._nativeRequest.response && !this._nativeRequest.responseText && !this._nativeRequest.responseType && !this._nativeRequest.responseURL && !this._nativeRequest.responseXML;
};
function dispatchTimeoutHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
{
aRequest._eventDispatcher.dispatchEvent({ type:"timeout", request:aRequest});
}
function determineAndDispatchHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
{
var eventDispatcher = aRequest._eventDispatcher;
var eventDispatcher = aRequest._eventDispatcher,
nativeRequest = aRequest._nativeRequest,
readyStates = ["uninitialized", "loading", "loaded", "interactive", "complete"];
eventDispatcher.dispatchEvent({ type:"readystatechange", request:aRequest});
var nativeRequest = aRequest._nativeRequest,
readyStates = ["uninitialized", "loading", "loaded", "interactive", "complete"];
if (readyStates[aRequest.readyState()] === "complete")
{
var status = "HTTP" + aRequest.status();
@@ -323,12 +352,21 @@ function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure, onprogress)
var aFilePath = aURL.toString().substring(5),
OS = require("os"),
gccFlags = require("objective-j").currentCompilerFlags(),
gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
chunk,
fileContents = "";
while (chunk = gcc.stdout.read())
fileContents += chunk;
try
{
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" });
while (chunk = gcc.stdout.read())
fileContents += chunk;
}
finally
{
gcc.stdin.close();
gcc.stdout.close();
gcc.stderr.close();
}
if (fileContents.length > 0)
{
+39 -17
View File
@@ -94,6 +94,7 @@ exports.run = function(args)
print(" -I, --objj-include-paths include a specific framework paths")
print(" -h, --help print this help");
print(" -m, --multifiles launch objj on several files")
print(" -x, --xml specify the output format in xml.")
return;
}
@@ -101,45 +102,57 @@ exports.run = function(args)
{
switch (argv[0])
{
case "--objj-include-paths":
case "-I":
argv.shift();
OBJJ_INCLUDE_PATHS.unshift.apply(OBJJ_INCLUDE_PATHS, argv.shift().split(":"));
break;
case "--multifiles":
case "-m":
argv.shift();
multipleFiles = true;
break
case "-x":
case "--xml":
argv.shift();
exports.outputFormatInXML = true;
break;
}
}
}
if (argv && argv.length > 0)
{
var endCommand = false;
var endCommand = false,
errors = [];
while (argv.length > 0)
{
var arg0 = argv.shift();
var mainFilePath = FILE.canonical(arg0);
var arg0 = argv.shift(),
mainFilePath = FILE.canonical(arg0);
if (multipleFiles)
{
// This is needed to process every files passed in args
// Otherwise it would stop when an error is raised or we would like to objj the other given files
try
{
exports.make_narwhal_factory(mainFilePath)(require, { }, module, system, print);
}
catch(e)
{
print("\n" + e);
}
}
else
try
{
exports.make_narwhal_factory(mainFilePath)(require, { }, module, system, print);
}
catch(e)
{
if (exports.outputFormatInXML)
{
var dict = new CFMutableDictionary();
dict.addValueForKey('line', e.line ? e.line : 0);
dict.addValueForKey('sourcePath', e.path ? e.path : mainFilePath);
dict.addValueForKey('message', e.message);
errors.push(dict);
}
else
{
errors.push("\n" + e);
}
}
if (typeof main === "function")
{
@@ -157,6 +170,14 @@ exports.run = function(args)
ObjectiveJ.FileExecutable.resetFileExecutables();
objj_resetRegisterClasses();
}
if (errors.length)
{
if (exports.outputFormatInXML)
throw CFPropertyListCreateXMLData(errors, kCFPropertyListXMLFormat_v1_0).rawString();
else
throw errors;
}
}
else
{
@@ -229,6 +250,7 @@ function getPackage() {
exports.version = function() { return getPackage()["version"]; }
exports.revision = function() { return getPackage()["cappuccino-revision"]; }
exports.timestamp = function() { return new Date(getPackage()["cappuccino-timestamp"]); }
exports.outputFormatInXML = false;
exports.fullVersionString = function() {
return sprintf("objective-j %s (%04d-%02d-%02d %s)",
@@ -46,18 +46,39 @@ function compileWithResolvedFlags(aFilePath, objjcFlags, gccFlags, asPlainJavasc
if (!shouldObjjPreprocess)
{
if (OS.popen("which gcc").stdout.read().length === 0)
fileContents = FILE.read(aFilePath, { charset:"UTF-8" });
else
try
{
// GCC preprocess the file.
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags.join(" ") : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
chunk = "";
var p = OS.popen("which gcc");
while (chunk = gcc.stdout.read())
fileContents += chunk;
if (p.stdout.read().length === 0)
{
fileContents = FILE.read(aFilePath, { charset:"UTF-8" });
}
else
{
try
{
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags.join(" ") : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" }),
chunk = "";
while (chunk = gcc.stdout.read())
fileContents += chunk;
}
finally
{
gcc.stdin.close();
gcc.stdout.close();
gcc.stderr.close();
}
}
}
finally
{
p.stdin.close();
p.stdout.close();
p.stderr.close();
}
return fileContents;
}
@@ -22,7 +22,6 @@
var FILE = require("file");
var BUNDLE_TASK = require("objective-j/jake/bundletask");
exports.BundleTask = BUNDLE_TASK.BundleTask;
+15 -6
View File
@@ -40,8 +40,8 @@ $BROWSER_FILES = new FileList($BROWSER_FILE).include($OBJECTIVEJ_FILES);
filedir($BUILD_BROWSER_FILE, $BROWSER_FILES, function(aTask)
{
gcc($BROWSER_FILE,
$BUILD_BROWSER_FILE,
gcc($BROWSER_FILE,
$BUILD_BROWSER_FILE,
environmentFlags("Browser", "ObjJ").concat($INCLUDE_FLAGS, $DEBUG_FLAGS), $CONFIGURATION !== "Debug");
});
@@ -119,11 +119,20 @@ function gcc(inputFilePath, outputFilePath, flags, compress)
stream.print("Building... \0green(" + outputFilePath +"\0)");
// GCC preprocess the file.
var cmd = ["gcc", "-E", "-x", "c", "-P"].concat(flags, inputFilePath).join(" ");
var gcc = OS.popen(cmd, { charset:"UTF-8" });
var cmd = ["gcc", "-E", "-x", "c", "-P"].concat(flags, inputFilePath).join(" "),
contents = FILE.read("header.txt", { charset : "UTF-8" });
var contents = FILE.read("header.txt", { charset : "UTF-8" });
contents += gcc.stdout.read();
try
{
var gcc = OS.popen(cmd, { charset:"UTF-8" });
contents += gcc.stdout.read();
}
finally
{
gcc.stdin.close();
gcc.stdout.close();
gcc.stderr.close();
}
if (FILE.extension(inputFilePath) === ".js" && compress)
contents = compressor(contents);
+42 -5
View File
@@ -394,9 +394,22 @@ var ObjJAcornCompiler = function(/*String*/ aString, /*CFURL*/ aURL, /*unsigned*
#ifdef BROWSER
console.log(message);
#else
print(message);
if (exports.outputFormatInXML)
{
var dict = new CFMutableDictionary();
dict.addValueForKey('line', e.line);
dict.addValueForKey('sourcePath', this.URL.path());
dict.addValueForKey('message', message);
print(CFPropertyListCreateXMLData([dict], kCFPropertyListXMLFormat_v1_0).rawString());
}
else
{
print(message);
}
#endif
}
throw e;
}
@@ -434,6 +447,8 @@ exports.ObjJAcornCompiler.compileFileDependencies = function(/*String*/ aString,
ObjJAcornCompiler.prototype.compilePass2 = function()
{
var warnings = [];
ObjJAcornCompiler.currentCompileFile = this.URL;
this.pass = 2;
this.jsBuffer = new StringBuffer();
@@ -442,14 +457,32 @@ ObjJAcornCompiler.prototype.compilePass2 = function()
compile(this.tokens, new Scope(null ,{ compiler: this }), pass2);
for (var i = 0; i < this.warnings.length; i++)
{
var message = this.prettifyMessage(this.warnings[i], "WARNING");
var warning = this.warnings[i],
type = "WARNING";
var message = this.prettifyMessage(warning, type);
#ifdef BROWSER
console.log(message);
#else
print(message);
if (exports.outputFormatInXML)
{
var dict = new CFMutableDictionary();
dict.addValueForKey('line', warning.line)
dict.addValueForKey('sourcePath', this.URL.path())
dict.addValueForKey('message', message)
warnings.push(dict);
}
else
{
print(message);
}
#endif
}
if (warnings.length && exports.outputFormatInXML)
print(CFPropertyListCreateXMLData(warnings, kCFPropertyListXMLFormat_v1_0).rawString());
//print(this.URL + ": " + this.jsBuffer.toString());
return this.jsBuffer.toString();
}
@@ -660,9 +693,13 @@ ObjJAcornCompiler.prototype.prettifyMessage = function(/* Message */ aMessage, /
ObjJAcornCompiler.prototype.error_message = function(errorMessage, node)
{
var pos = exports.acorn.getLineInfo(this.source, node.start),
syntaxError = {message: errorMessage, line: pos.line, column: pos.column, lineStart: pos.lineStart, lineEnd: pos.lineEnd};
syntaxErrorData = {message: errorMessage, line: pos.line, column: pos.column, lineStart: pos.lineStart, lineEnd: pos.lineEnd},
syntaxError = new SyntaxError(this.prettifyMessage(syntaxErrorData, "ERROR"));
return new SyntaxError(this.prettifyMessage(syntaxError, "ERROR"));
syntaxError.line = pos.line;
syntaxError.path = this.URL.path();
return syntaxError;
}
ObjJAcornCompiler.prototype.pushImport = function(url)
+3 -1
View File
@@ -1,3 +1,5 @@
[![Build Status](https://travis-ci.org/cappuccino/cappuccino.svg?branch=master)](https://travis-ci.org/cappuccino/cappuccino)
Welcome to Cappuccino!
======================
@@ -71,7 +73,7 @@ If you need help with Cappuccino, you can get help from the following sources:
- Mailing Lists:
- [Objective-J](http://groups.google.com/group/objectivej)
- [Objective-J Developers](http://groups.google.com/group/objectivej-dev)
- IRC: irc://irc.freenode.net#cappuccino
- [Gitter] (https://gitter.im/cappuccino/cappuccino)
If you discover any bugs, please file a ticket at:
+9 -5
View File
@@ -1,8 +1,6 @@
@import <AppKit/CPApplication.j>
@import <AppKit/CPAnimation.j>
[CPApplication sharedApplication];
@implementation CPAnimation (TestMethods)
{
}
@@ -18,11 +16,17 @@
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
- (void)testScheduleTimerWithIntervalBasedOnDefaultFrameRate
{
var animation = [[CPAnimation alloc] initWithDuration:0.1 animationCurve:CPAnimationLinear];
[animation startAnimation];
[self assert:1.0/60.0 equals:[[animation timer] timeInterval]];
}
@@ -31,7 +35,7 @@
var animation = [[CPAnimation alloc] initWithDuration:0.1 animationCurve:CPAnimationLinear];
[animation setFrameRate:30];
[animation startAnimation];
[self assert:1.0/30.0 equals:[[animation timer] timeInterval]];
}
@@ -40,7 +44,7 @@
var animation = [[CPAnimation alloc] initWithDuration:0.1 animationCurve:CPAnimationLinear];
[animation setFrameRate:0];
[animation startAnimation];
[self assert:0.0001 equals:[[animation timer] timeInterval]];
}
+1 -1
View File
@@ -65,7 +65,7 @@ var globalResults = [];
{
// This sets up the CPApp convenience variable, the unit tests fails
// if this is not done, because the framework internally uses CPApp.
app = [CPApplication sharedApplication];
app = [[CPApplication alloc] init];
// fake the window.location.hash
window.location = {hash: "#var1=1/var2=2"};
@@ -6,6 +6,15 @@ var ELEMENTS = 200,
REPEATS = 25;
@implementation CPArrayControllerPerformance : OJTestCase
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
- (CPArrayController)setupWithElements:(int)aCount
{
+3
View File
@@ -56,6 +56,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
_contentArray = [self makeTestArray];
[self initControllerWithSimpleArray]
}
+3 -3
View File
@@ -1,9 +1,6 @@
@import <Foundation/Foundation.j>
@import <AppKit/AppKit.j>
[CPApplication sharedApplication];
@implementation CPAutosizePerformance : OJTestCase
{
CPInteger NUMBER_OF_VIEWS;
@@ -12,6 +9,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
NUMBER_OF_VIEWS = 50;
RESIZES_COUNT = 250;
}
+3 -1
View File
@@ -2,7 +2,6 @@
@class CPBrowserDelegate
@implementation CPBrowserTest : OJTestCase
{
CPBrowser browser;
@@ -11,6 +10,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
browser = [[CPBrowser alloc] initWithFrame:CGRectMake(0, 0, 500, 300)];
delegate = [CPBrowserDelegate new];
[delegate setEntries:[".1", ".1.1", ".1.2", ".1.2.1", ".1.2.2", ".2", ".3", ".3.1"]];
+3 -3
View File
@@ -1,10 +1,7 @@
@import <AppKit/CPButton.j>
@import <AppKit/CPApplication.j>
@import <AppKit/CPText.j>
[CPApplication sharedApplication];
@implementation CPButtonTest : OJTestCase
{
CPButton button;
@@ -13,6 +10,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
button = [CPButton buttonWithTitle:"hello world"];
wasClicked = NO;
}
+6 -2
View File
@@ -1,11 +1,15 @@
@import <AppKit/CPCheckBox.j>
[CPApplication sharedApplication]
@implementation CPCheckBoxTest : OJTestCase
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
/*!
Verify that CPCheckBox placeholders work, both explicit and default ones.
*/
+3
View File
@@ -9,6 +9,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
_collectionView = [[CPCollectionView alloc] initWithFrame:CGRectMakeZero()];
_globalResults = nil;
}
+6
View File
@@ -4,6 +4,12 @@
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
- (void)testHexStringConversion
{
var colors = ['000000', '0099CC', '7E8EAB', 'FFFFFF'];
+3 -2
View File
@@ -1,8 +1,6 @@
@import <AppKit/CPColorWell.j>
@import <AppKit/CPApplication.j>
[CPApplication sharedApplication];
@implementation CPColorWellTest : OJTestCase
{
CPColorWell colorWell;
@@ -10,6 +8,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
colorWell = [[CPColorWell alloc] initWithFrame:CGRectMakeZero()];
}
+3 -2
View File
@@ -4,8 +4,6 @@
@import "CPNotificationCenterHelper.j"
[CPApplication sharedApplication];
@implementation CPComboBoxTest : OJTestCase
{
CPComboBox comboBox;
@@ -14,6 +12,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
comboBox = [[CPComboBox alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
}
+3
View File
@@ -10,6 +10,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
// set up a dummy DOM element.
DOMElement = {
style: {
+31
View File
@@ -0,0 +1,31 @@
@import <OJUnit/OJTestCase.j>
@import <AppKit/CPDatePicker.j>
@import <AppKit/CPApplication.j>
@import <Foundation/Foundation.j>
@implementation CPDatePickerTest : OJTestCase
{
CPDatePicker datePicker;
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
datePicker = [[CPDatePicker alloc] initWithFrame:CGRectMake(200, 28, 0, 0)];
}
- (void)testCanCreate
{
[self assertTrue:!!datePicker];
}
- (void)testLayoutSubviews
{
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
@end
+2 -2
View File
@@ -7,8 +7,8 @@
- (void)setUp
{
// CPApplication must be initialised for some event handling to work.
[CPApplication sharedApplication];
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
/*!
+3 -2
View File
@@ -1,7 +1,5 @@
@import <AppKit/AppKit.j>
[CPApplication sharedApplication];
@implementation CPFontManagerTest : OJTestCase
{
CPFont fontA;
@@ -14,6 +12,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
fontA = [CPFont systemFontOfSize:8.0];
}
+3
View File
@@ -11,6 +11,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
_systemFont = [CPFont systemFontOfSize:15];
_boldSystemFont = [CPFont boldSystemFontOfSize:15];
+6
View File
@@ -4,6 +4,12 @@
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
- (void)testInitWithContentsOfFile_nil
{
var image = [[CPImage alloc] initWithContentsOfFile:nil];
+9 -2
View File
@@ -3,9 +3,16 @@
@import <AppKit/CPEvent.j>
@import <AppKit/CPButton.j>
[CPApplication sharedApplication];
@implementation CPKeyEquivalentPerformance : OJTestCase
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
- (void)testKeyEquivalentSpeed
{
@@ -20,8 +20,8 @@
- (void)setUp
{
// CPApp must be initialised or action sending will not work.
[CPApplication sharedApplication];
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
track = [Track new];
[track setVolume:5.0];
+6
View File
@@ -21,6 +21,12 @@
CPArrayController arrayController @accessors;
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
- (void)testExposingBindings
{
[BindingTester exposeBinding:@"foo"];
+10 -4
View File
@@ -7,6 +7,12 @@
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
+ (CPLevelIndicator)indicatorWithLowWarning
{
var levelIndicator = [[CPLevelIndicator alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
@@ -44,7 +50,7 @@
[levelIndicator setObjectValue:4];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
[self assert:[CPColor yellowColor] equals:[GET_LEVEL_INDICATOR_SEGMENT(levelIndicator, 0) backgroundColor]];
}
@@ -54,7 +60,7 @@
[levelIndicator setObjectValue:2];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
[self assert:[CPColor redColor] equals:[GET_LEVEL_INDICATOR_SEGMENT(levelIndicator, 0) backgroundColor]];
}
@@ -74,7 +80,7 @@
[levelIndicator setObjectValue:6];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
[self assert:[CPColor yellowColor] equals:[GET_LEVEL_INDICATOR_SEGMENT(levelIndicator, 0) backgroundColor]];
}
@@ -84,7 +90,7 @@
[levelIndicator setObjectValue:8];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
[self assert:[CPColor redColor] equals:[GET_LEVEL_INDICATOR_SEGMENT(levelIndicator, 0) backgroundColor]];
}
@end
+3 -2
View File
@@ -1,10 +1,8 @@
@import <AppKit/CPMenu.j>
@import <AppKit/CPMenuItem.j>
@import <AppKit/CPApplication.j>
@import <AppKit/CPText.j>
[CPApplication sharedApplication]
@implementation CPMenuTest : OJTestCase
{
@@ -21,6 +19,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
// Set up a fairly complete menu to have something to work with.
menu = [[CPMenu alloc] initWithTitle:@"MainMenu"];
@@ -11,6 +11,9 @@ var CPMenuValidatedUserInterfaceItemTestValidatedItems = [];
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
_menuTarget = [[MenuTarget alloc] init];
[[CPApplication sharedApplication] setDelegate:_menuTarget];
+3 -1
View File
@@ -2,7 +2,6 @@
@class TestOutlineDataSource
@implementation CPOutlineViewTest : OJTestCase
{
CPOutlineView outlineView;
@@ -12,6 +11,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
outlineView = [[CPOutlineView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
tableColumn = [[CPTableColumn alloc] initWithIdentifier:@"Foo"];
+6
View File
@@ -6,6 +6,12 @@
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
- (void)testSetString_forType_
{
var pboard = [CPPasteboard generalPasteboard];
+3
View File
@@ -11,6 +11,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
button = [CPPopUpButton new];
}
+3
View File
@@ -8,6 +8,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
_editor = [[CPPredicateEditor alloc] initWithFrame:CGRectMakeZero()];
}
+3 -2
View File
@@ -4,8 +4,6 @@
@import <AppKit/CPPlatformWindow+DOMKeys.j>
[CPApplication sharedApplication]
@implementation CPResponderTest : OJTestCase
{
CPWindow theWindow;
@@ -14,6 +12,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
responder = [TestResponder new];
responder.doCommandCalls = [];
}
+44 -1
View File
@@ -2,12 +2,17 @@
@import "CPNotificationCenterHelper.j"
[CPApplication sharedApplication];
@implementation CPScrollViewTest : OJTestCase
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
/*!
Test that scroll views don't generate bad layouts when very small.
*/
@@ -334,11 +339,49 @@
[self assert:[CPNotificationCenterHelper registeredNotificationsForObserver:scrollView] equals:[] message:@"Notications registered for the scrollView in the notification center are wrong"];
}
- (void)testDocumentVisibleRect
{
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
styleMask:CPWindowNotSizable],
windowView = [theWindow contentView],
aScrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
aDocumentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[CPScrollView setGlobalScrollerStyle:CPScrollerStyleOverlay];
[aScrollView setDocumentView:aDocumentView];
[windowView addSubview:aScrollView];
[self assertRect:CGRectMake(0, 0, 100, 100) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView"];
[aDocumentView setScaleSize:CGSizeMake(0.5, 0.5)];
[self assertRect:CGRectMake(0, 0, 200, 200) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView after scaling"];
[aDocumentView setScaleSize:CGSizeMake(1, 1)];
[aDocumentView scrollRectToVisible:CGRectMake(120, 120, 20, 20)];
[self assertRect:CGRectMake(40, 40, 100, 100) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView"];
[aDocumentView setScaleSize:CGSizeMake(0.5, 0.5)];
[self assertRect:CGRectMake(80, 80, 200, 200) equals:[aScrollView documentVisibleRect] message:@"documentVisibleRect is wrong in CPScrollView"];
}
- (void)assertPoint:(CGPoint)expected equals:(CGPoint)actual message:(CPString)message
{
[self assert:expected.x equals:actual.x message:@"X: " + message];
[self assert:expected.y equals:actual.y message:@"Y: " + message];
}
- (void)assertSize:(CGSize)expected equals:(CGSize)actual message:(CPString)message
{
[self assert:expected.width equals:actual.width message:@"Width: " + message];
[self assert:expected.height equals:actual.height message:@"Height: " + message];
}
- (void)assertRect:(CGRect)expected equals:(CGRect)actual message:(CPString)message
{
[self assertPoint:expected.origin equals:actual.origin message:message]
[self assertSize:expected.size equals:actual.size message:message]
}
@end
+3
View File
@@ -7,6 +7,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
_searchField = [[CPSearchField alloc] initWithFrame:CGRectMakeZero()];
}
+3
View File
@@ -8,6 +8,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
_segmentedControl = [[CPSegmentedControl alloc] initWithFrame:CGRectMakeZero()];
[_segmentedControl setSegmentCount:3];
}
+6
View File
@@ -4,6 +4,12 @@
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
- (void)testIsContinuous
{
// While normally testing simple instance variables is a waste of time,
+3 -3
View File
@@ -1,9 +1,6 @@
@import <AppKit/CPApplication.j>
@import <AppKit/CPSplitView.j>
[CPApplication sharedApplication];
@implementation CPSplitViewTest : OJTestCase
{
CPSplitView splitView;
@@ -13,6 +10,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
splitView = [[CPSplitView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
viewA = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
viewB = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
+3 -2
View File
@@ -1,8 +1,6 @@
@import <AppKit/CPStepper.j>
@import <AppKit/CPApplication.j>
[CPApplication sharedApplication]
@implementation CPStepperTest : OJTestCase
{
CPStepper stepper;
@@ -10,6 +8,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
stepper = [CPStepper stepper];
[stepper setValueWraps:NO];
}
+3 -2
View File
@@ -1,8 +1,6 @@
@import <Foundation/Foundation.j>
@import <AppKit/AppKit.j>
@implementation CPTabView (TEST)
- (CPSegmentedControl)tabs
@@ -27,6 +25,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
_tabView = [[CPTabView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)];
_tabItem1 = [[CPTabViewItem alloc] initWithIdentifier:@"id1"];
+3 -2
View File
@@ -1,7 +1,5 @@
@import <AppKit/AppKit.j>
[CPApplication sharedApplication];
@implementation CPTableViewReloadDataTest : OJTestCase
{
CPWindow theWindow;
@@ -11,6 +9,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
tableContent = [];
// setup a reasonable table
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
+3 -2
View File
@@ -1,7 +1,5 @@
@import <AppKit/AppKit.j>
[CPApplication sharedApplication];
@implementation CPTableViewTableColumnTest : OJTestCase
{
CPWindow theWindow;
@@ -10,6 +8,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
// setup a reasonable table
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0)
styleMask:CPWindowNotSizable];
+3 -2
View File
@@ -2,8 +2,6 @@
@import "CPNotificationCenterHelper.j"
[CPApplication sharedApplication];
@implementation CPTableViewTest : OJTestCase
{
CPWindow theWindow;
@@ -17,6 +15,9 @@
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
// setup a reasonable table
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(0.0, 0.0, 1024.0, 768.0) styleMask:CPWindowNotSizable];
+6 -1
View File
@@ -1,11 +1,16 @@
@import <AppKit/CPTextField.j>
[CPApplication sharedApplication]
@implementation CPTextFieldTest : OJTestCase
{
}
- (void)setUp
{
// This will init the global var CPApp which are used internally in the AppKit
[[CPApplication alloc] init];
}
/*!
Detect regressions with JS object theme attribute encoding in subclasses.
Loaded 100 of 326 files, more files were not shown because too many files have changed in this diff. Show more