diff --git a/AppKit/CPSplitView.j b/AppKit/CPSplitView.j index d7c2bb72e..70f1a9282 100644 --- a/AppKit/CPSplitView.j +++ b/AppKit/CPSplitView.j @@ -217,10 +217,9 @@ var CPSplitViewHorizontalImage = nil, _DOMDividerElements[_drawingDivider].style.backgroundRepeat = "repeat"; CPDOMDisplayServerAppendChild(_DOMElement, _DOMDividerElements[_drawingDivider]); - - [self _setupDOMDivider]; } + [self _setupDOMDivider]; CPDOMDisplayServerSetStyleLeftTop(_DOMDividerElements[_drawingDivider], NULL, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect)); CPDOMDisplayServerSetStyleSize(_DOMDividerElements[_drawingDivider], _CGRectGetWidth(aRect), _CGRectGetHeight(aRect)); #endif diff --git a/AppKit/CPWebView.j b/AppKit/CPWebView.j index 38ddfb5fa..cd4876675 100644 --- a/AppKit/CPWebView.j +++ b/AppKit/CPWebView.j @@ -187,7 +187,7 @@ CPWebViewScrollNative = 2; var win = null; try { win = [self DOMWindow]; } catch (e) {} - if (win && win.document) + if (win && win.document && win.document.body) { var width = win.document.body.scrollWidth, height = win.document.body.scrollHeight; diff --git a/AppKit/CPWindow/CPWindow.j b/AppKit/CPWindow/CPWindow.j index 209f6e769..f06953ab1 100644 --- a/AppKit/CPWindow/CPWindow.j +++ b/AppKit/CPWindow/CPWindow.j @@ -1933,7 +1933,8 @@ CPTexturedBackgroundWindowMask [keyWindow makeKeyWindow]; else { - var menuWindow = [CPApp mainMenu]._menuWindow; + var mainMenu = [CPApp mainMenu], + menuWindow = mainMenu ? mainMenu._menuWindow : nil; for (var i = 0; i < windowCount; i++) { var currentWindow = allWindows[i]; @@ -1961,7 +1962,8 @@ CPTexturedBackgroundWindowMask [mainWindow makeMainWindow]; else { - var menuWindow = [CPApp mainMenu]._menuWindow; + var mainMenu = [CPApp mainMenu], + menuWindow = mainMenu ? mainMenu._menuWindow : nil; for (var i = 0; i < windowCount; i++) { var currentWindow = allWindows[i]; diff --git a/AppKit/Cib/CPCibLoading.j b/AppKit/Cib/CPCibLoading.j index aa7007556..22543eddc 100644 --- a/AppKit/Cib/CPCibLoading.j +++ b/AppKit/Cib/CPCibLoading.j @@ -37,12 +37,12 @@ var CPCibOwner = @"CPCibOwner"; @implementation CPBundle (CPCibLoading) -+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable ++ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable { - [[[CPCib alloc] initWithContentsOfURL:anAbsolutePath] instantiateCibWithExternalNameTable:aNameTable]; + return [[[CPCib alloc] initWithContentsOfURL:anAbsolutePath] instantiateCibWithExternalNameTable:aNameTable]; } -+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner ++ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner { if (![aName hasSuffix:@".cib"]) aName = [aName stringByAppendingString:@".cib"]; @@ -51,24 +51,24 @@ var CPCibOwner = @"CPCibOwner"; var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle], path = [bundle pathForResource:aName]; - [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]]; + return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]]; } -- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable +- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable { - [[[CPCib alloc] initWithContentsOfURL:aFileName] instantiateCibWithExternalNameTable:aNameTable]; + return [[[CPCib alloc] initWithContentsOfURL:aFileName] instantiateCibWithExternalNameTable:aNameTable]; } -+ (void)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate ++ (CPCib)loadCibFile:(CPString)anAbsolutePath externalNameTable:(CPDictionary)aNameTable loadDelegate:aDelegate { - [[CPCib alloc] + return ([[CPCib alloc] initWithContentsOfURL:anAbsolutePath loadDelegate:[[_CPCibLoadDelegate alloc] initWithLoadDelegate:aDelegate - externalNameTable:aNameTable]]; + externalNameTable:aNameTable]]); } -+ (void)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate ++ (CPCib)loadCibNamed:(CPString)aName owner:(id)anOwner loadDelegate:(id)aDelegate { if (![aName hasSuffix:@".cib"]) aName = [aName stringByAppendingString:@".cib"]; @@ -77,17 +77,17 @@ var CPCibOwner = @"CPCibOwner"; var bundle = anOwner ? [CPBundle bundleForClass:[anOwner class]] : [CPBundle mainBundle], path = [bundle pathForResource:aName]; - [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate]; + return [self loadCibFile:path externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner] loadDelegate:aDelegate]; } -- (void)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate +- (CPCib)loadCibFile:(CPString)aFileName externalNameTable:(CPDictionary)aNameTable loadDelegate:(id)aDelegate { - [[CPCib alloc] + return ([[CPCib alloc] initWithCibNamed:aFileName bundle:self loadDelegate:[[_CPCibLoadDelegate alloc] initWithLoadDelegate:aDelegate - externalNameTable:aNameTable]]; + externalNameTable:aNameTable]]); } @end diff --git a/Foundation/CPArray.j b/Foundation/CPArray.j index 3c87f114a..f4f8be793 100755 --- a/Foundation/CPArray.j +++ b/Foundation/CPArray.j @@ -145,10 +145,10 @@ { var i = 2, array = [[self alloc] init], - argument; + count = arguments.length; - for (; i < arguments.length && (argument = arguments[i]) != nil; ++i) - array.push(argument); + for (; i < count; ++i) + array.push(arguments[i]); return array; } @@ -229,10 +229,10 @@ { // The arguments array contains self and _cmd, so the first object is at position 2. var i = 2, - argument; + count = arguments.length; - for (; i < arguments.length && (argument = arguments[i]) != nil; ++i) - push(argument); + for (; i < count; ++i) + push(arguments[i]); return self; } @@ -278,21 +278,18 @@ /*! Returns the index of \c anObject in this array. - If the object is \c nil or not in the array, + If the object is not in the array, returns \c CPNotFound. It first attempts to find - a match using \c -isEqual:, then \c ==. + a match using \c -isEqual:, then \c ===. @param anObject the object to search for */ - (int)indexOfObject:(id)anObject { - if (anObject === nil) - return CPNotFound; - var i = 0, count = length; // Only use -isEqual: if our object is a CPObject. - if (anObject.isa) + if (anObject && anObject.isa) { for (; i < count; ++i) if ([self[i] isEqual:anObject]) @@ -305,7 +302,7 @@ // Last resort, do a straight forward linear O(N) search. else for (; i < count; ++i) - if (self[i] == anObject) + if (self[i] === anObject) return i; return CPNotFound; @@ -314,21 +311,18 @@ /*! Returns the index of \c anObject in the array within \c aRange. It first attempts to find - a match using \c -isEqual:, then \c ==. + a match using \c -isEqual:, then \c ===. @param anObject the object to search for @param aRange the range to search within @return the index of the object, or \c CPNotFound if it was not found. */ - (int)indexOfObject:(id)anObject inRange:(CPRange)aRange { - if (anObject === nil) - return CPNotFound; - var i = aRange.location, count = MIN(CPMaxRange(aRange), length); // Only use isEqual: if our object is a CPObject. - if (anObject.isa) + if (anObject && anObject.isa) { for (; i < count; ++i) if ([self[i] isEqual:anObject]) @@ -337,22 +331,19 @@ // Last resort, do a straight forward linear O(N) search. else for (; i < count; ++i) - if (self[i] == anObject) + if (self[i] === anObject) return i; return CPNotFound; } /*! - Returns the index of \c anObject in the array. The test for equality is done using only \c ==. + Returns the index of \c anObject in the array. The test for equality is done using only \c ===. @param anObject the object to search for @return the index of the object in the array. \c CPNotFound if the object is not in the array. */ - (int)indexOfObjectIdenticalTo:(id)anObject { - if (anObject === nil) - return CPNotFound; - // If indexOf exists, use it since it's probably // faster than anything we can implement. if (self.indexOf) @@ -382,9 +373,6 @@ */ - (int)indexOfObjectIdenticalTo:(id)anObject inRange:(CPRange)aRange { - if (anObject === nil) - return CPNotFound; - // If indexOf exists, use it since it's probably // faster than anything we can implement. if (self.indexOf) @@ -460,7 +448,7 @@ - (unsigned)_indexOfObject:(id)anObject sortedByFunction:(Function)aFunction context:(id)aContext { - if (!aFunction || anObject === undefined) + if (!aFunction) return CPNotFound; if (length === 0) @@ -523,7 +511,8 @@ { var count = [self count]; - if (!count) return nil; + if (!count) + return nil; return self[count - 1]; } @@ -697,12 +686,7 @@ */ - (CPArray)arrayByAddingObject:(id)anObject { - if (anObject === nil || anObject === undefined) - [CPException raise:CPInvalidArgumentException - reason:"arrayByAddingObject: object can't be nil"]; - var array = [self copy]; - array.push(anObject); return array; diff --git a/Foundation/CPRunLoop.j b/Foundation/CPRunLoop.j index 0884e4915..a68eead71 100644 --- a/Foundation/CPRunLoop.j +++ b/Foundation/CPRunLoop.j @@ -157,6 +157,7 @@ var CPRunLoopLastNativeRunLoop = 0; CPDate _effectiveDate; CPArray _orderedPerforms; + int _runLoopInsuranceTimer; } /* @@ -267,6 +268,12 @@ var CPRunLoopLastNativeRunLoop = 0; aTimer._lastNativeRunLoopsForModes = {}; aTimer._lastNativeRunLoopsForModes[aMode] = CPRunLoopLastNativeRunLoop; + + if (!_runLoopInsuranceTimer) + _runLoopInsuranceTimer = window.setNativeTimeout(function() + { + [self limitDateForMode:CPDefaultRunLoopMode]; + }, 0); } /*! @@ -277,9 +284,15 @@ var CPRunLoopLastNativeRunLoop = 0; //simple locking to try to prevent concurrent iterating over timers if (_runLoopLock) return; - + _runLoopLock = YES; - + + if (_runLoopInsuranceTimer) + { + window.clearNativeTimeout(_runLoopInsuranceTimer); + _runLoopInsuranceTimer = nil; + } + var now = _effectiveDate ? [_effectiveDate laterDate:[CPDate date]] : [CPDate date], nextFireDate = nil, nextTimerFireDate = _nextTimerFireDatesForModes[aMode]; diff --git a/Objective-J/CFHTTPRequest.js b/Objective-J/CFHTTPRequest.js index d4f9cba76..de32c1897 100644 --- a/Objective-J/CFHTTPRequest.js +++ b/Objective-J/CFHTTPRequest.js @@ -92,15 +92,22 @@ if (!NativeRequest) GLOBAL(CFHTTPRequest) = function() { + this._requestHeaders = {}; + this._mimeType = null; + this._eventDispatcher = new EventDispatcher(this); this._nativeRequest = new NativeRequest(); var self = this; - - this._nativeRequest.onreadystatechange = function() + this._stateChangeHandler = function() { determineAndDispatchHTTPRequestEvents(self); } + + this._nativeRequest.onreadystatechange = this._stateChangeHandler; + + if (CFHTTPRequest.AuthenticationDelegate !== nil) + this._eventDispatcher.addEventListener("HTTP403", function(){CFHTTPRequest.AuthenticationDelegate(self)}); } CFHTTPRequest.UninitializedState = 0; @@ -109,6 +116,9 @@ CFHTTPRequest.LoadedState = 2; CFHTTPRequest.InteractiveState = 3; CFHTTPRequest.CompleteState = 4; +//override to forward all CFHTTPRequest authorization failures to a single function +CFHTTPRequest.AuthenticationDelegate = nil; + CFHTTPRequest.prototype.status = function() { try @@ -177,7 +187,7 @@ CFHTTPRequest.prototype.responseText = function() CFHTTPRequest.prototype.setRequestHeader = function(/*String*/ aHeader, /*Object*/ aValue) { - return this._nativeRequest.setRequestHeader(aHeader, aValue); + this._requestHeaders[aHeader] = aValue; } CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader) @@ -192,17 +202,35 @@ CFHTTPRequest.prototype.getAllResponseHeaders = function() CFHTTPRequest.prototype.overrideMimeType = function(/*String*/ aMimeType) { - if ("overrideMimeType" in this._nativeRequest) - return this._nativeRequest.overrideMimeType(aMimeType); + this._mimeType = aMimeType; } CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*Boolean*/ isAsynchronous, /*String*/ aUser, /*String*/ aPassword) { + this._URL = aURL; + this._async = isAsynchronous; + this._method = aMethod; + this._user = aUser; + this._password = aPassword; return this._nativeRequest.open(aMethod, aURL, isAsynchronous, aUser, aPassword); } CFHTTPRequest.prototype.send = function(/*Object*/ aBody) { + delete this._nativeRequest.onreadystatechange; + + for (var i in this._requestHeaders) + { + if (this._requestHeaders.hasOwnProperty(i)) + this._nativeRequest.setRequestHeader(i, this._requestHeaders[i]); + } + + if (this._mimeType && "overrideMimeType" in this._nativeRequest) + this._nativeRequest.overrideMimeType(this._mimeType); + + this._nativeRequest.open(this._method, this._URL, this._async, this._user, this._password); + this._nativeRequest.onreadystatechange = this._stateChangeHandler; + try { return this._nativeRequest.send(aBody); @@ -236,20 +264,20 @@ function determineAndDispatchHTTPRequestEvents(/*CFHTTPRequest*/ aRequest) eventDispatcher.dispatchEvent({ type:"readystatechange", request:aRequest}); var nativeRequest = aRequest._nativeRequest, - readyState = ["uninitialized", "loading", "loaded", "interactive", "complete"][aRequest.readyState()]; + readyStates = ["uninitialized", "loading", "loaded", "interactive", "complete"]; - eventDispatcher.dispatchEvent({ type:readyState, request:aRequest}); - - if (readyState === "complete") + if (readyStates[aRequest.readyState()] === "complete") { var status = "HTTP" + aRequest.status(); - eventDispatcher.dispatchEvent({ type:status, request:aRequest }); var result = aRequest.success() ? "success" : "failure"; - eventDispatcher.dispatchEvent({ type:result, request:aRequest }); + + eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest}); } + else + eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest}); } function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure) diff --git a/Tests/Foundation/CPArrayTest.j b/Tests/Foundation/CPArrayTest.j index f99ec7b78..75cc9cf01 100644 --- a/Tests/Foundation/CPArrayTest.j +++ b/Tests/Foundation/CPArrayTest.j @@ -21,8 +21,8 @@ - (void)testsInsertObjectsAtIndexes { - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four", nil], - newAdditions = [CPArray arrayWithObjects:@"a", @"b", nil], + var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"], + newAdditions = [CPArray arrayWithObjects:@"a", @"b"], indexes = [CPMutableIndexSet indexSetWithIndex:1]; [indexes addIndex:3]; @@ -31,8 +31,8 @@ [self assert:array equals:[@"one", @"a", @"two", @"b", @"three", @"four"]]; - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four", nil], - newAdditions = [CPArray arrayWithObjects:@"a", @"b", nil], + var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"], + newAdditions = [CPArray arrayWithObjects:@"a", @"b"], indexes = [CPMutableIndexSet indexSetWithIndex:5]; [indexes addIndex:4]; @@ -41,8 +41,8 @@ [self assert:array equals:[@"one", @"two", @"three", @"four", @"a", @"b"]]; - var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four", nil], - newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c", nil], + var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four"], + newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c"], indexes = [CPMutableIndexSet indexSetWithIndex:1]; [indexes addIndex:2]; @@ -53,8 +53,8 @@ [self assert:array equals:[@"one", @"a", @"b", @"two", @"c", @"three", @"four"]]; - var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four", nil], - newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c", nil], + var array = [CPMutableArray arrayWithObjects: @"one", @"two", @"three", @"four"], + newAdditions = [CPArray arrayWithObjects: @"a", @"b", @"c"], indexes = [CPMutableIndexSet indexSetWithIndex:1]; [indexes addIndex:2]; @@ -64,10 +64,9 @@ [self assert:array equals:[@"one", @"a", @"b", @"two", @"three", @"four", @"c"]]; - // - - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four", nil], - newAdditions = [CPArray arrayWithObjects:@"a", @"b", nil], + + var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"], + newAdditions = [CPArray arrayWithObjects:@"a", @"b"], indexes = [CPMutableIndexSet indexSetWithIndex:5]; [indexes addIndex:6]; @@ -88,10 +87,10 @@ { var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four", nil], indexes = [CPMutableIndexSet indexSetWithIndex: 2]; - + [array removeObjectsAtIndexes: indexes]; - - [self assert:array equals:[@"one", @"two", @"four"]]; + + [self assert:array equals:[@"one", @"two", @"four", nil]]; } - (void)testIndexOfObjectSortedByFunction diff --git a/Tests/Manual/LoadTimeTest/AppController.j b/Tests/Manual/LoadTimeTest/AppController.j index bd1f94618..1638643a2 100644 --- a/Tests/Manual/LoadTimeTest/AppController.j +++ b/Tests/Manual/LoadTimeTest/AppController.j @@ -28,7 +28,7 @@ if (data.length < 10) { // reload with data in the query string - window.location.href = [window.location.protocol, "//", window.location.host, window.location.port, window.location.pathname, "?", encodeURIComponent(JSON.stringify(data))].join(""); + window.location.href = [window.location.protocol, "//", window.location.host, window.location.pathname, "?", encodeURIComponent(JSON.stringify(data))].join(""); } else {