diff --git a/AppKit/CPApplication.j b/AppKit/CPApplication.j index 717d02993..76e65a768 100644 --- a/AppKit/CPApplication.j +++ b/AppKit/CPApplication.j @@ -814,6 +814,12 @@ CPRunContinuesResponse = -1002; return [_documentController openDocumentWithContentsOfURL:aFilename display:YES error:NULL]; } +- (void)_didResignActive +{ + if (self._activeMenu) + [self._activeMenu cancelTracking]; +} + @end var _CPModalSessionMake = function(aWindow, aStopCode) diff --git a/AppKit/CPDocument.j b/AppKit/CPDocument.j index abf06fb9c..57f77452c 100644 --- a/AppKit/CPDocument.j +++ b/AppKit/CPDocument.j @@ -460,7 +460,12 @@ var CPDocumentUntitledCount = 0; _writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL]; - [_writeRequest setHTTPMethod:@"PUT"]; + // FIXME: THIS IS WRONG! We need a way to decide + if ([CPPlatform isBrowser]) + [_writeRequest setHTTPMethod:@"POST"]; + else + [_writeRequest setHTTPMethod:@"PUT"]; + [_writeRequest setHTTPBody:[data string]]; [_writeRequest setValue:@"close" forHTTPHeaderField:@"Connection"]; diff --git a/AppKit/CPMenu.j b/AppKit/CPMenu.j index 52376975f..3c899a024 100644 --- a/AppKit/CPMenu.j +++ b/AppKit/CPMenu.j @@ -30,6 +30,7 @@ @import "CPMenuItem.j" @import "CPPanel.j" +#include "CoreGraphics/CGGeometry.h" #include "Platform/Platform.h" @@ -738,7 +739,21 @@ var _CPMenuBarVisible = NO, */ - (void)cancelTracking { - [_menuWindow cancelTracking]; + [[CPRunLoop currentRunLoop] performSelector:@selector(_fireCancelTrackingEvent) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]]; +} + +- (void)_fireCancelTrackingEvent +{ + [CPApp sendEvent:[CPEvent + otherEventWithType:CPAppKitDefined + location:_CGPointMakeZero() + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:0 + subtype:0 + data1:0 + data2:0]]; } /* @ignore */ @@ -767,7 +782,7 @@ var _CPMenuBarVisible = NO, { var item = _items[index], modifierMask = [item keyEquivalentModifierMask]; - + if ((modifierFlags & (CPShiftKeyMask | CPAlternateKeyMask | CPCommandKeyMask | CPControlKeyMask)) == modifierMask && [characters caseInsensitiveCompare:[item keyEquivalent]] == CPOrderedSame) { @@ -928,7 +943,7 @@ var STICKY_TIME_INTERVAL = 500, */ @implementation _CPMenuWindow : CPWindow { - _CPMenuView _menuView; + _CPMenuView _menuView; CPClipView _menuClipView; CPView _lastMouseOverMenuView; @@ -1178,13 +1193,10 @@ var STICKY_TIME_INTERVAL = 500, [_menuView scrollPoint:CGPointMake(0.0, [self convertBaseToGlobal:clipFrame.origin].y - menuViewOrigin.y)]; } -- (void)cancelTracking -{ - _trackingCanceled = YES; -} - - (void)beginTrackingWithEvent:(CPEvent)anEvent sessionDelegate:(id)aSessionDelegate didEndSelector:(SEL)aDidEndSelector { + CPApp._activeMenu = [_menuView menu]; + _startTime = [anEvent timestamp];//new Date(); _scrollingState = _CPMenuWindowScrollingStateNone; _trackingCanceled = NO; @@ -1198,7 +1210,41 @@ var STICKY_TIME_INTERVAL = 500, - (void)trackEvent:(CPEvent)anEvent { var type = [anEvent type], - theWindow = [anEvent window], + menu = [_menuView menu]; + + // Close Menu Event. + if (type === CPAppKitDefined) + { + // Stop all periodic events at this point. + [CPEvent stopPeriodicEvents]; + + var highlightedItem = [[_menuView menu] highlightedItem]; + + [menu _highlightItemAtIndex:CPNotFound]; + + [self orderOut:self]; + + var delegate = [menu delegate]; + + if ([delegate respondsToSelector:@selector(menuDidClose:)]) + [delegate menuDidClose:menu]; + + if (_sessionDelegate && _didEndSelector) + objj_msgSend(_sessionDelegate, _didEndSelector, self, highlightedItem); + + [[CPNotificationCenter defaultCenter] + postNotificationName:CPMenuDidEndTrackingNotification + object:menu]; + + // Clear these now so its faster next time around. + [_menuView setMenu:nil]; + + CPApp._activeMenu = nil; + + return; + } + + var theWindow = [anEvent window], globalLocation = theWindow ? [theWindow convertBaseToGlobal:[anEvent locationInWindow]] : [anEvent locationInWindow]; if (type === CPPeriodic) @@ -1222,8 +1268,7 @@ var STICKY_TIME_INTERVAL = 500, _lastGlobalLocation = globalLocation; - var menu = [_menuView menu], - menuLocation = [self convertGlobalToBase:globalLocation], + var menuLocation = [self convertGlobalToBase:globalLocation], activeItemIndex = [_menuView itemIndexAtPoint:[_menuView convertPoint:menuLocation fromView:nil]], mouseOverMenuView = [[menu itemAtIndex:activeItemIndex] view]; @@ -1279,47 +1324,11 @@ var STICKY_TIME_INTERVAL = 500, else if (oldScrollingState == _CPMenuWindowScrollingStateNone) [CPEvent startPeriodicEventsAfterDelay:0.0 withPeriod:0.04]; } - else if (type == CPLeftMouseUp && ([anEvent timestamp] - _startTime > STICKY_TIME_INTERVAL)) - { - // Stop these if they're still goin'. - if (_scrollingState != _CPMenuWindowScrollingStateNone) - [CPEvent stopPeriodicEvents]; - - [self cancelTracking]; - } + [menu cancelTracking]; } - - if (_trackingCanceled) - { - // Stop all periodic events at this point. - [CPEvent stopPeriodicEvents]; - - var highlightedItem = [[_menuView menu] highlightedItem]; - - [menu _highlightItemAtIndex:CPNotFound]; - - [self orderOut:self]; - var delegate = [menu delegate]; - - if ([delegate respondsToSelector:@selector(menuDidClose:)]) - [delegate menuDidClose:menu]; - - if (_sessionDelegate && _didEndSelector) - objj_msgSend(_sessionDelegate, _didEndSelector, self, highlightedItem); - - [[CPNotificationCenter defaultCenter] - postNotificationName:CPMenuDidEndTrackingNotification - object:menu]; - - // Clear these now so its faster next time around. - [_menuView setMenu:nil]; - - return; - } - - [CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask untilDate:nil inMode:nil dequeue:YES]; + [CPApp setTarget:self selector:@selector(trackEvent:) forNextEventMatchingMask:CPPeriodicMask | CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask | CPAppKitDefinedMask untilDate:nil inMode:nil dequeue:YES]; } @end @@ -1492,7 +1501,8 @@ var _CPMenuBarWindowBackgroundColor = nil, - (id)init { - var contentRect = [CPPlatform isBrowser] ? [[CPPlatformWindow primaryPlatformWindow] contentBounds] : [[self screen] visibleFrame]; + // This only shows up in browser land, so don't bother calculating metrics in desktop. + var contentRect = [[CPPlatformWindow primaryPlatformWindow] contentBounds]; contentRect.size.height = MENUBAR_HEIGHT; @@ -1501,9 +1511,7 @@ var _CPMenuBarWindowBackgroundColor = nil, if (self) { // FIXME: http://280north.lighthouseapp.com/projects/13294-cappuccino/tickets/39-dont-allow-windows-to-go-above-menubar - if ([CPPlatform isBrowser]) - [self setLevel:-1];//CPTornOffMenuWindowLevel]; - + [self setLevel:-1];//CPTornOffMenuWindowLevel]; [self setAutoresizingMask:CPWindowWidthSizable]; var contentView = [self contentView]; @@ -1971,11 +1979,14 @@ var _CPMenuBarWindowBackgroundColor = nil, } } -- (void)setFrameSize:(CGSize)aSize +- (void)setFrame:(CGRect)aRect display:(BOOL)shouldDisplay animate:(BOOL)shouldAnimate { - [super setFrameSize:aSize]; - - [self tile]; + var size = [self frame].size; + + [super setFrame:aRect display:shouldDisplay animate:shouldAnimate]; + + if (_CGSizeEqualToSize(size, aRect.size)) + [self tile]; } @end diff --git a/AppKit/CPOpenPanel.j b/AppKit/CPOpenPanel.j index 8cff33aed..e8c2fe676 100644 --- a/AppKit/CPOpenPanel.j +++ b/AppKit/CPOpenPanel.j @@ -1,6 +1,5 @@ @import -#include "Platform/Platform.h" @implementation CPOpenPanel : CPPanel @@ -19,19 +18,24 @@ - (CPInteger)runModal { - // FIXME: Is this correct??? - [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; + if (typeof window["cpOpenPanel"] === "function") + { + // FIXME: Is this correct??? + [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; - var options = { directoryURL: [self directoryURL], - canChooseFiles: [self canChooseFiles], - canChooseDirectories: [self canChooseDirectories], - allowsMultipleSelection: [self allowsMultipleSelection] }; + var options = { directoryURL: [self directoryURL], + canChooseFiles: [self canChooseFiles], + canChooseDirectories: [self canChooseDirectories], + allowsMultipleSelection: [self allowsMultipleSelection] }; - var result = window.cpOpenPanel(options); + var result = window.cpOpenPanel(options); - _URLs = result.URLs; + _URLs = result.URLs; - return result.button; + return result.button; + } + + throw "-runModal is unimplemented."; } - (CPArray)URLs diff --git a/AppKit/CPSavePanel.j b/AppKit/CPSavePanel.j index bc99c3699..f8e888d8d 100644 --- a/AppKit/CPSavePanel.j +++ b/AppKit/CPSavePanel.j @@ -4,7 +4,7 @@ @implementation CPSavePanel : CPPanel { - Object result; + CPURL _URL; } + (id)savePanel @@ -17,14 +17,28 @@ // FIXME: Is this correct??? [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; - result = window.cpSavePanel(); + if (typeof window["cpSavePanel"] === "function") + { + var resultObject = window.cpSavePanel(), + result = resultObject.button; - return result.button; + _URL = result ? [CPURL URLWithString:resultObject.URL] : nil; + } + else + { + // FIXME: This is not the best way to do this. + var documentName = window.prompt("Document Name:"), + result = documentName !== null; + + _URL = result ? [[self class] proposedFileURLWithDocumentName:documentName] : nil; + } + + return result; } - (CPURL)URL { - return [CPURL URLWithString:result.URL]; + return _URL; } @end diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 66ad3d3e6..60dd53a3d 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -260,9 +260,11 @@ var CPTabViewDidSelectTabViewItemSelector = 1, */ - (void)removeTabViewItem:(CPTabViewItem)aTabViewItem { + var index = [self indexOfTabViewItem:aTabViewItem]; + [_tabViewItems removeObjectIdenticalTo:aTabViewItem]; - [_labelsView tabView:self didRemoveTabViewItem:aTabViewItem]; + [_labelsView tabView:self didRemoveTabViewItemAtIndex:index]; if (_delegateSelectors & CPTabViewDidChangeNumberOfTabViewItemsSelector) [_delegate tabViewDidChangeNumberOfTabViewItems:self]; @@ -648,10 +650,9 @@ var _CPTabLabelsViewBackgroundColor = nil, [self layoutSubviews]; } -- (void)tabView:(CPTabView)aTabView didRemoveTabViewItem:(CPTabViewItem)aTabViewItem +- (void)tabView:(CPTabView)aTabView didRemoveTabViewItemAtIndex:(unsigned)index { - var index = [aTabView indexOfTabViewItem:aTabViewItem], - label = _tabLabels[index]; + var label = _tabLabels[index]; [_tabLabels removeObjectAtIndex:index]; diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 0303ee1bb..7994ab75f 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -597,14 +597,14 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); window.setTimeout(function() { - element.value = [self stringValue]; element.focus(); CPTextFieldInputOwner = self; }, 0.0); //post CPControlTextDidBeginEditingNotification [self textDidBeginEditing:[CPNotification notificationWithName:CPControlTextDidBeginEditingNotification object:self userInfo:nil]]; - + element.value = [self stringValue]; + [[[self window] platformWindow] _propagateCurrentDOMEvent:YES]; CPTextFieldInputIsActive = YES; diff --git a/AppKit/Platform/DOM/CPDOMWindowLayer.j b/AppKit/Platform/DOM/CPDOMWindowLayer.j index 3d6f3dede..a41fa4cc9 100644 --- a/AppKit/Platform/DOM/CPDOMWindowLayer.j +++ b/AppKit/Platform/DOM/CPDOMWindowLayer.j @@ -68,7 +68,7 @@ count = _windows.length - 1; CPDOMDisplayServerRemoveChild(_DOMElement, aWindow._DOMElement); - + [_windows removeObjectAtIndex:aWindow._index]; for (; index < count; ++index) @@ -107,11 +107,12 @@ _windows[zIndex]._index = zIndex; _windows[zIndex]._DOMElement.style.zIndex = zIndex; } + // If the window is not already a resident of this layer, add it. - if (!isVisible) + if (aWindow._DOMElement.parentNode !== _DOMElement) { CPDOMDisplayServerAppendChild(_DOMElement, aWindow._DOMElement); - + aWindow._isVisible = YES; if ([aWindow isFullBridge]) diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index 49a4cab15..5733dac6c 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -192,6 +192,8 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; // Make sure the pastboard element is blurred. _DOMPasteboardElement.blur(); + [self _addLayers]; + var theClass = [self class], dragEventImplementation = class_getMethodImplementation(theClass, @selector(dragEvent:)), @@ -250,6 +252,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMWindow.addEventListener("unload", function() { [self updateFromNativeContentRect]; + [self _removeLayers]; theDocument.removeEventListener("mouseup", mouseEventCallback, NO); theDocument.removeEventListener("mousedown", mouseEventCallback, NO); @@ -296,6 +299,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMWindow.attachEvent("onbeforeunload", function() { [self updateFromNativeContentRect]; + [self _removeLayers]; theDocument.removeEvent("onmouseup", mouseEventCallback); theDocument.removeEvent("onmousedown", mouseEventCallback); @@ -334,6 +338,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; if (![CPPlatform isBrowser]) { + _DOMWindow.cpWindowNumber = [self._only windowNumber]; _DOMWindow.cpSetFrame(_contentRect); _DOMWindow.cpSetLevel(_level); _DOMWindow.cpSetHasShadow(_hasShadow); @@ -904,6 +909,34 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; [layer insertWindow:aWindow atIndex:(otherWindow ? (aPlace == CPWindowAbove ? otherWindow._index + 1 : otherWindow._index) : CPNotFound)]; } +- (void)_removeLayers +{ + var levels = _windowLevels, + layers = _windowLayers, + levelCount = levels.length; + + while (levelCount--) + { + var layer = [layers objectForKey:levels[levelCount]]; + + _DOMBodyElement.removeChild(layer._DOMElement); + } +} + +- (void)_addLayers +{ + var levels = _windowLevels, + layers = _windowLayers, + levelCount = levels.length; + + while (levelCount--) + { + var layer = [layers objectForKey:levels[levelCount]]; + + _DOMBodyElement.appendChild(layer._DOMElement); + } +} + /* @ignore */ - (id)_dragHitTest:(CPPoint)aPoint pasteboard:(CPPasteboard)aPasteboard { diff --git a/Tests/Foundation/CPExceptionTest.j b/Tests/Foundation/CPExceptionTest.j new file mode 100644 index 000000000..6451e32b5 --- /dev/null +++ b/Tests/Foundation/CPExceptionTest.j @@ -0,0 +1,49 @@ +@import + +@implementation CPExceptionTest : OJTestCase +{ +} + +- (void)setUp +{ + exception = [CPException exceptionWithName:@"CPGenericException" + reason:@"Margins must be positive" + userInfo:nil]; +} + +- (void)testInitWithNameReasonUserInfo +{ + var exception = [[CPException alloc] initWithName:@"CPUnsupportedMethodException" + reason:@"setHeaderCell: is not supported. -setHeaderCell:aView instead." + userInfo:nil]; + [self assert:[exception name] equals:"CPUnsupportedMethodException"]; + [self assert:[exception reason] equals:"setHeaderCell: is not supported. -setHeaderCell:aView instead."]; + [self assertThrows:function(){[exception raise]}]; +} + +- (void)testRaiseReason +{ + [self assertThrows:function(){[CPException raise:@"CPGenericException" reason:@"Margins must be positive"];}]; +} + +- (void)testName +{ + [self assert:[exception name] equals:@"CPGenericException"]; +} + +- (void)testReason +{ + [self assert:[exception reason] equals:@"Margins must be positive"]; +} + +- (void)testUserInfo +{ + [self assert:[exception userInfo] equals:null]; +} + +- (void)testRaise +{ + [self assertThrows:function(){[exception raise];}]; +} + +@end