Merge remote-tracking branch 'upstream/master' into CPTabView

This commit is contained in:
cacaodev
2015-09-14 18:57:12 +02:00
340 changed files with 13774 additions and 10535 deletions
+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
+47 -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
@@ -445,6 +455,9 @@ var CPMainCibFile = @"CPMainCibFile",
- (void)activateIgnoringOtherApps:(BOOL)shouldIgnoreOtherApps
{
if (_isActive)
return;
[self _willBecomeActive];
[CPPlatform activateIgnoringOtherApps:shouldIgnoreOtherApps];
@@ -455,6 +468,9 @@ var CPMainCibFile = @"CPMainCibFile",
- (void)deactivate
{
if (!_isActive)
return;
[self _willResignActive];
[CPPlatform deactivate];
@@ -480,6 +496,15 @@ var CPMainCibFile = @"CPMainCibFile",
- (void)run
{
[self finishLaunching];
[self sendEvent:[CPEvent otherEventWithType:CPAppKitDefined
location:CGPointMakeZero()
modifierFlags:0
timestamp:[CPEvent currentTimestamp]
windowNumber:[_keyWindow windowNumber]
context:nil
subtype:nil
data1:nil
data2:nil]];
}
// Managing the Event Loop
@@ -1195,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;
+11 -2
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;
@@ -843,7 +843,16 @@ var CPComboBoxTextSubview = @"text",
// In FireFox this needs to be done in setTimeout, otherwise there is no caret
// We have to save the input element now, when we lose focus it will change.
var element = [self _inputElement];
window.setTimeout(function() { element.focus(); }, 0);
window.setTimeout(function() {
// This will prevent to jump to the focused element
var previousScrollingOrigin = [self _scrollToVisibleRectAndReturnPreviousOrigin];
element.focus();
[self _restorePreviousScrollingOrigin:previousScrollingOrigin];
}, 0);
#endif
return NO;
+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
View File
@@ -236,6 +236,7 @@ var _CPEventPeriodicEventPeriod = 0,
_subtype = aSubtype;
_data1 = aData1;
_data2 = aData2;
_windowNumber = aWindowNumber;
}
return self;
+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;
+10 -9
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
@@ -74,8 +73,8 @@ var RECENT_SEARCH_PREFIX = @" ";
@"image-find": [CPNull null],
@"image-cancel": [CPNull null],
@"image-cancel-pressed": [CPNull null],
@"image-search-left-margin" : 0,
@"image-cancel-right-margin" : 0
@"image-search-inset" : CGInsetMake(0, 0, 0, 5),
@"image-cancel-inset" : CGInsetMake(0, 5, 0, 0)
};
}
@@ -268,9 +267,10 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (CGRect)searchButtonRectForBounds:(CGRect)rect
{
var size = [[self currentValueForThemeAttribute:@"image-search"] size] || CGSizeMakeZero();
var size = [[self currentValueForThemeAttribute:@"image-search"] size] || CGSizeMakeZero(),
inset = [self currentValueForThemeAttribute:@"image-search-inset"];
return CGRectMake([self currentValueForThemeAttribute:@"image-search-left-margin"], (CGRectGetHeight(rect) - size.height) / 2, size.width, size.height);
return CGRectMake(inset.left - inset.right, inset.top - inset.bottom + (CGRectGetHeight(rect) - size.height) / 2, size.width, size.height);
}
/*!
@@ -280,9 +280,10 @@ var RECENT_SEARCH_PREFIX = @" ";
*/
- (CGRect)cancelButtonRectForBounds:(CGRect)rect
{
var size = [[self currentValueForThemeAttribute:@"image-cancel"] size] || CGSizeMakeZero();
var size = [[self currentValueForThemeAttribute:@"image-cancel"] size] || CGSizeMakeZero(),
inset = [self currentValueForThemeAttribute:@"image-cancel-inset"];
return CGRectMake(CGRectGetWidth(rect) - size.width - [self currentValueForThemeAttribute:@"image-cancel-right-margin"], (CGRectGetHeight(rect) - size.width) / 2, size.height, size.height);
return CGRectMake(CGRectGetWidth(rect) - size.width + inset.left - inset.right, inset.top - inset.bottom + (CGRectGetHeight(rect) - size.width) / 2, size.height, size.height);
}
// Managing Menu Templates
+18 -18
View File
@@ -516,7 +516,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);
@@ -745,29 +745,23 @@ CPSegmentSwitchTrackingMomentary = 2;
if (aSegment < 0 || (segmentCount > 0 && aSegment >= segmentCount))
return;
// Invalidate frames for segments on the right. They will be lazily computed by -frameForSegment:.
for (var i = aSegment; i < segmentCount; i++)
[_segments[i] setFrame:CGRectMakeZero()];
var width = 0;
[self setFrameSize:[self intrinsicContentSize]];
if (segmentCount > 0)
{
// Invalidate frames for segments on the right. They will be lazily computed by -frameForSegment:.
for (var i = aSegment; i < segmentCount; i++)
[_segments[i] setFrame:CGRectMakeZero()];
width = CGRectGetMaxX([self frameForSegment:(segmentCount - 1)]);
}
[self setFrameSize:CGSizeMake(width, CGRectGetHeight([self frame]))];
[self setNeedsLayout];
[self setNeedsDisplay:YES];
}
/*! @ignore */
- (CGSize)intrinsicContentSize
{
// frameForSegment is recursively called backwards. All previously invalidated frames will be recomputed.
var segmentCount = [self segmentCount],
width = 0;
if (segmentCount > 0)
width = CGRectGetMaxX([self frameForSegment:(segmentCount - 1)]);
return CGSizeMake(width, [self valueForThemeAttribute:@"min-size"].height);
}
/*!
Returns the bounding rectangle for the specified segment.
@param aSegment the segment to get the rectangle for
@@ -819,6 +813,12 @@ CPSegmentSwitchTrackingMomentary = 2;
return CGRectMake(left + contentInset.left, contentInset.top, width - contentInset.left - contentInset.right, height - contentInset.top - contentInset.bottom);
}
- (CGSize)_minimumFrameSize
{
// The current width is always the minimum width.
return CGSizeMake(CGRectGetWidth([self frame]), [self currentValueForThemeAttribute:@"min-size"].height);
}
/*!
Returns the segment that is hit by the specified point.
@param aPoint the point to test for a segment hit
+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
@@ -765,6 +765,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.
+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;
+92 -6
View File
@@ -28,12 +28,12 @@
@import "_CPImageAndTextView.j"
@class CPPasteboard
@class CPScrollView
@global CPApp
@global CPStringPboardType
@global CPCursor
@protocol CPTextFieldDelegate <CPControlTextEditingDelegate>
@end
@@ -65,7 +65,8 @@ var CPTextFieldDOMCurrentElement = nil,
CPTextFieldCachedSelectStartFunction = nil,
CPTextFieldCachedDragFunction = nil,
CPTextFieldBlurHandler = nil,
CPTextFieldInputFunction = nil;
CPTextFieldInputFunction = nil,
CPTexFieldCurrentCSSSelectableField = nil;
var CPSecureTextFieldCharacter = "\u2022";
@@ -88,7 +89,12 @@ function CPTextFieldBlurFunction(anEvent, owner, domElement, inputElement, resig
{
window.setTimeout(function()
{
// This will prevent to jump to the focused element
var previousScrollingOrigin = [owner _scrollToVisibleRectAndReturnPreviousOrigin];
inputElement.focus();
[owner _restorePreviousScrollingOrigin:previousScrollingOrigin];
}, 0.0);
}
}
@@ -370,7 +376,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
_sendActionOn = CPKeyUpMask | CPKeyDownMask;
[self setValue:CPLeftTextAlignment forThemeAttribute:@"alignment"];
[self setValue:CPNaturalTextAlignment forThemeAttribute:@"alignment"];
}
return self;
@@ -643,6 +649,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
_stringValue = [self stringValue];
#if PLATFORM(DOM)
[self _setCSSStyleForInputElement];
@@ -672,8 +679,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (CPTextFieldInputOwner !== self)
return;
// This will prevent to jump to the focused element
var previousScrollingOrigin = [self _scrollToVisibleRectAndReturnPreviousOrigin];
element.focus();
[self _restorePreviousScrollingOrigin:previousScrollingOrigin];
// Select the text if the textfield became first responder through keyboard interaction
if (!_willBecomeFirstResponderByClick)
[self _selectText:self immediately:YES];
@@ -688,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
@@ -741,6 +768,10 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
element.style.textAlign = "right";
break;
case CPNaturalTextAlignment:
element.style.textAlign = "";
break;
default:
element.style.textAlign = "left";
}
@@ -783,7 +814,13 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// even if the value has not changed.
if ([self _valueIsValid:newValue] === NO)
{
// This will prevent to jump to the focused element
var previousScrollingOrigin = [self _scrollToVisibleRectAndReturnPreviousOrigin];
element.focus();
[self _restorePreviousScrollingOrigin:previousScrollingOrigin];
return NO;
}
}
@@ -792,7 +829,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
// When we are no longer the first responder we don't worry about the key status of our window anymore.
[self _setObserveWindowKeyNotifications:NO];
[self _resignFirstKeyResponder];
if ([[self window] isKeyWindow])
[self _resignFirstKeyResponder];
_isEditing = NO;
if ([self isEditable])
@@ -970,6 +1008,7 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
}
else if ([self isSelectable])
{
[self _setEnableCSSSelection:YES];
if (document.attachEvent)
{
CPTextFieldCachedSelectStartFunction = [[self window] platformWindow]._DOMBodyElement.onselectstart;
@@ -1011,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]))
@@ -1950,17 +1997,55 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder");
if (!wind)
return NO;
var scrollView = [self enclosingScrollView],
previousContentViewBoundsOrigin;
// Here we scroll to the textField, otherwise the textField could not be in the usable platformRect
var previousScrollingOrigin = [self _scrollToVisibleRectAndReturnPreviousOrigin];
var frame = [self convertRectToBase:[self contentRectForBounds:[self bounds]]],
usableRect = [[wind platformWindow] usableContentFrame];
frame.origin = [wind convertBaseToGlobal:frame.origin];
// Here we restore the the previous scrolling posiition
[self _restorePreviousScrollingOrigin:previousScrollingOrigin];
return (CGRectGetMinX(frame) >= CGRectGetMinX(usableRect) &&
CGRectGetMaxX(frame) <= CGRectGetMaxX(usableRect) &&
CGRectGetMinY(frame) >= CGRectGetMinY(usableRect) &&
CGRectGetMaxY(frame) <= CGRectGetMaxY(usableRect));
}
/*!
@ignore
*/
- (CGPoint)_scrollToVisibleRectAndReturnPreviousOrigin
{
var scrollView = [self enclosingScrollView],
previousContentViewBoundsOrigin;
// Here we scroll to the textField, otherwise the textField could not be in the usable platformRect
if ([scrollView isKindOfClass:[CPScrollView class]])
{
previousContentViewBoundsOrigin = CGPointMakeCopy([[scrollView contentView] boundsOrigin]);
if (![[self superview] scrollRectToVisible:[self frame]])
previousContentViewBoundsOrigin = nil;
}
return previousContentViewBoundsOrigin;
}
/*!
@ignore
*/
- (void)_restorePreviousScrollingOrigin:(CGPoint)scrollingOrigin
{
if (scrollingOrigin)
[[[self enclosingScrollView] contentView] setBoundsOrigin:scrollingOrigin];
}
@end
var secureStringForString = function(aString)
@@ -2082,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];
@@ -2109,4 +2195,4 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey",
[_source setObjectValue:aValue];
}
@end
@end
+6
View File
@@ -457,7 +457,13 @@ CPTokenFieldDeleteButtonType = 1;
window.setTimeout(function()
{
// This will prevent to jump to the focused element
var previousScrollingOrigin = [self _scrollToVisibleRectAndReturnPreviousOrigin];
element.focus();
[self _restorePreviousScrollingOrigin:previousScrollingOrigin];
CPTokenFieldInputOwner = self;
}, 0.0);
+137 -14
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
@@ -2731,18 +2742,47 @@ setBoundsOrigin:
if (CGRectContainsRect(documentViewVisibleRect, rectInDocumentView))
return NO;
var scrollPoint = CGPointMakeCopy(documentViewVisibleRect.origin);
var currentScrollPoint = documentViewVisibleRect.origin,
scrollPoint = CGPointMakeCopy(currentScrollPoint),
rectInDocumentViewMinX = CGRectGetMinX(rectInDocumentView),
documentViewVisibleRectMinX = CGRectGetMinX(documentViewVisibleRect),
doesItFitForWidth = documentViewVisibleRect.size.width >= rectInDocumentView.size.width;
// One of the following has to be true since our current visible rect didn't contain aRect.
if (CGRectGetMinX(rectInDocumentView) < CGRectGetMinX(documentViewVisibleRect))
scrollPoint.x = CGRectGetMinX(rectInDocumentView);
else if (CGRectGetMaxX(rectInDocumentView) > CGRectGetMaxX(documentViewVisibleRect))
scrollPoint.x += CGRectGetMaxX(rectInDocumentView) - CGRectGetMaxX(documentViewVisibleRect);
if (rectInDocumentViewMinX < documentViewVisibleRectMinX && doesItFitForWidth)
// Scroll to left edge of aRect as it is to the left of the visible rect and it fit inside
scrollPoint.x = rectInDocumentViewMinX;
else if (CGRectGetMaxX(rectInDocumentView) > CGRectGetMaxX(documentViewVisibleRect) && doesItFitForWidth)
// Scroll to right edge of aRect as it is to the right of the visible rect and it fit inside
scrollPoint.x = CGRectGetMaxX(rectInDocumentView) - documentViewVisibleRect.size.width;
else if (rectInDocumentViewMinX > documentViewVisibleRectMinX)
// Scroll to left edge of aRect as it is to the right of the visible rect and it doesn't fit inside
scrollPoint.x = rectInDocumentViewMinX;
else if (CGRectGetMaxX(rectInDocumentView) < CGRectGetMaxX(documentViewVisibleRect))
// Scroll to right edge of aRect as it is to the left of the visible rect and it doesn't fit inside
scrollPoint.x = CGRectGetMaxX(rectInDocumentView) - documentViewVisibleRect.size.width;
if (CGRectGetMinY(rectInDocumentView) < CGRectGetMinY(documentViewVisibleRect))
scrollPoint.y = CGRectGetMinY(rectInDocumentView);
else if (CGRectGetMaxY(rectInDocumentView) > CGRectGetMaxY(documentViewVisibleRect))
scrollPoint.y += CGRectGetMaxY(rectInDocumentView) - CGRectGetMaxY(documentViewVisibleRect);
var rectInDocumentViewMinY = CGRectGetMinY(rectInDocumentView),
documentViewVisibleRectMinY = CGRectGetMinY(documentViewVisibleRect),
doesItFitForHeight = documentViewVisibleRect.size.height >= rectInDocumentView.size.height;
if (rectInDocumentViewMinY < documentViewVisibleRectMinY && doesItFitForHeight)
// Scroll to top edge of aRect as it is above the visible rect and it fit inside
scrollPoint.y = rectInDocumentViewMinY;
else if (CGRectGetMaxY(rectInDocumentView) > CGRectGetMaxY(documentViewVisibleRect) && doesItFitForHeight)
// Scroll to bottom edge of aRect as it is below the visible rect and it fit inside
scrollPoint.y = CGRectGetMaxY(rectInDocumentView) - documentViewVisibleRect.size.height;
else if (rectInDocumentViewMinY > documentViewVisibleRectMinY)
// Scroll to top edge of aRect as it is below the visible rect and it doesn't fit inside
scrollPoint.y = rectInDocumentViewMinY;
else if (CGRectGetMaxY(rectInDocumentView) < CGRectGetMaxY(documentViewVisibleRect))
// Scroll to bottom edge of aRect as it is above the visible rect and it doesn't fit inside
scrollPoint.y = CGRectGetMaxY(rectInDocumentView) - documentViewVisibleRect.size.height;
// Don't scroll if aRect contains the whole visible rect as it is already as visible as possible.
// We check this by comparing to new scrollPoint to the current.
if (CGPointEqualToPoint(scrollPoint, currentScrollPoint))
return NO;
[enclosingClipView scrollToPoint:scrollPoint];
@@ -3480,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",
@@ -3502,7 +3621,8 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
CPReuseIdentifierKey = @"CPReuseIdentifierKey",
CPViewScaleKey = @"CPViewScaleKey",
CPViewSizeScaleKey = @"CPViewSizeScaleKey",
CPViewIsScaledKey = @"CPViewIsScaledKey";
CPViewIsScaledKey = @"CPViewIsScaledKey",
CPViewAppearanceKey = @"CPViewAppearanceKey";
@implementation CPView (CPCoding)
@@ -3617,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];
}
@@ -3705,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
+59 -3
View File
@@ -63,22 +63,28 @@
@optional
- (BOOL)windowShouldClose:(CPWindow)aWindow;
- (CGSize)windowWillResize:(CPWindow)sender toSize:(CGSize)aSize;
- (CPUndoManager)windowWillReturnUndoManager:(CPWindow)window;
- (void)windowDidBecomeKey:(CPNotification)aNotification;
- (void)windowDidBecomeMain:(CPNotification)aNotification;
- (void)windowDidDeminiaturize:(CPNotification)notification;
- (void)windowDidEndSheet:(CPNotification)aNotification;
- (void)windowDidMiniaturize:(CPNotification)notification;
- (void)windowDidMove:(CPNotification)aNotification;
- (void)windowDidResignKey:(CPNotification)aNotification;
- (void)windowDidResignMain:(CPNotification)aNotification;
- (void)windowDidResize:(CPNotification)aNotification;
- (void)windowWillMiniaturize:(CPNotification)notification;
- (void)windowWillBeginSheet:(CPNotification)aNotification;
- (void)windowWillClose:(CPWindow)aWindow;
@end
var CPWindowDelegate_windowShouldClose_ = 1 << 1
var CPWindowDelegate_windowShouldClose_ = 1 << 1,
CPWindowDelegate_windowWillReturnUndoManager_ = 1 << 2,
CPWindowDelegate_windowWillClose_ = 1 << 3;
CPWindowDelegate_windowWillClose_ = 1 << 3,
CPWindowDelegate_windowWillResize_toSize_ = 1 << 4;
var CPWindowSaveImage = nil,
@@ -747,6 +753,9 @@ CPTexturedBackgroundWindowMask
size.width = newSize.width;
size.height = newSize.height;
if (!_isAnimating)
size = [self _sendDelegateWindowWillResizeToSize:size];
[_windowView setFrameSize:size];
if (_hasShadow)
@@ -975,6 +984,7 @@ CPTexturedBackgroundWindowMask
[[CPNotificationCenter defaultCenter] removeObserver:self name:_CPPlatformWindowWillCloseNotification object:nil];
[[self contentView] _removeObservers];
_hasBecomeKeyWindow = NO;
}
@@ -1429,6 +1439,9 @@ CPTexturedBackgroundWindowMask
[defaultCenter removeObserver:_delegate name:CPWindowDidResizeNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowWillBeginSheetNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowDidEndSheetNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowDidMiniaturizeNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowDidDeminiaturizeNotification object:self];
[defaultCenter removeObserver:_delegate name:CPWindowWillMiniaturizeNotification object:self];
_delegate = aDelegate;
_implementedDelegateMethods = 0;
@@ -1442,6 +1455,9 @@ CPTexturedBackgroundWindowMask
if ([_delegate respondsToSelector:@selector(windowWillClose:)])
_implementedDelegateMethods |= CPWindowDelegate_windowWillClose_;
if ([_delegate respondsToSelector:@selector(windowWillResize:toSize:)])
_implementedDelegateMethods |= CPWindowDelegate_windowWillResize_toSize_;
if ([_delegate respondsToSelector:@selector(windowDidResignKey:)])
[defaultCenter
addObserver:_delegate
@@ -1497,6 +1513,27 @@ CPTexturedBackgroundWindowMask
selector:@selector(windowDidEndSheet:)
name:CPWindowDidEndSheetNotification
object:self];
if ([_delegate respondsToSelector:@selector(windowDidMiniaturize:)])
[defaultCenter
addObserver:_delegate
selector:@selector(windowDidMiniaturize:)
name:CPWindowDidMiniaturizeNotification
object:self];
if ([_delegate respondsToSelector:@selector(windowWillMiniaturize:)])
[defaultCenter
addObserver:_delegate
selector:@selector(windowWillMiniaturize:)
name:CPWindowWillMiniaturizeNotification
object:self];
if ([_delegate respondsToSelector:@selector(windowDidDeminiaturize:)])
[defaultCenter
addObserver:_delegate
selector:@selector(windowDidDeminiaturize:)
name:CPWindowDidDeminiaturizeNotification
object:self];
}
/*!
@@ -1809,6 +1846,9 @@ CPTexturedBackgroundWindowMask
switch (type)
{
case CPAppKitDefined:
return [CPApp activateIgnoringOtherApps:YES];
case CPFlagsChanged:
return [[self firstResponder] flagsChanged:anEvent];
@@ -2023,6 +2063,7 @@ CPTexturedBackgroundWindowMask
[self _setupFirstResponder];
_hasBecomeKeyWindow = YES;
_platformWindow._currentKeyWindow = self;
[_windowView noteKeyWindowStateChanged];
[_contentView _notifyWindowDidBecomeKey];
@@ -2093,6 +2134,7 @@ CPTexturedBackgroundWindowMask
if (CPApp._keyWindow === self)
CPApp._keyWindow = nil;
_platformWindow._currentKeyWindow = nil;
[_windowView noteKeyWindowStateChanged];
[_contentView _notifyWindowDidResignKey];
@@ -2476,6 +2518,7 @@ CPTexturedBackgroundWindowMask
- (void)becomeMainWindow
{
CPApp._mainWindow = self;
_platformWindow._currentMainWindow = self;
[self _synchronizeSaveMenuWithDocumentSaving];
@@ -2498,6 +2541,7 @@ CPTexturedBackgroundWindowMask
if (CPApp._mainWindow === self)
CPApp._mainWindow = nil;
_platformWindow._currentMainWindow = nil;
[_windowView noteMainWindowStateChanged];
}
@@ -2736,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"];
@@ -3473,6 +3517,18 @@ var keyViewComparator = function(lhs, rhs, context)
[_delegate windowWillClose:self];
}
/*!
@ignore
Call the delegate windowWillResize:toSize:
*/
- (CGSize)_sendDelegateWindowWillResizeToSize:(CGSize)aSize
{
if (!(_implementedDelegateMethods & CPWindowDelegate_windowWillResize_toSize_))
return aSize;
return [_delegate windowWillResize:self toSize:aSize];
}
@end
+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;
+6
View File
@@ -75,6 +75,12 @@ var PrimaryPlatformWindow = NULL;
CPPlatformPasteboard _platformPasteboard;
CPString _overriddenEventType;
CPWindow _currentKeyWindow;
CPWindow _previousKeyWindow;
CPWindow _currentMainWindow;
CPWindow _previousMainWindow;
#endif
}
+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
+118 -2
View File
@@ -127,6 +127,7 @@
@import "CPText.j"
@import "CPWindow_Constants.j"
@class CPApplication
@class CPDragServer
@class _CPToolTip
@@ -202,6 +203,7 @@ var ModifierKeyCodes = [
var resizeTimer = nil;
var PreventScroll = true;
var blurTimer = nil;
_CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotification";
@@ -363,6 +365,7 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
_DOMBodyElement.style["-khtml-user-select"] = "none";
_DOMBodyElement.webkitTouchCallout = "none";
_DOMBodyElement.style[CPBrowserStyleProperty(@"user-select")] = @"none";
[self createDOMElements];
[self _addLayers];
@@ -396,7 +399,15 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
touchEventSelector = @selector(touchEvent:),
touchEventImplementation = class_getMethodImplementation(theClass, touchEventSelector),
touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); };
touchEventCallback = function (anEvent) { touchEventImplementation(self, nil, anEvent); },
onFocusEventSelector = @selector(focusEvent:),
onFocusEventImplementation = class_getMethodImplementation(theClass, onFocusEventSelector),
onFocusEventCallback = function (anEvent) { onFocusEventImplementation(self, nil, anEvent); },
onBlurEventSelector = @selector(blurEvent:),
onBlurEventImplementation = class_getMethodImplementation(theClass, onBlurEventSelector),
onBlurEventCallback = function (anEvent) { onBlurEventImplementation(self, nil, anEvent); };
if (theDocument.addEventListener)
{
@@ -430,10 +441,14 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
_DOMWindow.addEventListener("resize", resizeEventCallback, NO);
_DOMWindow.addEventListener("blur", onBlurEventCallback, NO);
_DOMWindow.addEventListener("focus", onFocusEventCallback, NO);
_DOMWindow.addEventListener("unload", function()
{
_DOMWindow.removeEventListener("unload", arguments.callee, NO);
[self blurEvent:nil];
[self _notifyPlatformWindowWillClose];
[self updateFromNativeContentRect];
[self _removeLayers];
@@ -453,6 +468,9 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
_DOMWindow.removeEventListener("resize", resizeEventCallback, NO);
_DOMWindow.removeEventListener("blur", onBlurEventCallback, NO);
_DOMWindow.removeEventListener("focus", onFocusEventCallback, NO);
//FIXME: does firefox really need a different value?
_DOMWindow.removeEventListener("DOMMouseScroll", scrollEventCallback, NO);
_DOMWindow.removeEventListener("wheel", scrollEventCallback, NO);
@@ -479,6 +497,9 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
_DOMWindow.attachEvent("onresize", resizeEventCallback);
_DOMWindow.attachEvent("onfocus", onFocusEventCallback);
_DOMWindow.attachEvent("onblur", onBlurEventCallback);
_DOMWindow.onmousewheel = scrollEventCallback;
theDocument.onmousewheel = scrollEventCallback;
@@ -489,6 +510,7 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
{
_DOMWindow.detachEvent("unload", arguments.callee);
[self blurEvent:nil];
[self _notifyPlatformWindowWillClose];
[self updateFromNativeContentRect];
[self _removeLayers];
@@ -505,7 +527,11 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
_DOMWindow.detachEvent("onresize", resizeEventCallback);
_DOMWindow.detachEvent("onfocus", onBlurEventCallback);
_DOMWindow.detachEvent("onblur", onFocusEventCallback);
_DOMWindow.onmousewheel = NULL;
theDocument.onmousewheel = NULL;
_DOMBodyElement.ondrag = NULL;
@@ -545,7 +571,7 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
[PlatformWindows addObject:self];
// FIXME: cpSetFrame?
_DOMWindow.document.write('<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"></head><body style="background-color:transparent;"></body></html>');
_DOMWindow.document.write('<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"></head><body style="background-color:transparent; overflow:hidden"></body></html>');
_DOMWindow.document.close();
if (self != [CPPlatformWindow primaryPlatformWindow])
@@ -1031,6 +1057,96 @@ _CPPlatformWindowWillCloseNotification = @"_CPPlatformWindowWillCloseNotificatio
_shouldUpdateContentRect = YES;
}
/*!
@ignore
*/
- (void)blurEvent:(DOMEvent)aDOMEvent
{
if ([CPApp keyWindow] == _currentKeyWindow)
[_currentKeyWindow resignKeyWindow];
if ([CPApp mainWindow] == _currentMainWindow)
[_currentMainWindow resignMainWindow];
_previousKeyWindow = aDOMEvent ? _currentKeyWindow : nil;
_previousMainWindow = aDOMEvent ? _currentMainWindow : nil;
[blurTimer invalidate];
blurTimer = [CPTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(_blurEventTimer:) userInfo:nil repeats:NO];
}
/*!
@ignore
*/
- (void)_blurEventTimer:(CPTimer)aTimer
{
if (![CPApp mainWindow])
[[CPApplication sharedApplication] deactivate];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
/*!
@ignore
*/
- (void)focusEvent:(DOMEvent)aDOMEvent
{
[blurTimer invalidate];
[CPApp activateIgnoringOtherApps:YES];
var keyWindow = _previousKeyWindow;
if (!keyWindow)
keyWindow = [[[_windowLayers objectForKey:[_windowLevels firstObject]] orderedWindows] firstObject];
if (!keyWindow)
return;
[self _makeKeyWindow:keyWindow];
if ([keyWindow isKeyWindow] && ([keyWindow firstResponder] === keyWindow || ![keyWindow firstResponder]))
[keyWindow makeFirstResponder:[keyWindow initialFirstResponder]];
[self _makeMainWindow:keyWindow];
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
_previousKeyWindow = nil;
_previousMainWindow = nil;
}
/*!
@ignore
*/
- (void)_makeKeyWindow:(CPWindow)aWindow
{
if ([CPApp keyWindow] === aWindow || ![aWindow canBecomeKeyWindow])
return;
[[CPApp keyWindow] resignKeyWindow];
[aWindow becomeKeyWindow];
}
/*!
@ignore
*/
- (void)_makeMainWindow:(CPWindow)aWindow
{
// Sheets cannot be main. Their parent window becomes main.
if (aWindow._isSheet)
{
[self _makeMainWindow:aWindow._parentView];
return;
}
if ([CPApp mainWindow] === aWindow || ![aWindow canBecomeMainWindow])
return;
[[CPApp mainWindow] resignMainWindow];
[aWindow becomeMainWindow];
}
- (void)touchEvent:(DOMEvent)aDOMEvent
{
if (aDOMEvent.touches && (aDOMEvent.touches.length == 1 || (aDOMEvent.touches.length == 0 && aDOMEvent.changedTouches.length == 1)))
+24 -6
View File
@@ -1243,8 +1243,8 @@ var themedButtonValues = nil,
overrides =
[
[@"image-search-left-margin", 5],
[@"image-cancel-right-margin", 5],
[@"image-search-inset", CGInsetMake(0, 0, 0, 5)],
[@"image-cancel-inset", CGInsetMake(0, 5, 0, 0)],
[@"image-search", imageSearch],
[@"image-find", imageFind],
@@ -1255,15 +1255,15 @@ var themedButtonValues = nil,
[@"image-find", smallImageFind, CPThemeStateControlSizeSmall],
[@"image-cancel", smallImageCancel, CPThemeStateControlSizeSmall],
[@"image-cancel-pressed", smallImageCancelPressed, CPThemeStateControlSizeSmall],
[@"image-search-left-margin", 8, CPThemeStateControlSizeSmall],
[@"image-cancel-right-margin", 8, CPThemeStateControlSizeSmall],
[@"image-search-inset", CGInsetMake(0, 0, 0, 8), CPThemeStateControlSizeSmall],
[@"image-cancel-inset", CGInsetMake(0, 8, 0, 0), CPThemeStateControlSizeSmall],
[@"image-search", miniImageSearch, CPThemeStateControlSizeMini],
[@"image-find", miniImageFind, CPThemeStateControlSizeMini],
[@"image-cancel", miniImageCancel, CPThemeStateControlSizeMini],
[@"image-cancel-pressed", miniImageCancelPressed, CPThemeStateControlSizeMini],
[@"image-search-left-margin", 8, CPThemeStateControlSizeMini],
[@"image-cancel-right-margin", 8, CPThemeStateControlSizeMini],
[@"image-search-inset", CGInsetMake(0, 0, 0, 8), CPThemeStateControlSizeMini],
[@"image-cancel-inset", CGInsetMake(0, 8, 0, 0), CPThemeStateControlSizeMini],
];
[self registerThemeValues:overrides forView:searchField inherit:themedRoundedTextFieldValues];
@@ -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)],
+22 -3
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]],
@@ -824,8 +825,8 @@ var themedButtonValues = nil,
overrides =
[
[@"image-search-left-margin", 5],
[@"image-cancel-right-margin", 5],
[@"image-search-inset", CGInsetMake(0, 0, 0, 5)],
[@"image-cancel-inset", CGInsetMake(0, 5, 0, 0)],
[@"image-search", imageSearch],
[@"image-find", imageFind],
@@ -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)],
+39 -16
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)
@@ -668,6 +680,17 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
[_delegate _popoverWindowDidClose];
}
/*!
@ignore
Needed to be ignored to close a popover when a platform is closed.
Because the animation, the popover is not properly closed.
*/
- (void)_didReceivePlatformWindowWillCloseNotification:(CPNotification)aNotification
{
[super _didReceivePlatformWindowWillCloseNotification:aNotification];
[self _orderOutRecursively:YES];
}
#pragma mark -
#pragma mark Private
@@ -715,7 +738,7 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4,
// Consider clicks in child windows to be "inside". This keeps a transient popover from
// closing if e.g. the window containing the menu of a token field is clicked.
if (mouseWindow === self || [mouseWindow _hasAncestorWindow:self] || ![self _hasOnlyTransientChild:self])
if (mouseWindow === self || [mouseWindow _hasAncestorWindow:self] || ![self _hasOnlyTransientChild:self] || [mouseWindow platformWindow] != [self platformWindow])
{
[self _trapNextMouseDown];
}
+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);
}
+16 -1
View File
@@ -26,7 +26,8 @@
@import "CPString.j"
// The default global behavior class, created lazily
var CPDefaultDcmHandler = nil;
var CPDefaultDcmHandler = nil,
CPDecimalNumberUIDs = new CFMutableDictionary();
/*!
@class CPDecimalNumberHandler
@@ -531,6 +532,20 @@ var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundi
}
// instance methods
- (CPString)UID
{
var UID = CPDecimalNumberUIDs.valueForKey(self);
if (!UID)
{
UID = objj_generateObjectUID();
CPDecimalNumberUIDs.setValueForKey(self, UID);
}
return UID + "";
}
/*!
Returns a new CPDecimalNumber object with the result of the summation of
the receiver object and \c decimalNumber. If overflow occurs then the
+9 -71
View File
@@ -26,10 +26,7 @@
@import "CPNull.j"
@import "CPObject.j"
//FIXME: After release of 0.9.7 remove below variable
var CPDictionaryShowNilDeprecationMessage = YES,
CPDictionaryMaxDescriptionRecursion = 10;
var CPDictionaryMaxDescriptionRecursion = 10;
/*!
@class CPDictionary
@@ -238,28 +235,10 @@ var CPDictionaryShowNilDeprecationMessage = YES,
key = keyArray[i];
if (value === nil)
{
CPDictionaryShowNilDeprecationMessage = NO;
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: Attempt to insert nil object from objects[%d]", [self className], _cmd, i]);
if (typeof(objj_backtrace_print) === "function")
objj_backtrace_print(CPLog.warn);
// FIXME: After release of 0.9.7 change this block to:
// [CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil object from objects[" + i + @"]"];
}
[CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil object from objects[" + i + @"]"];
if (key === nil)
{
CPDictionaryShowNilDeprecationMessage = NO;
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: Attempt to insert nil key from keys[%d]", [self className], _cmd, i]);
if (typeof(objj_backtrace_print) === "function")
objj_backtrace_print(CPLog.warn);
// FIXME: After release of 0.9.7 change this block to:
// [CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil key from keys[" + i + @"]"];
}
[CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil key from keys[" + i + @"]"];
[self setObject:value forKey:key];
}
@@ -302,28 +281,10 @@ var CPDictionaryShowNilDeprecationMessage = YES,
key = arguments[index + 1];
if (value === nil)
{
CPDictionaryShowNilDeprecationMessage = NO;
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: Attempt to insert nil object from objects[%d]", [self className], _cmd, (index / 2) - 1]);
if (typeof(objj_backtrace_print) === "function")
objj_backtrace_print(CPLog.warn);
// FIXME: After release of 0.9.7 change 3 lines above to this:
// [CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil object from objects[" + ((index / 2) - 1) + @"]"];
}
[CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil object from objects[" + ((index / 2) - 1) + @"]"];
if (key === nil)
{
CPDictionaryShowNilDeprecationMessage = NO;
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: Attempt to insert nil key from keys[%d]", [self className], _cmd, (index / 2) - 1]);
if (typeof(objj_backtrace_print) === "function")
objj_backtrace_print(CPLog.warn);
// FIXME: After release of 0.9.7 change 3 lines above to this:
// [CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil key from keys[" + ((index / 2) - 1) + @"]"];
}
[CPException raise:CPInvalidArgumentException reason:@"Attempt to insert nil key from keys[" + ((index / 2) - 1) + @"]"];
[self setObject:value forKey:key];
}
@@ -634,34 +595,11 @@ var CPDictionaryShowNilDeprecationMessage = YES,
*/
- (void)setObject:(id)anObject forKey:(id)aKey
{
// FIXME: After release of 0.9.7, remove this test and leave the contents of its block
if (CPDictionaryShowNilDeprecationMessage)
{
if (aKey === nil)
{
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: key cannot be nil", [self className], _cmd]);
if (aKey === nil)
[CPException raise:CPInvalidArgumentException reason:@"key cannot be nil"];
if (typeof(objj_backtrace_print) === "function")
objj_backtrace_print(CPLog.warn);
// FIXME: After release of 0.9.7 change this block to:
// [CPException raise:CPInvalidArgumentException reason:@"key cannot be nil"];
}
if (anObject === nil)
{
CPLog.warn([CPString stringWithFormat:@"[%s %s] DEPRECATED: object cannot be nil (key: %s)", [self className], _cmd, aKey]);
if (typeof(objj_backtrace_print) === "function")
objj_backtrace_print(CPLog.warn);
// FIXME: After release of 0.9.7 change this block to:
// [CPException raise:CPInvalidArgumentException reason:@"object cannot be nil (key: " + aKey + @")"];
}
}
// FIXME: After release of 0.9.7 remove 2 lines below.
else
CPDictionaryShowNilDeprecationMessage = YES;
if (anObject === nil)
[CPException raise:CPInvalidArgumentException reason:@"object cannot be nil (key: " + aKey + @")"];
self.setValueForKey(aKey, anObject);
}
+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)
+4 -2
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!
======================
@@ -33,7 +35,7 @@ Getting Started
---------------
To get started, download and install the current release version of Cappuccino:
$ curl https://raw.githubusercontent.com/cappuccino/cappuccino/v0.9.7-1/bootstrap.sh >/tmp/cappuccino_bootstrap.sh && bash /tmp/cappuccino_bootstrap.sh
$ curl https://raw.githubusercontent.com/cappuccino/cappuccino/v0.9.8/bootstrap.sh >/tmp/cappuccino_bootstrap.sh && bash /tmp/cappuccino_bootstrap.sh
If you'd just like to get started using Cappuccino for your web apps, you are done.
@@ -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
+3 -3
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];
}
/*!
@@ -37,7 +37,7 @@
anEvent = [CPEvent otherEventWithType:CPApplicationDefined location:CGPointMakeZero() modifierFlags:0 timestamp:500.5 windowNumber:2 context:nil subtype:5 data1:15 data2:25];
[self assert:@"CPEvent: type=15 loc={0, 0} time=500.5 flags=0x0 win=null winNum=0 ctxt=null subtype=5 data1=15 data2=25" equals:[anEvent description]];
[self assert:@"CPEvent: type=15 loc={0, 0} time=500.5 flags=0x0 win=null winNum=2 ctxt=null subtype=5 data1=15 data2=25" equals:[anEvent description]];
}
- (void)testModifierFlags
+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 = [];
}
+105 -6
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.
*/
@@ -229,7 +234,7 @@
[scrollView setDocumentView:documentView];
[textField1 setFrameOrigin:CGPointMake(0, 0)];
[textField1 setFrameOrigin:CGPointMake(10, 10)];
[textField2 setFrameOrigin:CGPointMake(500, 500)];
[documentView addSubview:textField1];
@@ -242,9 +247,11 @@
[self assertPoint:CGPointMake(0, 0) equals:visibleRect.origin message:@"VisibleRect origin not at top left corner"];
// Make the second text field visible
[textField2 scrollRectToVisible:[textField2 bounds]];
var hasScrolled = [textField2 scrollRectToVisible:[textField2 bounds]];
var visibleRectOriginShouldBeAt = CGPointMake(500 - originalVisibleSize.width + textField2Size.width, 500 -originalVisibleSize.height + textField2Size.height);
[self assertTrue:hasScrolled];
var visibleRectOriginShouldBeAt = CGPointMake(500 - originalVisibleSize.width + textField2Size.width, 500 - originalVisibleSize.height + textField2Size.height);
visibleRect = [documentView visibleRect];
@@ -252,12 +259,66 @@
[self assertPoint:visibleRectOriginShouldBeAt equals:visibleRect.origin message:@"Second text field not at lower right corner in visible rect"];
// Make the first text field visible again
[textField1 scrollRectToVisible:[textField2 bounds]];
hasScrolled = [textField1 scrollRectToVisible:[textField1 bounds]];
[self assertTrue:hasScrolled];
visibleRect = [documentView visibleRect];
// We should now be back at top left corner
[self assertPoint:CGPointMake(0, 0) equals:visibleRect.origin message:@"VisibleRect origin not at top left corner again"];
[self assertPoint:CGPointMake(10, 10) equals:visibleRect.origin message:@"VisibleRect origin not at top left corner again"];
// Try to scroll again and it should not scroll
hasScrolled = [textField1 scrollRectToVisible:[textField1 bounds]];
[self assertFalse:hasScrolled];
}
- (void)testScrollRectToVisibleWithLargeRect
{
var scrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)],
documentView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 1000, 1000)],
view1 = [[CPView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)],
view2 = [[CPView alloc] initWithFrame:CGRectMake(500, 500, 200, 200)],
view1Size = CGSizeMakeCopy([view1 bounds].size),
view2Size = CGSizeMakeCopy([view2 bounds].size);
[scrollView setDocumentView:documentView];
[view1 setFrameOrigin:CGPointMake(0, 0)];
[view2 setFrameOrigin:CGPointMake(500, 500)];
[documentView addSubview:view1];
[documentView addSubview:view2];
var visibleRect = [documentView visibleRect],
originalVisibleSize = CGSizeMakeCopy(visibleRect.size);
// Make sure we are at the top left corner
[self assertPoint:CGPointMake(0, 0) equals:visibleRect.origin message:@"VisibleRect origin not at top left corner"];
// Make the second view visible
var hasScrolled = [view2 scrollRectToVisible:[view2 bounds]];
[self assertTrue:hasScrolled];
visibleRect = [documentView visibleRect];
// We should now have the origin of view2 in the upper left corner
[self assertPoint:CGPointMake(500, 500) equals:visibleRect.origin message:@"Origin of second view not at upper left corner in visible rect"];
// Make the first view visible again
hasScrolled = [view1 scrollRectToVisible:[view1 bounds]];
[self assertTrue:hasScrolled];
visibleRect = [documentView visibleRect];
var visibleRectOriginShouldBeAt = CGPointMake(200 - visibleRect.size.width, 200 - visibleRect.size.height);
// We should now be back almost at top left corner except that the lower right corner of the rect should be at the lower right corner of the visible rect.
[self assertPoint:visibleRectOriginShouldBeAt equals:visibleRect.origin message:@"VisibleRect origin not at top left corner again"];
// Try to scroll again and it should not scroll even as some parts are outside the visible rect
hasScrolled = [view1 scrollRectToVisible:[view1 bounds]];
[self assertFalse:hasScrolled];
}
-(void)testNotificationsRegistered
@@ -278,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"];

Some files were not shown because too many files have changed in this diff Show More