mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
Added HTML 5 drag and drop support for WebKit/Safari.
Reviewed by me.
This commit is contained in:
@@ -35,17 +35,18 @@ CPCSSRGBAFeature = 1 << 5;
|
||||
|
||||
CPHTMLCanvasFeature = 1 << 6;
|
||||
CPHTMLContentEditableFeature = 1 << 7;
|
||||
CPHTMLDragAndDropFeature = 1 << 8;
|
||||
|
||||
CPJavascriptInnerTextFeature = 1 << 8;
|
||||
CPJavascriptTextContentFeature = 1 << 9;
|
||||
CPJavascriptClipboardEventsFeature = 1 << 10;
|
||||
CPJavascriptClipboardAccessFeature = 1 << 11;
|
||||
CPJavaScriptCanvasDrawFeature = 1 << 12;
|
||||
CPJavaScriptCanvasTransformFeature = 1 << 13;
|
||||
CPJavascriptInnerTextFeature = 1 << 9;
|
||||
CPJavascriptTextContentFeature = 1 << 10;
|
||||
CPJavascriptClipboardEventsFeature = 1 << 11;
|
||||
CPJavascriptClipboardAccessFeature = 1 << 12;
|
||||
CPJavaScriptCanvasDrawFeature = 1 << 13;
|
||||
CPJavaScriptCanvasTransformFeature = 1 << 14;
|
||||
|
||||
CPVMLFeature = 1 << 14;
|
||||
CPVMLFeature = 1 << 15;
|
||||
|
||||
CPJavascriptRemedialKeySupport = 1 << 15;
|
||||
CPJavascriptRemedialKeySupport = 1 << 16;
|
||||
CPJavaScriptShadowFeature = 1 << 20;
|
||||
|
||||
CPJavaScriptNegativeMouseWheelValues = 1 << 22;
|
||||
@@ -54,7 +55,8 @@ CPJavaScriptMouseWheelValues_8_15 = 1 << 23
|
||||
CPOpacityRequiresFilterFeature = 1 << 24;
|
||||
|
||||
//Internet explorer does not allow dynamically changing the type of an input element
|
||||
CPInputTypeCanBeChangedFeature = 1 << 25;
|
||||
CPInputTypeCanBeChangedFeature = 1 << 25;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -100,6 +102,7 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1)
|
||||
// Features we can only be sure of with WebKit (no known independent tests)
|
||||
PLATFORM_FEATURES |= CPCSSRGBAFeature;
|
||||
PLATFORM_FEATURES |= CPHTMLContentEditableFeature;
|
||||
PLATFORM_FEATURES |= CPHTMLDragAndDropFeature;
|
||||
PLATFORM_FEATURES |= CPJavascriptClipboardEventsFeature;
|
||||
PLATFORM_FEATURES |= CPJavascriptClipboardAccessFeature;
|
||||
PLATFORM_FEATURES |= CPJavaScriptShadowFeature;
|
||||
|
||||
+222
-155
@@ -29,73 +29,25 @@
|
||||
#import "Platform/Platform.h"
|
||||
|
||||
|
||||
CPDragOperationNone = 0,
|
||||
CPDragOperationCopy = 1 << 1,
|
||||
CPDragOperationLink = 1 << 1,
|
||||
CPDragOperationGeneric = 1 << 2,
|
||||
CPDragOperationPrivate = 1 << 3,
|
||||
CPDragOperationMove = 1 << 4,
|
||||
CPDragOperationDelete = 1 << 5,
|
||||
CPDragOperationEvery = -1;
|
||||
|
||||
#define DRAGGING_WINDOW(anObject) ([anObject isKindOfClass:[CPWindow class]] ? anObject : [anObject window])
|
||||
|
||||
var CPSharedDragServer = nil;
|
||||
|
||||
var CPDragServerView = nil,
|
||||
CPDragServerSource = nil,
|
||||
CPDragServerWindow = nil,
|
||||
CPDragServerOffset = nil,
|
||||
CPDragServerLocation = nil,
|
||||
CPDragServerPasteboard = nil,
|
||||
CPDragServerDestination = nil,
|
||||
CPDragServerDraggingInfo = nil,
|
||||
CPDragServerPreviousEvent = nil,
|
||||
CPDragServerAutoscrollInterval = nil;
|
||||
|
||||
var CPDragServerIsDraggingImage = NO,
|
||||
|
||||
CPDragServerShouldSendDraggedViewMovedTo = NO,
|
||||
CPDragServerShouldSendDraggedImageMovedTo = NO,
|
||||
|
||||
CPDragServerShouldSendDraggedViewEndedAtOperation = NO,
|
||||
CPDragServerShouldSendDraggedImageEndedAtOperation = NO;
|
||||
|
||||
var CPDragServerPreviousEvent = nil,
|
||||
CPDragServerAutoscrollInterval = nil;
|
||||
/*
|
||||
var CPDragServerAutoscroll = function()
|
||||
{
|
||||
[CPDragServerSource autoscroll:CPDragServerPreviousEvent];
|
||||
}
|
||||
|
||||
var CPDragServerStartDragging = function(anEvent)
|
||||
{
|
||||
CPDragServerUpdateDragging(anEvent);
|
||||
}
|
||||
|
||||
var CPDragServerUpdateDragging = function(anEvent)
|
||||
{
|
||||
var globalLocation = [[anEvent window] convertBaseToGlobal:[anEvent locationInWindow]];
|
||||
|
||||
// If this is a mouse up, then complete the drag.
|
||||
if([anEvent type] == CPLeftMouseUp)
|
||||
{
|
||||
if (CPDragServerAutoscrollInterval !== nil)
|
||||
clearInterval(CPDragServerAutoscrollInterval);
|
||||
|
||||
CPDragServerAutoscrollInterval = nil;
|
||||
|
||||
CPDragServerLocation = [DRAGGING_WINDOW(CPDragServerDestination) convertGlobalToBase:globalLocation];
|
||||
|
||||
[CPDragServerView removeFromSuperview];
|
||||
[CPSharedDragServer._dragWindow orderOut:nil];
|
||||
|
||||
if (CPDragServerDestination &&
|
||||
(![CPDragServerDestination respondsToSelector:@selector(prepareForDragOperation:)] || [CPDragServerDestination prepareForDragOperation:CPDragServerDraggingInfo]) &&
|
||||
(![CPDragServerDestination respondsToSelector:@selector(performDragOperation:)] || [CPDragServerDestination performDragOperation:CPDragServerDraggingInfo]) &&
|
||||
[CPDragServerDestination respondsToSelector:@selector(concludeDragOperation:)])
|
||||
[CPDragServerDestination concludeDragOperation:CPDragServerDraggingInfo];
|
||||
|
||||
if (CPDragServerShouldSendDraggedImageEndedAtOperation)
|
||||
[CPDragServerSource draggedImage:[CPDragServerView image] endedAt:CPDragServerLocation operation:NO];
|
||||
else if (CPDragServerShouldSendDraggedViewEndedAtOperation)
|
||||
[CPDragServerSource draggedView:CPDragServerView endedAt:CPDragServerLocation operation:NO];
|
||||
|
||||
CPDragServerIsDraggingImage = NO;
|
||||
CPDragServerDestination = nil;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (CPDragServerAutoscrollInterval === nil)
|
||||
{
|
||||
if ([CPDragServerSource respondsToSelector:@selector(autoscroll:)])
|
||||
@@ -104,39 +56,16 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
|
||||
CPDragServerPreviousEvent = anEvent;
|
||||
|
||||
// If we're not a mouse up, then we're going to want to grab the next event.
|
||||
[CPApp setCallback:CPDragServerUpdateDragging
|
||||
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask
|
||||
untilDate:nil inMode:0 dequeue:NO];
|
||||
if (CPDragServerAutoscrollInterval !== nil)
|
||||
clearInterval(CPDragServerAutoscrollInterval);
|
||||
|
||||
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
|
||||
var draggingDestination = [[CPPlatformWindow primaryPlatformWindow] _dragHitTest:globalLocation pasteboard:CPDragServerPasteboard];
|
||||
CPDragServerAutoscrollInterval = nil;
|
||||
*/
|
||||
|
||||
CPDragServerLocation = [DRAGGING_WINDOW(draggingDestination) convertGlobalToBase:globalLocation];
|
||||
var CPSharedDragServer = nil;
|
||||
|
||||
if(draggingDestination !== CPDragServerDestination)
|
||||
{
|
||||
if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingExited:)])
|
||||
[CPDragServerDestination draggingExited:CPDragServerDraggingInfo];
|
||||
|
||||
CPDragServerDestination = draggingDestination;
|
||||
|
||||
if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingEntered:)])
|
||||
[CPDragServerDestination draggingEntered:CPDragServerDraggingInfo];
|
||||
}
|
||||
else if (CPDragServerDestination && [CPDragServerDestination respondsToSelector:@selector(draggingUpdated:)])
|
||||
[CPDragServerDestination draggingUpdated:CPDragServerDraggingInfo];
|
||||
|
||||
globalLocation.x -= CPDragServerOffset.x;
|
||||
globalLocation.y -= CPDragServerOffset.y;
|
||||
|
||||
[[CPDragServerView window] setFrameOrigin:globalLocation];
|
||||
|
||||
if (CPDragServerShouldSendDraggedImageMovedTo)
|
||||
[CPDragServerSource draggedImage:[CPDragServerView image] movedTo:globalLocation];
|
||||
else if (CPDragServerShouldSendDraggedViewMovedTo)
|
||||
[CPDragServerSource draggedView:CPDragServerView movedTo:globalLocation];
|
||||
}
|
||||
var CPDragServerSource = nil;
|
||||
var CPDragServerDraggingInfo = nil;
|
||||
|
||||
/*
|
||||
CPDraggingInfo is a container of information about a specific dragging session.
|
||||
@@ -146,24 +75,36 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
{
|
||||
}
|
||||
|
||||
- (CPPasteboard)draggingPasteboard
|
||||
{
|
||||
if ([CPPlatform supportsDragAndDrop])
|
||||
return [_CPDOMDataTransferPasteboard DOMDataTransferPasteboard];
|
||||
|
||||
return [[CPDragServer sharedDragServer] draggingPasteboard];
|
||||
}
|
||||
|
||||
- (id)draggingSource
|
||||
{
|
||||
return CPDragServerSource;
|
||||
return [[CPDragServer sharedDragServer] draggingSource];
|
||||
}
|
||||
|
||||
/*
|
||||
- (unsigned)draggingSourceOperationMask
|
||||
*/
|
||||
|
||||
- (CPPoint)draggingLocation
|
||||
{
|
||||
return CPDragServerLocation;
|
||||
return [[CPDragServer sharedDragServer] draggingLocation];
|
||||
}
|
||||
|
||||
- (CPPasteboard)draggingPasteboard
|
||||
- (CPWindow)draggingDestinationWindow
|
||||
{
|
||||
return CPDragServerPasteboard;
|
||||
return DRAGGING_WINDOW([[CPDragServer sharedDragServer] draggingDestination]);
|
||||
}
|
||||
|
||||
- (CPImage)draggedImage
|
||||
{
|
||||
return [CPDragServerView image];
|
||||
return [[self draggedView] image];
|
||||
}
|
||||
|
||||
- (CGPoint)draggedImageLocation
|
||||
@@ -171,22 +112,44 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
return [self draggedViewLocation];
|
||||
}
|
||||
|
||||
- (CGPoint)draggedViewLocation
|
||||
{
|
||||
return [DRAGGING_WINDOW(CPDragServerDestination) convertBridgeToBase:[CPDragServerView frame].origin];
|
||||
}
|
||||
|
||||
- (CPView)draggedView
|
||||
{
|
||||
return CPDragServerView;
|
||||
return [[CPDragServer sharedDragServer] draggedView];
|
||||
}
|
||||
|
||||
- (CGPoint)draggedViewLocation
|
||||
{
|
||||
var dragServer = [CPDragServer sharedDragServer];
|
||||
|
||||
return [DRAGGING_WINDOW([dragServer draggingDestination]) convertPlatformWindowToBase:[[dragServer draggedView] frame].origin];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
var CPDraggingSource_draggedImage_movedTo_ = 1 << 0,
|
||||
CPDraggingSource_draggedImage_endAt_operation_ = 1 << 1,
|
||||
CPDraggingSource_draggedView_movedTo_ = 1 << 2,
|
||||
CPDraggingSource_draggedView_endedAt_operation_ = 1 << 3;
|
||||
|
||||
@implementation CPDragServer : CPObject
|
||||
{
|
||||
CPWindow _dragWindow;
|
||||
CPImageView _imageView;
|
||||
BOOL _isDragging @accessors(readonly, getter=isDragging);
|
||||
|
||||
CPWindow _draggedWindow @accessors(readonly, getter=draggedWindow);
|
||||
CPView _draggedView @accessors(readonly, getter=draggedView);
|
||||
CPImageView _imageView;
|
||||
|
||||
BOOL _isDraggingImage;
|
||||
|
||||
CGSize _draggingOffset @accessors(readonly, getter=draggingOffset);
|
||||
|
||||
CPPasteboard _draggingPasteboard @accessors(readonly, getter=draggingPasteboard);
|
||||
|
||||
id _draggingSource @accessors(readonly, getter=draggingSource);
|
||||
unsigned _implementedDraggingSourceMethods;
|
||||
|
||||
CGPoint _draggingLocation;
|
||||
id _draggingDestination;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -197,7 +160,7 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
{
|
||||
if (self !== [CPDragServer class])
|
||||
return;
|
||||
|
||||
|
||||
CPDragServerDraggingInfo = [[CPDraggingInfo alloc] init];
|
||||
}
|
||||
|
||||
@@ -205,7 +168,7 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
{
|
||||
if (!CPSharedDragServer)
|
||||
CPSharedDragServer = [[CPDragServer alloc] init];
|
||||
|
||||
|
||||
return CPSharedDragServer;
|
||||
}
|
||||
|
||||
@@ -215,17 +178,104 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_dragWindow = [[CPWindow alloc] initWithContentRect:_CGRectMakeZero() styleMask:CPBorderlessWindowMask];
|
||||
_draggedWindow = [[CPWindow alloc] initWithContentRect:_CGRectMakeZero() styleMask:CPBorderlessWindowMask];
|
||||
|
||||
[_dragWindow setLevel:CPDraggingWindowLevel];
|
||||
[_draggedWindow setLevel:CPDraggingWindowLevel];
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGPoint)draggingLocation
|
||||
{
|
||||
return _draggingLocation
|
||||
}
|
||||
|
||||
- (void)draggingStartedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation
|
||||
{
|
||||
if (_isDraggingImage)
|
||||
{
|
||||
if ([_draggingSource respondsToSelector:@selector(draggedImage:beganAt:)])
|
||||
[_draggingSource draggedImage:[_draggedView image] beganAt:aLocation];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([_draggingSource respondsToSelector:@selector(draggedView:beganAt:)])
|
||||
[_draggingSource draggedView:_draggedView beganAt:aLocation];
|
||||
}
|
||||
|
||||
if (![CPPlatform supportsDragAndDrop])
|
||||
[_draggedWindow orderFront:self];
|
||||
}
|
||||
|
||||
- (void)draggingSourceUpdatedWithLocation:(CGPoint)aGlobalLocation
|
||||
{
|
||||
if (![CPPlatform supportsDragAndDrop])
|
||||
[_draggedWindow setFrameOrigin:_CGPointMake(aGlobalLocation.x - _draggingOffset.width, aGlobalLocation.y - _draggingOffset.height)];
|
||||
|
||||
if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_movedTo_)
|
||||
[_draggingSource draggedImage:[_draggedView image] movedTo:aGlobalLocation];
|
||||
|
||||
else if (_implementedDraggingSourceMethods & CPDraggingSource_draggedView_movedTo_)
|
||||
[_draggingSource draggedView:_draggedView movedTo:aGlobalLocation];
|
||||
}
|
||||
|
||||
- (CPDragOperation)draggingUpdatedInPlatformWindow:(CPPlatformWindow)aPlatformWindow location:(CGPoint)aLocation
|
||||
{
|
||||
var dragOperation = CPDragOperationCopy;
|
||||
// We have to convert base to bridge since the drag event comes from the source window, not the drag window.
|
||||
var draggingDestination = [aPlatformWindow _dragHitTest:aLocation pasteboard:[CPDragServerDraggingInfo draggingPasteboard]];
|
||||
|
||||
if (draggingDestination)
|
||||
_draggingLocation = [DRAGGING_WINDOW(draggingDestination) convertPlatformWindowToBase:aLocation];
|
||||
|
||||
if(draggingDestination !== _draggingDestination)
|
||||
{
|
||||
if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingExited:)])
|
||||
[_draggingDestination draggingExited:CPDragServerDraggingInfo];
|
||||
|
||||
_draggingDestination = draggingDestination;
|
||||
|
||||
if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingEntered:)])
|
||||
dragOperation = [_draggingDestination draggingEntered:CPDragServerDraggingInfo];
|
||||
}
|
||||
else if (_draggingDestination && [_draggingDestination respondsToSelector:@selector(draggingUpdated:)])
|
||||
dragOperation = [_draggingDestination draggingUpdated:CPDragServerDraggingInfo];
|
||||
|
||||
if (!_draggingDestination)
|
||||
dragOperation = CPDragOperationNone;
|
||||
|
||||
return dragOperation;
|
||||
}
|
||||
|
||||
- (void)draggingEndedInPlatformWindow:(CPPlatformWindow)aPlatformWindow
|
||||
{
|
||||
[_draggedView removeFromSuperview];
|
||||
|
||||
if (![CPPlatform supportsDragAndDrop])
|
||||
[_draggedWindow orderOut:self];
|
||||
|
||||
if (_implementedDraggingSourceMethods & CPDraggingSource_draggedImage_endAt_operation_)
|
||||
[_draggingSource draggedImage:[_draggedView image] endedAt:_draggingLocation operation:NO];
|
||||
|
||||
else if (_implementedDraggingSourceMethods & CPDraggingSource_draggedView_endedAt_operation_)
|
||||
[_draggingSource draggedView:_draggedView endedAt:_draggingLocation operation:NO];
|
||||
|
||||
_isDragging = NO;
|
||||
}
|
||||
|
||||
- (void)performDragOperationInPlatformWindow:(CPPlatformWindow)aPlatformWindow
|
||||
{
|
||||
if (_draggingDestination &&
|
||||
(![_draggingDestination respondsToSelector:@selector(prepareForDragOperation:)] || [_draggingDestination prepareForDragOperation:CPDragServerDraggingInfo]) &&
|
||||
(![_draggingDestination respondsToSelector:@selector(performDragOperation:)] || [_draggingDestination performDragOperation:CPDragServerDraggingInfo]) &&
|
||||
[_draggingDestination respondsToSelector:@selector(concludeDragOperation:)])
|
||||
[_draggingDestination concludeDragOperation:CPDragServerDraggingInfo];
|
||||
}
|
||||
|
||||
/*!
|
||||
Initiates a drag session.
|
||||
@param aView the view being dragged
|
||||
@@ -240,10 +290,12 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
*/
|
||||
- (void)dragView:(CPView)aView fromWindow:(CPWindow)aWindow at:(CGPoint)viewLocation offset:(CGSize)mouseOffset event:(CPEvent)mouseDownEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
|
||||
{
|
||||
CPDragServerView = aView;
|
||||
CPDragServerSource = aSourceObject;
|
||||
CPDragServerWindow = aWindow;
|
||||
CPDragServerPasteboard = [CPPasteboard pasteboardWithName:CPDragPboard];//aPasteboard;
|
||||
_isDragging = YES;
|
||||
|
||||
_draggedView = aView;
|
||||
_draggingPasteboard = aPasteboard || [CPPasteboard pasteboardWithName:CPDragPboard];
|
||||
_draggingSource = aSourceObject;
|
||||
_draggingDestination = nil;
|
||||
|
||||
// The offset is based on the distance from where we want the view to be initially from where the mouse is initially
|
||||
// Hence the use of mouseDownEvent's location and view's location in global coordinates.
|
||||
@@ -255,58 +307,48 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
if (mouseDownWindow)
|
||||
mouseDownEventLocation = [mouseDownWindow convertBaseToGlobal:mouseDownEventLocation];
|
||||
|
||||
CPDragServerOffset = _CGPointMake(mouseDownEventLocation.x - viewLocation.x, mouseDownEventLocation.y - viewLocation.y);
|
||||
_draggingOffset = _CGSizeMake(mouseDownEventLocation.x - viewLocation.x, mouseDownEventLocation.y - viewLocation.y);
|
||||
}
|
||||
else
|
||||
CPDragServerOffset = _CGPointMakeZero();
|
||||
_draggingOffset = _CGSizeMakerZero();
|
||||
|
||||
if ([CPPlatform isBrowser])
|
||||
[_dragWindow setPlatformWindow:[aWindow platformWindow]];
|
||||
[_draggedWindow setPlatformWindow:[aWindow platformWindow]];
|
||||
|
||||
[aView setFrameOrigin:_CGPointMakeZero()];
|
||||
|
||||
var mouseLocation = [CPEvent mouseLocation];
|
||||
|
||||
// Place it where the mouse pointer is.
|
||||
[_dragWindow setFrameOrigin:_CGPointMake(mouseLocation.x - CPDragServerOffset.x, mouseLocation.y - CPDragServerOffset.y)];
|
||||
[_dragWindow setFrameSize:[aView frame].size];
|
||||
[_draggedWindow setFrameOrigin:_CGPointMake(mouseLocation.x - _draggingOffset.width, mouseLocation.y - _draggingOffset.height)];
|
||||
[_draggedWindow setFrameSize:[aView frame].size];
|
||||
|
||||
[[_dragWindow contentView] addSubview:aView];
|
||||
[[_draggedWindow contentView] addSubview:aView];
|
||||
|
||||
[_dragWindow orderFront:self];
|
||||
_implementedDraggingSourceMethods = 0;
|
||||
|
||||
if (CPDragServerIsDraggingImage)
|
||||
if (_draggedView === _imageView)
|
||||
{
|
||||
if ([CPDragServerSource respondsToSelector:@selector(draggedImage:beganAt:)])
|
||||
[CPDragServerSource draggedImage:[aView image] beganAt:viewLocation];
|
||||
|
||||
CPDragServerShouldSendDraggedImageMovedTo = [CPDragServerSource respondsToSelector:@selector(draggedImage:movedTo:)];
|
||||
CPDragServerShouldSendDraggedImageEndedAtOperation = [CPDragServerSource respondsToSelector:@selector(draggedImage:endAt:operation:)];
|
||||
|
||||
CPDragServerShouldSendDraggedViewMovedTo = NO;
|
||||
CPDragServerShouldSendDraggedViewEndedAtOperation = NO;
|
||||
if ([_draggingSource respondsToSelector:@selector(draggedImage:movedTo:)])
|
||||
_implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_movedTo_;
|
||||
|
||||
if ([_draggingSource respondsToSelector:@selector(draggedImage:endAt:operation:)])
|
||||
_implementedDraggingSourceMethods |= CPDraggingSource_draggedImage_endAt_operation_;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([CPDragServerSource respondsToSelector:@selector(draggedView:beganAt:)])
|
||||
[CPDragServerSource draggedView:aView beganAt:viewLocation];
|
||||
|
||||
CPDragServerShouldSendDraggedViewMovedTo = [CPDragServerSource respondsToSelector:@selector(draggedView:movedTo:)];
|
||||
CPDragServerShouldSendDraggedViewEndedAtOperation = [CPDragServerSource respondsToSelector:@selector(draggedView:endedAt:operation:)];
|
||||
|
||||
if ([_draggingSource respondsToSelector:@selector(draggedView:movedTo:)])
|
||||
_implementedDraggingSourceMethods |= CPDraggingSource_draggedView_movedTo_;
|
||||
|
||||
CPDragServerShouldSendDraggedImageMovedTo = NO;
|
||||
CPDragServerShouldSendDraggedImageEndedAtOperation = NO;
|
||||
if ([_draggingSource respondsToSelector:@selector(draggedView:endedAt:operation:)])
|
||||
_implementedDraggingSourceMethods |= CPDraggingSource_draggedView_endedAt_operation_;
|
||||
}
|
||||
|
||||
if (mouseDownWindow)
|
||||
mouseLocation = [mouseDownWindow convertGlobalToBase:mouseLocation];
|
||||
|
||||
var updatedEvent = [CPEvent mouseEventWithType:CPLeftMouseDragged location:mouseLocation modifierFlags:[mouseDownEvent modifierFlags]
|
||||
timestamp:[mouseDownEvent timestamp] windowNumber:[mouseDownEvent windowNumber] context:nil
|
||||
eventNumber:0 clickCount:[mouseDownEvent clickCount] pressure:[mouseDownEvent pressure]];
|
||||
|
||||
CPDragServerStartDragging(updatedEvent);
|
||||
if (![CPPlatform supportsDragAndDrop])
|
||||
{
|
||||
[self draggingStartedInPlatformWindow:[aWindow platformWindow] location:mouseLocation];
|
||||
[self trackDragging:mouseDownEvent];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -323,17 +365,42 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
*/
|
||||
- (void)dragImage:(CPImage)anImage fromWindow:(CPWindow)aWindow at:(CGPoint)imageLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
|
||||
{
|
||||
CPDragServerIsDraggingImage = YES;
|
||||
|
||||
_isDraggingImage = YES;
|
||||
|
||||
var imageSize = [anImage size];
|
||||
|
||||
if (!_imageView)
|
||||
_imageView = [[CPImageView alloc] initWithFrame:CPRectMakeZero()];
|
||||
|
||||
_imageView = [[CPImageView alloc] initWithFrame:_CGRectMake(0.0, 0.0, imageSize.width, imageSize.height)];
|
||||
|
||||
[_imageView setImage:anImage];
|
||||
[_imageView setFrameSize:CGSizeMakeCopy([anImage size])];
|
||||
|
||||
|
||||
[self dragView:_imageView fromWindow:aWindow at:imageLocation offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
|
||||
}
|
||||
|
||||
- (void)trackDragging:(CPEvent)anEvent
|
||||
{
|
||||
var type = [anEvent type],
|
||||
platformWindow = [_draggedWindow platformWindow],
|
||||
platformWindowLocation = [[anEvent window] convertBaseToPlatformWindow:[anEvent locationInWindow]];
|
||||
|
||||
if (type === CPLeftMouseUp)
|
||||
{
|
||||
[self performDragOperationInPlatformWindow:platformWindow];
|
||||
[self draggingEndedInPlatformWindow:platformWindow];
|
||||
|
||||
// Stop tracking events.
|
||||
return;
|
||||
}
|
||||
|
||||
[self draggingSourceUpdatedWithLocation:platformWindowLocation];
|
||||
[self draggingUpdatedInPlatformWindow:platformWindow location:platformWindowLocation];
|
||||
|
||||
// If we're not a mouse up, then we're going to want to grab the next event.
|
||||
[CPApp setTarget:self selector:@selector(trackDragging:)
|
||||
forNextEventMatchingMask:CPMouseMovedMask | CPLeftMouseDraggedMask | CPLeftMouseUpMask
|
||||
untilDate:nil inMode:0 dequeue:NO];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPWindow (CPDraggingAdditions)
|
||||
@@ -351,18 +418,18 @@ var CPDragServerUpdateDragging = function(anEvent)
|
||||
// if (![self containsPoint:aPoint])
|
||||
// return nil;
|
||||
|
||||
var adjustedPoint = _CGPointMake(aPoint.x - _CGRectGetMinX(_frame), aPoint.y - _CGRectGetMinY(_frame)),
|
||||
var adjustedPoint = [self convertPlatformWindowToBase:aPoint],
|
||||
hitView = [_windowView hitTest:adjustedPoint];
|
||||
|
||||
while (hitView && ![aPasteboard availableTypeFromArray:[hitView registeredDraggedTypes]])
|
||||
hitView = [hitView superview];
|
||||
|
||||
|
||||
if (hitView)
|
||||
return hitView;
|
||||
|
||||
|
||||
if ([aPasteboard availableTypeFromArray:[self registeredDraggedTypes]])
|
||||
return self;
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
+12
-1
@@ -87,7 +87,13 @@ var LEFT_SHADOW_INSET = 3.0,
|
||||
_DOMImageElement.style.position = "absolute";
|
||||
_DOMImageElement.style.left = "0px";
|
||||
_DOMImageElement.style.top = "0px";
|
||||
|
||||
|
||||
if ([CPPlatform supportsDragAndDrop])
|
||||
{
|
||||
_DOMImageElement.setAttribute("draggable", "true");
|
||||
_DOMImageElement.style["-khtml-user-drag"] = "element";
|
||||
}
|
||||
|
||||
CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement);
|
||||
|
||||
_DOMImageElement.style.visibility = "hidden";
|
||||
@@ -398,6 +404,11 @@ var CPImageViewImageKey = @"CPImageViewImageKey",
|
||||
_DOMImageElement.style.left = "0px";
|
||||
_DOMImageElement.style.top = "0px";
|
||||
_DOMImageElement.style.visibility = "hidden";
|
||||
if ([CPPlatform supportsDragAndDrop])
|
||||
{
|
||||
_DOMImageElement.setAttribute("draggable", "true");
|
||||
_DOMImageElement.style["-khtml-user-drag"] = "element";
|
||||
}
|
||||
#endif
|
||||
|
||||
self = [super initWithCoder:aCoder];
|
||||
|
||||
+70
-1
@@ -25,6 +25,8 @@
|
||||
@import <Foundation/CPDictionary.j>
|
||||
@import <Foundation/CPPropertyListSerialization.j>
|
||||
|
||||
#include "Platform/Platform.h"
|
||||
|
||||
|
||||
CPGeneralPboard = @"CPGeneralPboard";
|
||||
CPFontPboard = @"CPFontPboard";
|
||||
@@ -213,7 +215,7 @@ var CPPasteboards = nil;
|
||||
*/
|
||||
- (CPString)availableTypeFromArray:(CPArray)anArray
|
||||
{
|
||||
return [_types firstObjectCommonWithArray:anArray];
|
||||
return [[self types] firstObjectCommonWithArray:anArray];
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -304,3 +306,70 @@ var CPPasteboards = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
|
||||
var DOMDataTransferPasteboard = nil;
|
||||
|
||||
@implementation _CPDOMDataTransferPasteboard : CPPasteboard
|
||||
{
|
||||
DataTransfer _dataTransfer;
|
||||
}
|
||||
|
||||
+ (_CPDOMDataTransferPasteboard)DOMDataTransferPasteboard
|
||||
{
|
||||
if (!DOMDataTransferPasteboard)
|
||||
DOMDataTransferPasteboard = [[_CPDOMDataTransferPasteboard alloc] init];
|
||||
|
||||
return DOMDataTransferPasteboard;
|
||||
}
|
||||
|
||||
- (void)_setDataTransfer:(DataTransfer)aDataTransfer
|
||||
{
|
||||
_dataTransfer = aDataTransfer;
|
||||
}
|
||||
|
||||
- (void)_setPasteboard:(CPPasteboard)aPasteboard
|
||||
{
|
||||
_dataTransfer.clearData();
|
||||
|
||||
var types = [aPasteboard types],
|
||||
count = types.length;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
var type = types[count];
|
||||
|
||||
if (type === CPStringPboardType)
|
||||
_dataTransfer.setData(type, [aPasteboard stringForType:type]);
|
||||
else
|
||||
_dataTransfer.setData(type, [[aPasteboard dataForType:type] string]);
|
||||
}
|
||||
}
|
||||
|
||||
- (CPArray)types
|
||||
{
|
||||
return Array.prototype.slice.apply(_dataTransfer.types);
|
||||
}
|
||||
|
||||
- (CPData)dataForType:(CPString)aType
|
||||
{
|
||||
var dataString = _dataTransfer.getData(aType);
|
||||
|
||||
if (aType === CPStringPboardType)
|
||||
return [CPData dataFromPropertyList:dataString format:kCFPropertyList280NorthFormat_v1_0 errorDescription:0];
|
||||
|
||||
return [CPData dataWithString:dataString];
|
||||
}
|
||||
|
||||
- (id)propertyListForType:(CPString)aType
|
||||
{
|
||||
if (aType === CPStringPboardType)
|
||||
return _dataTransfer.getData(aType);
|
||||
|
||||
return [CPPropertyListSerialization propertyListFromData:[self dataForType:aType] format:CPPropertyListUnknownFormat errorDescription:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -250,7 +250,7 @@ var DOMElementPrototype = nil,
|
||||
|
||||
#if PLATFORM(DOM)
|
||||
_DOMElement = DOMElementPrototype.cloneNode(false);
|
||||
|
||||
|
||||
CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(aFrame), _CGRectGetMinY(aFrame));
|
||||
CPDOMDisplayServerSetStyleSize(_DOMElement, width, height);
|
||||
|
||||
|
||||
@@ -142,6 +142,10 @@ var _CPWindowViewResizeIndicatorImage = nil;
|
||||
|
||||
- (CGPoint)_pointWithinScreenFrame:(CGPoint)aPoint
|
||||
{
|
||||
// FIXME: this is WRONG, all of this is WRONG
|
||||
if (![CPPlatform isBrowser])
|
||||
return aPoint;
|
||||
|
||||
var visibleFrame = _cachedScreenFrame;
|
||||
|
||||
if (!visibleFrame)
|
||||
|
||||
@@ -26,7 +26,12 @@
|
||||
|
||||
+ (BOOL)isBrowser
|
||||
{
|
||||
return YES;
|
||||
return typeof window.cpIsDesktop === "undefined";
|
||||
}
|
||||
|
||||
+ (BOOL)supportsDragAndDrop
|
||||
{
|
||||
return CPFeatureIsCompatible(CPHTMLDragAndDropFeature);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -164,6 +164,10 @@ var CTRL_KEY_CODE = 17;
|
||||
|
||||
_DOMBodyElement = theDocument.getElementsByTagName("body")[0];
|
||||
|
||||
// FIXME: Always do this?
|
||||
if ([CPPlatform supportsDragAndDrop])
|
||||
_DOMBodyElement.style["-khtml-user-select"] = "none";
|
||||
|
||||
_DOMBodyElement.webkitTouchCallout = "none";
|
||||
|
||||
_DOMFocusElement = theDocument.createElement("input");
|
||||
@@ -189,6 +193,9 @@ var CTRL_KEY_CODE = 17;
|
||||
|
||||
var theClass = [self class],
|
||||
|
||||
dragEventImplementation = class_getMethodImplementation(theClass, @selector(dragEvent:)),
|
||||
dragEventCallback = function (anEvent) { dragEventImplementation(self, nil, anEvent); },
|
||||
|
||||
resizeEventSelector = @selector(resizeEvent:),
|
||||
resizeEventImplementation = class_getMethodImplementation(theClass, resizeEventSelector),
|
||||
resizeEventCallback = function (anEvent) { resizeEventImplementation(self, nil, anEvent); },
|
||||
@@ -211,6 +218,16 @@ var CTRL_KEY_CODE = 17;
|
||||
|
||||
if (theDocument.addEventListener)
|
||||
{
|
||||
if ([CPPlatform supportsDragAndDrop])
|
||||
{
|
||||
theDocument.addEventListener("dragstart", dragEventCallback, NO);
|
||||
theDocument.addEventListener("drag", dragEventCallback, NO);
|
||||
theDocument.addEventListener("dragend", dragEventCallback, NO);
|
||||
theDocument.addEventListener("dragover", dragEventCallback, NO);
|
||||
theDocument.addEventListener("dragleave", dragEventCallback, NO);
|
||||
theDocument.addEventListener("drop", dragEventCallback, NO);
|
||||
}
|
||||
|
||||
theDocument.addEventListener("mouseup", mouseEventCallback, NO);
|
||||
theDocument.addEventListener("mousedown", mouseEventCallback, NO);
|
||||
theDocument.addEventListener("mousemove", mouseEventCallback, NO);
|
||||
@@ -331,6 +348,78 @@ var CTRL_KEY_CODE = 17;
|
||||
_DOMWindow.close();
|
||||
}
|
||||
|
||||
- (void)dragEvent:(DOMEvent)aDOMEvent
|
||||
{
|
||||
var type = aDOMEvent.type,
|
||||
dragServer = [CPDragServer sharedDragServer],
|
||||
location = _CGPointMake(aDOMEvent.clientX, aDOMEvent.clientY),
|
||||
pasteboard = [_CPDOMDataTransferPasteboard DOMDataTransferPasteboard];
|
||||
|
||||
[pasteboard _setDataTransfer:aDOMEvent.dataTransfer];
|
||||
|
||||
if (aDOMEvent.type === "dragstart")
|
||||
{
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
|
||||
[pasteboard _setPasteboard:[dragServer draggingPasteboard]];
|
||||
|
||||
var draggedWindow = [dragServer draggedWindow],
|
||||
draggedWindowFrame = [draggedWindow frame],
|
||||
DOMDragElement = draggedWindow._DOMElement;
|
||||
|
||||
DOMDragElement.style.left = -_CGRectGetWidth(draggedWindowFrame) + "px";
|
||||
DOMDragElement.style.top = -_CGRectGetHeight(draggedWindowFrame) + "px";
|
||||
|
||||
document.getElementsByTagName("body")[0].appendChild(DOMDragElement);
|
||||
|
||||
var draggingOffset = [dragServer draggingOffset];
|
||||
|
||||
aDOMEvent.dataTransfer.setDragImage(DOMDragElement, draggingOffset.width, draggingOffset.height);
|
||||
|
||||
[dragServer draggingStartedInPlatformWindow:self location:[CPPlatform isBrowser] ? location : _CGPointMake(aDOMEvent.screenX, aDOMEvent.screenY)];
|
||||
}
|
||||
|
||||
else if (type === "drag")
|
||||
[dragServer draggingSourceUpdatedWithLocation:[CPPlatform isBrowser] ? location : _CGPointMake(aDOMEvent.screenX, aDOMEvent.screenY)];
|
||||
|
||||
else if (type === "dragover" || type === "dragleave")
|
||||
{
|
||||
if (aDOMEvent.preventDefault)
|
||||
aDOMEvent.preventDefault();
|
||||
|
||||
var dropEffect = "none",
|
||||
dragOperation = [dragServer draggingUpdatedInPlatformWindow:self location:location];
|
||||
|
||||
if (dragOperation === CPDragOperationMove || dragOperation === CPDragOperationGeneric || dragOperation === CPDragOperationPrivate)
|
||||
dropEffect = "move";
|
||||
|
||||
else if (dragOperation === CPDragOperationCopy)
|
||||
dropEffect = "copy";
|
||||
|
||||
else if (dragOperation === CPDragOperationLink)
|
||||
dropEffect = "link";
|
||||
|
||||
aDOMEvent.dataTransfer.dropEffect = dropEffect;
|
||||
}
|
||||
|
||||
else if (type === "dragend")
|
||||
[dragServer draggingEndedInPlatformWindow:self];
|
||||
|
||||
else //if (type === "drop")
|
||||
{
|
||||
[dragServer performDragOperationInPlatformWindow:self];
|
||||
|
||||
// W3C Model
|
||||
if (aDOMEvent.preventDefault)
|
||||
aDOMEvent.preventDefault();
|
||||
|
||||
if (aDOMEvent.stopPropagation)
|
||||
aDOMEvent.stopPropagation();
|
||||
}
|
||||
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
- (void)keyEvent:(DOMEvent)aDOMEvent
|
||||
{
|
||||
var event,
|
||||
@@ -693,9 +782,15 @@ var CTRL_KEY_CODE = 17;
|
||||
}
|
||||
|
||||
else if (type === "mousedown")
|
||||
{
|
||||
{
|
||||
if (ExcludedDOMElements[sourceElement.tagName] && sourceElement != _DOMFocusElement)
|
||||
{
|
||||
if ([CPPlatform supportsDragAndDrop])
|
||||
{
|
||||
_DOMBodyElement.setAttribute("draggable", "false");
|
||||
_DOMBodyElement.style["-khtml-user-drag"] = "none";
|
||||
}
|
||||
|
||||
_DOMEventMode = YES;
|
||||
_mouseIsDown = YES;
|
||||
|
||||
@@ -710,6 +805,11 @@ var CTRL_KEY_CODE = 17;
|
||||
|
||||
return;
|
||||
}
|
||||
else if ([CPPlatform supportsDragAndDrop])
|
||||
{
|
||||
_DOMBodyElement.setAttribute("draggable", "true");
|
||||
_DOMBodyElement.style["-khtml-user-drag"] = "element";
|
||||
}
|
||||
|
||||
event = _CPEventFromNativeMouseEvent(aDOMEvent, CPLeftMouseDown, location, modifierFlags, timestamp, windowNumber, nil, -1, CPDOMEventGetClickCount(_lastMouseDown, timestamp, location), 0);
|
||||
|
||||
@@ -717,7 +817,7 @@ var CTRL_KEY_CODE = 17;
|
||||
_lastMouseDown = event;
|
||||
}
|
||||
|
||||
else // if (type === "mousemove")
|
||||
else // if (type === "mousemove" || type === "drag")
|
||||
{
|
||||
if (_DOMEventMode)
|
||||
return;
|
||||
@@ -732,7 +832,7 @@ var CTRL_KEY_CODE = 17;
|
||||
[CPApp sendEvent:event];
|
||||
}
|
||||
|
||||
if (StopDOMEventPropagation)
|
||||
if (StopDOMEventPropagation && (![CPPlatform supportsDragAndDrop] || type !== "mousedown" && ![[CPDragServer sharedDragServer] isDragging]))
|
||||
CPDOMEventStop(aDOMEvent, self);
|
||||
|
||||
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
|
||||
|
||||
@@ -511,7 +511,13 @@ var HORIZONTAL_MARGIN = 3.0,
|
||||
else
|
||||
{
|
||||
_DOMImageElement = document.createElement("img");
|
||||
|
||||
|
||||
if ([CPPlatform supportsDragAndDrop])
|
||||
{
|
||||
_DOMImageElement.setAttribute("draggable", "true");
|
||||
_DOMImageElement.style["-khtml-user-drag"] = "element";
|
||||
}
|
||||
|
||||
var imageStyle = _DOMImageElement.style;
|
||||
|
||||
imageStyle.top = "0px";
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
@import "CPObject.j"
|
||||
|
||||
|
||||
CPPropertyListUnknownFormat = 0;
|
||||
CPPropertyListOpenStepFormat = kCFPropertyListOpenStepFormat;
|
||||
CPPropertyListXMLFormat_v1_0 = kCFPropertyListXMLFormat_v1_0;
|
||||
CPPropertyListBinaryFormat_v1_0 = kCFPropertyListBinaryFormat_v1_0;
|
||||
|
||||
Reference in New Issue
Block a user