mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-10-15 13:04:29 +00:00
Merge branch 'master' into kvo
This commit is contained in:
commit
3b39b64e1b
10 files changed
+410
-127
No files matched your search
+93
-52
@@ -49,21 +49,22 @@ var CPSplitViewHorizontalImage = nil,
|
||||
CPArray _DOMDividerElements;
|
||||
CPString _dividerImagePath;
|
||||
int _drawingDivider;
|
||||
|
||||
BOOL _needsResizeSubviews;
|
||||
}
|
||||
|
||||
/*
|
||||
@ignore
|
||||
*/
|
||||
//+ (void)initialize
|
||||
//{
|
||||
// if (self != [CPSplitView class])
|
||||
// return;
|
||||
//
|
||||
// var bundle = [CPBundle bundleForClass:self];
|
||||
//
|
||||
// CPSplitViewHorizontalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewHorizontal.png"] size:CPSizeMake(5.0, 10.0)];
|
||||
// CPSplitViewVerticalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewVertical.png"] size:CPSizeMake(10.0, 5.0)];
|
||||
//}
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self != [CPSplitView class])
|
||||
return;
|
||||
|
||||
var bundle = [CPBundle bundleForClass:self];
|
||||
CPSplitViewHorizontalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewHorizontal.png"] size:CPSizeMake(5.0, 10.0)];
|
||||
CPSplitViewVerticalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewVertical.png"] size:CPSizeMake(10.0, 5.0)];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)aFrame
|
||||
{
|
||||
@@ -89,20 +90,45 @@ var CPSplitViewHorizontalImage = nil,
|
||||
return _isVertical;
|
||||
}
|
||||
|
||||
- (void)setVertical:(BOOL)flag
|
||||
- (void)setVertical:(BOOL)shouldBeVertical
|
||||
{
|
||||
[self _setVertical:flag];
|
||||
if (![self _setVertical:shouldBeVertical])
|
||||
return;
|
||||
|
||||
[self adjustSubviews];
|
||||
// Just re-adjust evenly.
|
||||
var frame = [self frame],
|
||||
dividerThickness = [self dividerThickness];
|
||||
|
||||
[self _postNotificationWillResize];
|
||||
|
||||
var eachSize = ROUND((frame.size[_sizeComponent] - dividerThickness * (_subviews.length - 1)) / _subviews.length),
|
||||
index = 0,
|
||||
count = _subviews.length;
|
||||
|
||||
if ([self isVertical])
|
||||
for (; index < count; ++index)
|
||||
[_subviews[index] setFrame:CGRectMake(ROUND((eachSize + dividerThickness) * index), 0, eachSize, frame.size.height)];
|
||||
else
|
||||
for (; index < count; ++index)
|
||||
[_subviews[index] setFrame:CGRectMake(0, ROUND((eachSize + dividerThickness) * index), frame.size.width, eachSize)];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[self _postNotificationDidResize];
|
||||
|
||||
}
|
||||
|
||||
- (void)_setVertical:(BOOL)flag
|
||||
- (BOOL)_setVertical:(BOOL)shouldBeVertical
|
||||
{
|
||||
_isVertical = flag;
|
||||
var changed = (_isVertical != shouldBeVertical);
|
||||
|
||||
_originComponent = [self isVertical] ? "x" : "y";
|
||||
_sizeComponent = [self isVertical] ? "width" : "height";
|
||||
_dividerImagePath = [self isVertical] ? [CPSplitViewVerticalImage filename] : [CPSplitViewHorizontalImage filename];
|
||||
_isVertical = shouldBeVertical;
|
||||
|
||||
_originComponent = [self isVertical] ? "x" : "y";
|
||||
_sizeComponent = [self isVertical] ? "width" : "height";
|
||||
_dividerImagePath = [self isVertical] ? [CPSplitViewVerticalImage filename] : [CPSplitViewHorizontalImage filename];
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
- (BOOL)isPaneSplitter
|
||||
@@ -124,32 +150,10 @@ var CPSplitViewHorizontalImage = nil,
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)didAddSubview:(CPView)subview
|
||||
- (void)didAddSubview:(CPView)aSubview
|
||||
{
|
||||
[self adjustSubviews];
|
||||
}
|
||||
|
||||
- (void)adjustSubviews
|
||||
{
|
||||
var frame = [self frame],
|
||||
dividerThickness = [self dividerThickness];
|
||||
|
||||
[self _postNotificationWillResize];
|
||||
|
||||
var eachSize = ROUND((frame.size[_sizeComponent] - dividerThickness * (_subviews.length - 1)) / _subviews.length),
|
||||
index = 0,
|
||||
count = _subviews.length;
|
||||
|
||||
if ([self isVertical])
|
||||
for (; index < count; ++index)
|
||||
[_subviews[index] setFrame:CGRectMake(ROUND((eachSize + dividerThickness) * index), 0, eachSize, frame.size.height)];
|
||||
else
|
||||
for (; index < count; ++index)
|
||||
[_subviews[index] setFrame:CGRectMake(0, ROUND((eachSize + dividerThickness) * index), frame.size.width, eachSize)];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[self _postNotificationDidResize];
|
||||
_needsResizeSubviews = YES;
|
||||
// [self adjustSubviews];
|
||||
}
|
||||
|
||||
- (BOOL)isSubviewCollapsed:(CPView)subview
|
||||
@@ -219,6 +223,39 @@ var CPSplitViewHorizontalImage = nil,
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)viewWillDraw
|
||||
{
|
||||
[self _adjustSubviewsWithCalculatedSize];
|
||||
}
|
||||
|
||||
- (void)_adjustSubviewsWithCalculatedSize
|
||||
{
|
||||
if (!_needsResizeSubviews)
|
||||
return;
|
||||
|
||||
_needsResizeSubviews = NO;
|
||||
|
||||
var subviews = [self subviews],
|
||||
count = subviews.length,
|
||||
oldSize = CGSizeMakeZero();
|
||||
|
||||
if ([self isVertical])
|
||||
{
|
||||
oldSize.width += [self dividerThickness] * (count - 1);
|
||||
oldSize.height = CGRectGetHeight([self frame]);
|
||||
}
|
||||
else
|
||||
{
|
||||
oldSize.width = CGRectGetWidth([self frame]);
|
||||
oldSize.height += [self dividerThickness] * (count - 1);
|
||||
}
|
||||
|
||||
while (count--)
|
||||
oldSize[_sizeComponent] += [subviews[count] frame].size[_sizeComponent];
|
||||
|
||||
[self resizeSubviewsWithOldSize:oldSize];
|
||||
}
|
||||
|
||||
- (BOOL)cursorAtPoint:(CPPoint)aPoint hitDividerAtIndex:(int)anIndex
|
||||
{
|
||||
var frame = [_subviews[anIndex] frame],
|
||||
@@ -354,6 +391,8 @@ var CPSplitViewHorizontalImage = nil,
|
||||
|
||||
- (void)setPosition:(float)position ofDividerAtIndex:(int)dividerIndex
|
||||
{
|
||||
[self _adjustSubviewsWithCalculatedSize];
|
||||
|
||||
// not sure where this should override other positions?
|
||||
if ([_delegate respondsToSelector:@selector(splitView:constrainSplitPosition:ofSubviewAt:)])
|
||||
position = [_delegate splitView:self constrainSplitPosition:position ofSubviewAt:dividerIndex];
|
||||
@@ -387,13 +426,22 @@ var CPSplitViewHorizontalImage = nil,
|
||||
|
||||
frameB.size[_sizeComponent] = frameB.origin[_originComponent] + frameB.size[_sizeComponent] - realPosition - [self dividerThickness];
|
||||
frameB.origin[_originComponent] = realPosition + [self dividerThickness];
|
||||
[_subviews[dividerIndex+1] setFrame:frameB];
|
||||
[_subviews[dividerIndex + 1] setFrame:frameB];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)setFrameSize:(CGSize)aSize
|
||||
{
|
||||
[self _adjustSubviewsWithCalculatedSize];
|
||||
|
||||
[super setFrameSize:aSize];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)resizeSubviewsWithOldSize:(CPSize)oldSize
|
||||
{
|
||||
{
|
||||
if ([_delegate respondsToSelector:@selector(splitView:resizeSubviewsWithOldSize:)])
|
||||
{
|
||||
[_delegate splitView:self resizeSubviewsWithOldSize:oldSize];
|
||||
@@ -422,8 +470,6 @@ var CPSplitViewHorizontalImage = nil,
|
||||
|
||||
[view setFrame:newFrame];
|
||||
}
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
[self _postNotificationDidResize];
|
||||
}
|
||||
@@ -505,8 +551,3 @@ var CPSplitViewDelegateKey = "CPSplitViewDelegateKey",
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// FIXME: once +initialize is fixed for superclasses, remove this and uncomment +initialize
|
||||
var bundle = [CPBundle bundleForClass:CPSplitView];
|
||||
CPSplitViewHorizontalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewHorizontal.png"] size:CPSizeMake(5.0, 10.0)];
|
||||
CPSplitViewVerticalImage = [[CPImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CPSplitView/CPSplitViewVertical.png"] size:CPSizeMake(10.0, 5.0)];
|
||||
+47
-23
@@ -105,6 +105,7 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
BOOL _isSelectable;
|
||||
|
||||
id _value;
|
||||
id _placeholderString;
|
||||
|
||||
CPLineBreakMode _lineBreakMode;
|
||||
#if PLATFORM(DOM)
|
||||
@@ -144,7 +145,8 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
if (self)
|
||||
{
|
||||
_value = @"";
|
||||
|
||||
_placeholderString = @"";
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_DOMTextElement = document.createElement("div");
|
||||
_DOMTextElement.style.position = "absolute";
|
||||
@@ -167,8 +169,7 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
// Setting the Bezel Style
|
||||
/*
|
||||
Sets whether the textfield will have a bezeled border.
|
||||
@param shouldBeBezeled <code>YES</code> means the textfield
|
||||
will draw a bezeled border
|
||||
@param shouldBeBezeled <code>YES</code> means the textfield will draw a bezeled border
|
||||
*/
|
||||
- (void)setBezeled:(BOOL)shouldBeBezeled
|
||||
{
|
||||
@@ -181,8 +182,7 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns <code>YES</code> if the textfield draws a
|
||||
bezeled border.
|
||||
Returns <code>YES</code> if the textfield draws a bezeled border.
|
||||
*/
|
||||
- (BOOL)isBezeled
|
||||
{
|
||||
@@ -213,8 +213,7 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
|
||||
/*
|
||||
Sets whether the textfield will have a border drawn.
|
||||
@param shouldBeBordered <code>YES</code> makes the
|
||||
textfield draw a border
|
||||
@param shouldBeBordered <code>YES</code> makes the textfield draw a border
|
||||
*/
|
||||
- (void)setBordered:(BOOL)shouldBeBordered
|
||||
{
|
||||
@@ -227,8 +226,7 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns <code>YES</code> if the textfield has
|
||||
a border.
|
||||
Returns <code>YES</code> if the textfield has a border.
|
||||
*/
|
||||
- (BOOL)isBordered
|
||||
{
|
||||
@@ -264,11 +262,13 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
[self setBackgroundColor:nil];
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return _isEditable;
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (BOOL)becomeFirstResponder
|
||||
{
|
||||
var string = [self stringValue];
|
||||
@@ -283,12 +283,12 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
element.style.font = _DOMElement.style.font;
|
||||
element.style.zIndex = 1000;
|
||||
element.style.width = CGRectGetWidth([self bounds]) - 3.0 + "px";
|
||||
// element.style.left = _DOMTextElement.style.left;
|
||||
// element.style.top = _DOMTextElement.style.top;
|
||||
//element.style.left = _DOMTextElement.style.left;
|
||||
//element.style.top = _DOMTextElement.style.top;
|
||||
|
||||
_DOMElement.appendChild(element);
|
||||
window.setTimeout(function() { element.focus(); }, 0.0);
|
||||
// element.onblur = function() { objj_debug_print_backtrace(); }
|
||||
//element.onblur = function() { objj_debug_print_backtrace(); }
|
||||
//element.select();
|
||||
|
||||
element.onkeypress = function(aDOMEvent)
|
||||
@@ -309,12 +309,17 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
}
|
||||
};
|
||||
|
||||
// If current value is the placeholder value, remove it to allow user to update.
|
||||
if ([_value lowercaseString] == [[self placeholderString] lowercaseString])
|
||||
[self setStringValue:@""];
|
||||
|
||||
[[CPDOMWindowBridge sharedDOMWindowBridge] _propagateCurrentDOMEvent:YES];
|
||||
#endif
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* @ignore */
|
||||
- (BOOL)resignFirstResponder
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
@@ -322,19 +327,25 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
|
||||
_DOMElement.removeChild(element);
|
||||
[self setStringValue:element.value];
|
||||
#endif
|
||||
|
||||
// If textfield has no value, then display the placeholderValue
|
||||
if (!_value)
|
||||
[self setStringValue:[self placeholderString]];
|
||||
|
||||
#endif
|
||||
return YES;
|
||||
}
|
||||
|
||||
/*
|
||||
Sets whether or not the receiver text field can be edited
|
||||
*/
|
||||
- (void)setEditable:(BOOL)shouldBeEditable
|
||||
{
|
||||
_isEditable = shouldBeEditable;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns <code>YES</code> if the textfield is currently
|
||||
editable by the user.
|
||||
Returns <code>YES</code> if the textfield is currently editable by the user.
|
||||
*/
|
||||
- (BOOL)isEditable
|
||||
{
|
||||
@@ -351,8 +362,7 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns <code>YES</code> if the field's text is
|
||||
selectable by the user.
|
||||
Returns <code>YES</code> if the field's text is selectable by the user.
|
||||
*/
|
||||
- (BOOL)isSelectable
|
||||
{
|
||||
@@ -360,8 +370,7 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
}
|
||||
|
||||
/*
|
||||
Sets whether the field's text is selectable
|
||||
by the user.
|
||||
Sets whether the field's text is selectable by the user.
|
||||
@param aFlag <code>YES</code> makes the text selectable
|
||||
*/
|
||||
- (void)setSelectable:(BOOL)aFlag
|
||||
@@ -457,6 +466,23 @@ var _CPTextFieldSquareBezelColor = nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the receiver's placeholder string
|
||||
*/
|
||||
- (CPString)placeholderString
|
||||
{
|
||||
return _placeholderString;
|
||||
}
|
||||
|
||||
/*
|
||||
Sets a placeholder string for the receiver. The placeholder is displayed until editing begins,
|
||||
and after editing ends, if the text field has an empty string value
|
||||
*/
|
||||
-(void)setPlaceholderString:(CPString)aStringValue
|
||||
{
|
||||
_placeholderString = aStringValue;
|
||||
}
|
||||
|
||||
/*
|
||||
Adjusts the text field's size in the application.
|
||||
*/
|
||||
@@ -533,10 +559,8 @@ var CPTextFieldIsSelectableKey = @"CPTextFieldIsSelectableKey",
|
||||
}
|
||||
|
||||
/*
|
||||
Encodes the data of this textfield into the
|
||||
provided coder.
|
||||
@param aCoder the coder into which the data
|
||||
will be written
|
||||
Encodes the data of this textfield into the provided coder.
|
||||
@param aCoder the coder into which the data will be written
|
||||
*/
|
||||
- (void)encodeWithCoder:(CPCoder)aCoder
|
||||
{
|
||||
|
||||
+51
-7
@@ -37,13 +37,47 @@ import "CPGraphicsContext.j"
|
||||
#include "CoreGraphics/CGGeometry.h"
|
||||
#include "Platform/DOM/CPDOMDisplayServer.h"
|
||||
|
||||
|
||||
/*
|
||||
@global
|
||||
@group CPViewAutoresizingMasks
|
||||
The default resizingMask, the view will not resize or reposition itself.
|
||||
*/
|
||||
CPViewNotSizable = 0;
|
||||
/*
|
||||
@global
|
||||
@group CPViewAutoresizingMasks
|
||||
Allow for flexible space on the left hand side of the view.
|
||||
*/
|
||||
CPViewMinXMargin = 1;
|
||||
/*
|
||||
@global
|
||||
@group CPViewAutoresizingMasks
|
||||
The view should grow and shrink horizontally with its parent view.
|
||||
*/
|
||||
CPViewWidthSizable = 2;
|
||||
/*
|
||||
@global
|
||||
@group CPViewAutoresizingMasks
|
||||
Allow for flexible space to the right hand side of the view.
|
||||
*/
|
||||
CPViewMaxXMargin = 4;
|
||||
/*
|
||||
@global
|
||||
@group CPViewAutoresizingMasks
|
||||
Allow for flexible space above the view.
|
||||
*/
|
||||
CPViewMinYMargin = 8;
|
||||
/*
|
||||
@global
|
||||
@group CPViewAutoresizingMasks
|
||||
The view should grow and shrink vertically with its parent view.
|
||||
*/
|
||||
CPViewHeightSizable = 16;
|
||||
/*
|
||||
@global
|
||||
@group CPViewAutoresizingMasks
|
||||
Allow for flexible space below the view.
|
||||
*/
|
||||
CPViewMaxYMargin = 32;
|
||||
|
||||
CPViewBoundsDidChangeNotification = @"CPViewBoundsDidChangeNotification";
|
||||
@@ -139,11 +173,6 @@ var DOMElementPrototype = nil,
|
||||
*/
|
||||
+ (void)initialize
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
if ([self instanceMethodForSelector:@selector(drawRect:)] != [CPView instanceMethodForSelector:@selector(drawRect:)])
|
||||
CustomDrawRectViews[[self hash]] = YES;
|
||||
#endif
|
||||
|
||||
if (self != [CPView class])
|
||||
return;
|
||||
|
||||
@@ -1346,7 +1375,16 @@ setBoundsOrigin:
|
||||
- (void)setNeedsDisplayInRect:(CPRect)aRect
|
||||
{
|
||||
#if PLATFORM(DOM)
|
||||
if (!CustomDrawRectViews[[[self class] hash]])
|
||||
var hash = [[self class] hash],
|
||||
hasCustomDrawRect = CustomDrawRectViews[hash];
|
||||
|
||||
if (!hasCustomDrawRect && typeof hasCustomDrawRect === "undefined")
|
||||
{
|
||||
hasCustomDrawRect = [self methodForSelector:@selector(drawRect:)] != [CPView instanceMethodForSelector:@selector(drawRect:)];
|
||||
CustomDrawRectViews[hash] = hasCustomDrawRect;
|
||||
}
|
||||
|
||||
if (!hasCustomDrawRect)
|
||||
return;
|
||||
#endif
|
||||
|
||||
@@ -1397,6 +1435,8 @@ setBoundsOrigin:
|
||||
*/
|
||||
- (void)displayRect:(CPRect)aRect
|
||||
{
|
||||
[self viewWillDraw];
|
||||
|
||||
[self displayRectIgnoringOpacity:aRect inContext:nil];
|
||||
|
||||
_dirtyRect = NULL;
|
||||
@@ -1412,6 +1452,10 @@ setBoundsOrigin:
|
||||
[self unlockFocus];
|
||||
}
|
||||
|
||||
- (void)viewWillDraw
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Locks focus on the receiver, so drawing commands apply to it.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -24,8 +24,8 @@ import <Foundation/CPObject.j>
|
||||
import <Foundation/CPURLConnection.j>
|
||||
import <Foundation/CPURLRequest.j>
|
||||
|
||||
import "CPCustomView.j"
|
||||
import "_CPCibCustomObject.j"
|
||||
import "_CPCibCustomView.j"
|
||||
import "_CPCibKeyedUnarchiver.j"
|
||||
import "_CPCibObjectData.j"
|
||||
import "_CPCibWindowTemplate.j"
|
||||
|
||||
File renamed without changes.
+115
-28
@@ -128,14 +128,15 @@ var CPStringHashes = new objj_dictionary();
|
||||
{
|
||||
if (!format)
|
||||
[CPException raise:CPInvalidArgumentException
|
||||
reason:"stringWithString: the format can't be 'nil'"];
|
||||
reason:"initWithFormat: the format can't be 'nil'"];
|
||||
|
||||
self = sprintf.apply(this, Array.prototype.slice.call(arguments, 2));
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
Creates a new string using C printf-style formatting. First argument should be a constant format string, like ' "float val = %f" ', remaining arguments should be the variables to print the values of, comma-separated.
|
||||
Creates a new string using C printf-style formatting. First argument should be a constant format string,
|
||||
like ' "float val = %f" ', remaining arguments should be the variables to print the values of, comma-separated.
|
||||
@param format the format to be used, printf-style
|
||||
@return the initialized <objj>CPString</objj>
|
||||
*/
|
||||
@@ -143,7 +144,7 @@ var CPStringHashes = new objj_dictionary();
|
||||
{
|
||||
if (!format)
|
||||
[CPException raise:CPInvalidArgumentException
|
||||
reason:"stringWithString: the format can't be 'nil'"];
|
||||
reason:"initWithFormat: the format can't be 'nil'"];
|
||||
|
||||
return sprintf.apply(this, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
@@ -174,6 +175,21 @@ var CPStringHashes = new objj_dictionary();
|
||||
}
|
||||
|
||||
// Combining strings
|
||||
|
||||
/*
|
||||
Returns a string made by appending to the reciever a string constructed from a given format
|
||||
string and the floowing arguments
|
||||
@param format the format string in printf-style.
|
||||
@return the initialized <objj>CPString</objj>
|
||||
*/
|
||||
- (CPString)stringByAppendingFormat:(CPString)format, ...
|
||||
{
|
||||
if (!format)
|
||||
[CPException raise:CPInvalidArgumentException reason:"initWithFormat: the format can't be 'nil'"];
|
||||
|
||||
return self + sprintf.apply(this, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
|
||||
/*
|
||||
Creates a new <objj>CPString</objj> from the concatenation of the receiver and the specified string.
|
||||
@param aString the string to append to the receiver
|
||||
@@ -214,6 +230,7 @@ var CPStringHashes = new objj_dictionary();
|
||||
if (difference) string += substring.substr(difference + substring.length);
|
||||
}
|
||||
|
||||
//Dividing Strings
|
||||
/*
|
||||
Tokenizes the receiver string using the specified
|
||||
delimiter. For example, if the receiver is:
|
||||
@@ -261,6 +278,7 @@ var CPStringHashes = new objj_dictionary();
|
||||
}
|
||||
|
||||
// Finding characters and substrings
|
||||
|
||||
/*
|
||||
Finds the range of characters in the receiver where the specified string exists. If the string
|
||||
does not exist in the receiver, the range <code>length</code> will be 0.
|
||||
@@ -269,9 +287,7 @@ var CPStringHashes = new objj_dictionary();
|
||||
*/
|
||||
- (CPRange)rangeOfString:(CPString)aString
|
||||
{
|
||||
var location = indexOf(aString);
|
||||
|
||||
return CPMakeRange(location, location == CPNotFound ? 0 : aString.length);
|
||||
return [self rangeOfString:aString options:0];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -279,13 +295,13 @@ var CPStringHashes = new objj_dictionary();
|
||||
where the specified string exists. The search
|
||||
is subject to the options specified in the
|
||||
specified mask which can be a combination of:
|
||||
<pre>
|
||||
CPCaseInsensitiveSearch
|
||||
CPLiteralSearch
|
||||
CPBackwardsSearch
|
||||
CPAnchoredSearch
|
||||
CPNumericSearch
|
||||
</pre>
|
||||
<pre>
|
||||
CPCaseInsensitiveSearch
|
||||
CPLiteralSearch
|
||||
CPBackwardsSearch
|
||||
CPAnchoredSearch
|
||||
CPNumericSearch
|
||||
</pre>
|
||||
@param aString the string to search for
|
||||
@param aMask the options to use in the search
|
||||
@return the range of characters in the receiver. If the string was not found,
|
||||
@@ -293,23 +309,78 @@ CPNumericSearch
|
||||
*/
|
||||
- (CPRange)rangeOfString:(CPString)aString options:(int)aMask
|
||||
{
|
||||
var string = self,
|
||||
return [self rangeOfString:aString options:aMask range:nil];
|
||||
}
|
||||
|
||||
/*
|
||||
Finds the range of characters in the receiver
|
||||
where the specified string exists in the given range
|
||||
of the receiver.The search is subject to the options specified in the
|
||||
specified mask which can be a combination of:
|
||||
<pre>
|
||||
CPCaseInsensitiveSearch
|
||||
CPLiteralSearch
|
||||
CPBackwardsSearch
|
||||
CPAnchoredSearch
|
||||
CPNumericSearch
|
||||
</pre>
|
||||
@param aString the string to search for
|
||||
@param aMask the options to use in the search
|
||||
@param aRange the range of the receiver in which to search for
|
||||
@return the range of characters in the receiver. If the string was not found,
|
||||
the <code>length</code> of the range will be 0.
|
||||
*/
|
||||
- (CPRange)rangeOfString:(CPString)aString options:(int)aMask range:(CPrange)aRange
|
||||
{
|
||||
var string = (aRange == nil) ? self : [self substringWithRange:aRange],
|
||||
location = CPNotFound;
|
||||
|
||||
|
||||
if (aMask & CPCaseInsensitiveSearch)
|
||||
{
|
||||
string = string.toLowerCase();
|
||||
aString = aString.toLowerCase();
|
||||
}
|
||||
|
||||
if (CPBackwardsSearch) location = lastIndexOf(aString, aMask & CPAnchoredSearch ? length - aString.length : 0);
|
||||
else if (aMask & CPAnchoredSearch) location = substr(0, aString.length).indexOf(aString) != CPNotFound ? 0 : CPNotFound;
|
||||
else location = indexOf(aString);
|
||||
|
||||
|
||||
if (aMask & CPBackwardsSearch)
|
||||
location = string.lastIndexOf(aString, aMask & CPAnchoredSearch ? length - aString.length : 0);
|
||||
else if (aMask & CPAnchoredSearch)
|
||||
location = string.substr(0, aString.length).indexOf(aString) != CPNotFound ? 0 : CPNotFound;
|
||||
else
|
||||
location = string.indexOf(aString);
|
||||
|
||||
return CPMakeRange(location, location == CPNotFound ? 0 : aString.length);
|
||||
}
|
||||
|
||||
//Replacing Substrings
|
||||
|
||||
/*
|
||||
Returns a new string in which all occurrences of a target string in the reciever are replaced by
|
||||
another given string.
|
||||
@param target The string to replace.
|
||||
@param replacement the string with which to replace the <pre>target<pre>
|
||||
*/
|
||||
|
||||
- (CPString)stringByReplacingOccurrencesOfString:(CPString)target withString:(CPString)replacement
|
||||
{
|
||||
return self.replace(new RegExp(target, "g"), replacement);
|
||||
}
|
||||
|
||||
/*
|
||||
- (CPString)stringByReplacingOccurrencesOfString:(CPString)target withString:(CPString)replacement options:(int)options range:(CPRange)searchRange
|
||||
{
|
||||
//TODO :Vijay implement the method
|
||||
|
||||
}
|
||||
|
||||
- (CPString)stringByReplacingCharactersInRange:(CPRange)range withString:(CPString)replacement
|
||||
{
|
||||
//TODO :Vijay implement the method
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Identifying and comparing strings
|
||||
|
||||
/*
|
||||
Compares the receiver to the specified string.
|
||||
@param aString the string with which to compare
|
||||
@@ -433,7 +504,18 @@ CPNumericSearch
|
||||
*/
|
||||
- (double)doubleValue
|
||||
{
|
||||
return eval(self);
|
||||
return parseFloat(self, 10);
|
||||
}
|
||||
/*
|
||||
Returns <code>YES</code> on encountering one of "Y", "y", "T", "t", or
|
||||
a digit 1-9. Returns <code>NO</code> otherwise. This method skips the initial
|
||||
whitespace characters, +,- followed by Zeroes.
|
||||
*/
|
||||
|
||||
- (BOOL)boolValue
|
||||
{
|
||||
var replaceRegExp = new RegExp("^\\s*[\\+,\\-]*0*");
|
||||
return RegExp("^[Y,y,t,T,1-9]").test(self.replace(replaceRegExp, ''));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -441,7 +523,7 @@ CPNumericSearch
|
||||
*/
|
||||
- (float)floatValue
|
||||
{
|
||||
return eval(self);
|
||||
return parseFloat(self, 10);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -449,12 +531,12 @@ CPNumericSearch
|
||||
*/
|
||||
- (int)intValue
|
||||
{
|
||||
return parseInt(self);
|
||||
return parseInt(self, 10);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns an the path components of this string. This
|
||||
method assumes that the string's contents is a '/'
|
||||
method assumes that the string's content is a '/'
|
||||
separated file system path.
|
||||
*/
|
||||
- (CPArray)pathComponents
|
||||
@@ -472,6 +554,11 @@ CPNumericSearch
|
||||
return substr(lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the last component of this string.
|
||||
This method assumes that the string's content is a '/'
|
||||
separated file system path.
|
||||
*/
|
||||
- (CPString)lastPathComponent
|
||||
{
|
||||
var components = [self pathComponents];
|
||||
@@ -484,8 +571,8 @@ CPNumericSearch
|
||||
*/
|
||||
- (CPString)stringByDeletingLastPathComponent
|
||||
{
|
||||
// FIMXE: this is wrong: a/a/ returns a/a/.
|
||||
return substr(0, lastIndexOf('/')+1);
|
||||
// FIXME: this is wrong: a/a/ returns a/a/.
|
||||
return substr(0, lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
- (CPString)stringByStandardizingPath
|
||||
@@ -509,11 +596,11 @@ String.prototype.isa = CPString;
|
||||
var sprintfFormatRegex = new RegExp("([^%]+|%[\\+\\-\\ \\#0]*[0-9\\*]*(.[0-9\\*]+)?[hlL]?[cdieEfgGosuxXpn%])", "g");
|
||||
var sprintfTagRegex = new RegExp("(%)([\\+\\-\\ \\#0]*)([0-9\\*]*)((.[0-9\\*]+)?)([hlL]?)([cdieEfgGosuxXpn%])");
|
||||
|
||||
/**
|
||||
/*
|
||||
Creates a new string using C printf-style formatting. First argument should be a constant format string, like ' "float val = %f" ', remaining arguments should be the variables to print the values of, comma-separated.
|
||||
@param format the format to be used, printf-style
|
||||
@return the initialized <objj>CPString</objj>
|
||||
*/
|
||||
*/
|
||||
function sprintf(format)
|
||||
{
|
||||
var format = arguments[0],
|
||||
|
||||
@@ -340,7 +340,7 @@ function CPPropertyListCreateFromXMLData(XMLNodeOrData)
|
||||
if (XMLNode.string)
|
||||
{
|
||||
#if RHINO
|
||||
XMLNode = DOCUMENT_ELEMENT(Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
|
||||
XMLNode = DOCUMENT_ELEMENT(_documentBuilder.parse(
|
||||
new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(XMLNode.string))));
|
||||
#else
|
||||
if (window.ActiveXObject)
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import <Foundation/CPString.j>
|
||||
|
||||
@implementation CPStringTest : OJTestCase
|
||||
|
||||
|
||||
- (void)testStringByReplacingOccurrencesOfStringWithString
|
||||
{
|
||||
var expectedString = @"hello world. A new world!";
|
||||
var dummyString = @"hello woold. A new woold!";
|
||||
var actualString = [dummyString stringByReplacingOccurrencesOfString:@"woold" withString:@"world"];
|
||||
[self assertTrue:(expectedString === actualString)
|
||||
message:"stringByAppendingFormat: expected:" + expectedString + " actual:" + actualString];
|
||||
|
||||
|
||||
|
||||
}
|
||||
- (void)testStringByAppendingFormat
|
||||
{
|
||||
var format = @"%d X %d = %d";
|
||||
var expectedString = "2 X 3 = 6";
|
||||
var dummyString = @"";
|
||||
var actualString = [dummyString stringByAppendingFormat:format ,2 ,3 ,6];
|
||||
[self assertTrue:(expectedString === actualString)
|
||||
message:"stringByAppendingFormat: expected:" + expectedString + " actual:" + actualString];
|
||||
|
||||
}
|
||||
- (void) testBoolValue
|
||||
{
|
||||
var testString = @" 090";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" YES";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" true";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" True";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" tTR";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" +98";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" -98";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" +08";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" -98";
|
||||
[self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
|
||||
|
||||
testString = @" NO";
|
||||
[self assertFalse:[testString boolValue] message:"boolValue for the string " + testString + " should return false"];
|
||||
|
||||
testString = @" -N00";
|
||||
[self assertFalse:[testString boolValue] message:"boolValue for the string " + testString + " should return false"];
|
||||
|
||||
testString = @" 00";
|
||||
[self assertFalse:[testString boolValue] message:"boolValue for the string " + testString + " should return false"];
|
||||
|
||||
testString = @" -00";
|
||||
[self assertFalse:[testString boolValue] message:"boolValue for the string " + testString + " should return false"];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
+29
-14
@@ -107,11 +107,11 @@ if (typeof readFile == "undefined") {
|
||||
var f = new Packages.java.io.File(path);
|
||||
|
||||
if (!f.canRead()) {
|
||||
//alert("can't read: " + f.path)
|
||||
alert("can't read: " + f.path)
|
||||
return "";
|
||||
}
|
||||
|
||||
//alert("reading: " + f.getAbsolutePath());
|
||||
alert("reading: " + f.getAbsolutePath());
|
||||
|
||||
var fis = new Packages.java.io.FileInputStream(f);
|
||||
|
||||
@@ -119,12 +119,11 @@ if (typeof readFile == "undefined") {
|
||||
fis.read(b);
|
||||
|
||||
fis.close();
|
||||
|
||||
//return String(new Packages.java.lang.String(b));
|
||||
|
||||
if (characterCoding)
|
||||
return new Packages.java.lang.String(b, characterCoding);
|
||||
return String(new Packages.java.lang.String(b, characterCoding));
|
||||
else
|
||||
return new Packages.java.lang.String(b);
|
||||
return String(new Packages.java.lang.String(b));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -283,9 +282,25 @@ if (typeof Packages != "undefined") {
|
||||
}
|
||||
};
|
||||
|
||||
var xhr_builder = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
xhr_builder.setErrorHandler(function(exception, methodName) {
|
||||
//print("xml error!");
|
||||
var _documentBuilderFactory = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
|
||||
// setValidating to false doesn't seem to prevent it from downloading the DTD, but lets do it anyway
|
||||
_documentBuilderFactory.setValidating(false);
|
||||
|
||||
_documentBuilder = _documentBuilderFactory.newDocumentBuilder();
|
||||
// prevent the Java XML parser from downloading the plist DTD from Apple every time we parse a plist
|
||||
_documentBuilder.setEntityResolver(new Packages.org.xml.sax.EntityResolver({
|
||||
resolveEntity: function(publicId, systemId) {
|
||||
//Packages.java.lang.System.out.println("publicId=" + publicId + " systemId=" + systemId);
|
||||
|
||||
// TODO: return a local copy of the DTD?
|
||||
if (String(systemId) == "http://www.apple.com/DTDs/PropertyList-1.0.dtd")
|
||||
return new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(""));
|
||||
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
// throw an exception on error
|
||||
_documentBuilder.setErrorHandler(function(exception, methodName) {
|
||||
throw exception;
|
||||
});
|
||||
|
||||
@@ -372,7 +387,7 @@ if (typeof Packages != "undefined") {
|
||||
}
|
||||
|
||||
parseXMLString = function(string) {
|
||||
return (Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
|
||||
return (_documentBuilder.parse(
|
||||
new Packages.org.xml.sax.InputSource(
|
||||
new Packages.java.io.StringReader(string))).getDocumentElement());
|
||||
}
|
||||
@@ -435,23 +450,23 @@ XMLHttpRequest.prototype.send = function(body) {
|
||||
|
||||
try {
|
||||
this.responseText = readFile(this.url);
|
||||
alert("xhr: " + this.url);
|
||||
alert("xhr response: " + this.url + " (length="+this.responseText.length+")");
|
||||
} catch (e) {
|
||||
alert("read exception: " + this.url);
|
||||
alert("xhr exception: " + this.url);
|
||||
this.responseText = "";
|
||||
this.responseXML = null;
|
||||
}
|
||||
|
||||
if (this.responseText.length > 0) {
|
||||
try {
|
||||
this.responseXML = xhr_builder.parse(new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(this.responseText)));
|
||||
this.responseXML = _documentBuilder.parse(new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(this.responseText)));
|
||||
} catch (e) {
|
||||
this.responseXML = null;
|
||||
}
|
||||
this.status = 200;
|
||||
}
|
||||
else {
|
||||
alert("empty file: " + this.url);
|
||||
alert("xhr empty: " + this.url);
|
||||
this.status = 404;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
import <AppKit/CPCustomView.j>
|
||||
import <AppKit/_CPCibCustomView.j>
|
||||
|
||||
import "NSView.j"
|
||||
|
||||
|
||||
Reference in new issue
Block a user