Commit cd54bad1 authored by oliver's avatar oliver

2007-02-18 Oliver Hunt <oliver@apple.com>

        Reviewed by Adam.
WebCore:
        More drag and drop migration, now the entirety of the
        drag initiation logic has been rendered platform independent
        This has required a number of new interfaces, and a reasonable
        amount of logic migration.

        As a side effect, this patch also fixes rdar://problem/4945341

        There are some basic Qt stubs that should stop the build from failing,
        however the absence of ClipboardQt means any attempt to initiate a drag 
        may cause a crash.

        * WebCore.exp:
           Exporting new symbols

        * WebCore.xcodeproj/project.pbxproj:
           New files

        * dom/Clipboard.cpp:
        (WebCore::Clipboard::canSaveAsWebArchive):
          Migrated from WebKit

        * dom/Clipboard.h:
          Added more methods to allow Clipboard to be used as a 
          platform independent container for drag and drop

        * page/DragClient.h:
        (WebCore::DragClient::declareAndWriteDragImage):
          This is a mac only helper function, so i've made it have an empty implementation,
          that way we won't need a PLATFORM(MAC) block in SVGImageEmptyClients

        * page/DragController.cpp:
        (WebCore::DragController::dragExited):
        (WebCore::DragController::performDrag):
        (WebCore::DragController::tryDocumentDrag): 
        (WebCore::DragController::tryDHTMLDrag):
          Using RefPtrs now
        (WebCore::getCachedImage):
        (WebCore::getImage):
          Helper functions                   
        (WebCore::dragLocForDHTMLDrag):
        (WebCore::dragLocForSelectionDrag):
        (WebCore::DragController::startDrag):
        (WebCore::DragController::doImageDrag):
        (WebCore::DragController::doSystemDrag):
          Logic that generates drag images and clipboard content, and
          initiates the actual system drag operation

        * page/DragController.h:
          Method and variable declarations

        * page/EventHandler.cpp:
        (WebCore::EventHandler::handleDrag):
          handleDrag is now platform independent
        (WebCore::EventHandler::handleTextInputEvent):
           formatting

        * page/EventHandler.h:
        (WebCore::EventHandler::eventLoopHandleMouseDragged):
          Forgot to define this stub function 

        * page/Frame.h:
          Declaring dragImageForSelection to provide drag image for selected content

        * page/mac/DragControllerMac.mm:
          Defining drag images control vars

        * page/mac/EventHandlerMac.mm:
        (WebCore::EventHandler::createDraggingClipboard):
          Migrated old clipboard creation to here

        * page/mac/FrameMac.mm:
        (WebCore::Frame::dragImageForSelection):
          Wrap FrameMac::selectionImage

        * page/qt/DragControllerQt.cpp:
          Defining drag images control vars

        * page/qt/EventHandlerQt.cpp:
        (WebCore::EventHandler::createDraggingClipboard):
          stub

        * page/qt/FrameQt.cpp:
        (WebCore::Frame::dragImageForSelection):
          stub

        * platform/DragImage.cpp: Added.
        (WebCore::fitDragImageToMaxSize):
        (WebCore::createDragImageForSelection):
           Platform independent processing for drag images

        * platform/DragImage.h: Added.
           Declaring typedefs and wrapper functions to abstract the handling
           of drag images 

        * platform/Pasteboard.h:
          Declaring extracted writeURL and writeSelection methods

        * platform/graphics/svg/SVGImageEmptyClients.h:
        (WebCore::SVGEmptyDragClient::willPerformDragSourceAction):
        (WebCore::SVGEmptyDragClient::startDrag):
        (WebCore::SVGEmptyDragClient::createDragImageForLink):
          Stubs FTW!

        * platform/mac/ClipboardMac.h:
        (WebCore::ClipboardMac::pasteboard):
          Provide accessor for underlying NSPasteboard

        * platform/mac/ClipboardMac.mm:
        (WebCore::ClipboardMac::hasData):
        (WebCore::ClipboardMac::writeRange):
        (WebCore::ClipboardMac::writeURL):
        (WebCore::ClipboardMac::declareAndWriteDragImage):
        (WebCore::ClipboardMac::createDragImage):
           Implemented new Clipboarid functionality.
        (WebCore::ClipboardMac::dragNSImage):
           Made this a const method

        * platform/mac/DragImageMac.mm: Added.
        (WebCore::dragImageSize):
        (WebCore::deleteDragImage):
        (WebCore::scaleDragImage):
        (WebCore::dissolveDragImageToFraction):
        (WebCore::createDragImageFromImage):
        (WebCore::createDragImageIconForCachedImage):
           Implemented platform specific DragImage functions

        * platform/mac/PasteboardMac.mm:
        (WebCore::writeSelection):
        (WebCore::Pasteboard::writeSelection):
        (WebCore::writeURL):
        (WebCore::Pasteboard::writeURL):
           Extracted member implementations of these functions, so that
           Clipboard could also make use of this functionality.
           Pasteboard methods now call the new non-member implementations.
           Also fixed implementations to respect the list of requested types.

        * platform/qt/DragImageQt.cpp: Added.
        (WebCore::dragImageSize):
        (WebCore::deleteDragImage):
        (WebCore::scaleDragImage):
        (WebCore::dissolveDragImageToFraction):
        (WebCore::createDragImageFromImage):
        (WebCore::createDragImageIconForCachedImage):  
          Stubs

WebKit:
        Moving the drag initiation logic to WebCore.
        The redundant code in webkit will be moved out in a later patch.

        * WebCoreSupport/WebDragClient.h:
        * WebCoreSupport/WebDragClient.mm:
        (getTopHTMLView):
          Helper function
        (WebDragClient::willPerformDragSourceAction):
        (WebDragClient::startDrag):
        (WebDragClient::createDragImageForLink):
          Implemented new DragClient methods
        (WebDragClient::declareAndWriteDragImage):
          Helper function for the Mac to allow new drag and drop
          code to match behaviour
          
        * WebView/WebHTMLView.mm:
        (-[WebHTMLView _dragImageForURL:withLabel:]):
        (-[WebHTMLView _dragImageForLinkElement:]):
          Refactoring old _dragImageForLinkElement function so that 
          the link drag image can be created with just a URL and label, 
          rather than requiring the original element
        (-[WebHTMLView dragImage:at:offset:event:pasteboard:source:slideBack:]):
          Removed logic that is no longer necessary                 
        (-[WebHTMLView _mouseDownEvent]):
          The WebDragClient may need the original mouseDownEvent of a drag when initiating
          a drag
        * WebView/WebHTMLViewInternal.h:
          Declaring _mouseDownEvent

        * WebView/WebHTMLViewPrivate.h:
          Declaring _dragImageForURL
                                        
      


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@19689 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d309cc7e
2007-02-18 Oliver Hunt <oliver@apple.com>
Reviewed by Adam.
More drag and drop migration, now the entirety of the
drag initiation logic has been rendered platform independent
This has required a number of new interfaces, and a reasonable
amount of logic migration.
As a side effect, this patch also fixes rdar://problem/4945341
There are some basic Qt stubs that should stop the build from failing,
however the absence of ClipboardQt means any attempt to initiate a drag
may cause a crash.
* WebCore.exp:
Exporting new symbols
* WebCore.xcodeproj/project.pbxproj:
New files
* dom/Clipboard.cpp:
(WebCore::Clipboard::canSaveAsWebArchive):
Migrated from WebKit
* dom/Clipboard.h:
Added more methods to allow Clipboard to be used as a
platform independent container for drag and drop
* page/DragClient.h:
(WebCore::DragClient::declareAndWriteDragImage):
This is a mac only helper function, so i've made it have an empty implementation,
that way we won't need a PLATFORM(MAC) block in SVGImageEmptyClients
* page/DragController.cpp:
(WebCore::DragController::dragExited):
(WebCore::DragController::performDrag):
(WebCore::DragController::tryDocumentDrag):
(WebCore::DragController::tryDHTMLDrag):
Using RefPtrs now
(WebCore::getCachedImage):
(WebCore::getImage):
Helper functions
(WebCore::dragLocForDHTMLDrag):
(WebCore::dragLocForSelectionDrag):
(WebCore::DragController::startDrag):
(WebCore::DragController::doImageDrag):
(WebCore::DragController::doSystemDrag):
Logic that generates drag images and clipboard content, and
initiates the actual system drag operation
* page/DragController.h:
Method and variable declarations
* page/EventHandler.cpp:
(WebCore::EventHandler::handleDrag):
handleDrag is now platform independent
(WebCore::EventHandler::handleTextInputEvent):
formatting
* page/EventHandler.h:
(WebCore::EventHandler::eventLoopHandleMouseDragged):
Forgot to define this stub function
* page/Frame.h:
Declaring dragImageForSelection to provide drag image for selected content
* page/mac/DragControllerMac.mm:
Defining drag images control vars
* page/mac/EventHandlerMac.mm:
(WebCore::EventHandler::createDraggingClipboard):
Migrated old clipboard creation to here
* page/mac/FrameMac.mm:
(WebCore::Frame::dragImageForSelection):
Wrap FrameMac::selectionImage
* page/qt/DragControllerQt.cpp:
Defining drag images control vars
* page/qt/EventHandlerQt.cpp:
(WebCore::EventHandler::createDraggingClipboard):
stub
* page/qt/FrameQt.cpp:
(WebCore::Frame::dragImageForSelection):
stub
* platform/DragImage.cpp: Added.
(WebCore::fitDragImageToMaxSize):
(WebCore::createDragImageForSelection):
Platform independent processing for drag images
* platform/DragImage.h: Added.
Declaring typedefs and wrapper functions to abstract the handling
of drag images
* platform/Pasteboard.h:
Declaring extracted writeURL and writeSelection methods
* platform/graphics/svg/SVGImageEmptyClients.h:
(WebCore::SVGEmptyDragClient::willPerformDragSourceAction):
(WebCore::SVGEmptyDragClient::startDrag):
(WebCore::SVGEmptyDragClient::createDragImageForLink):
Stubs FTW!
* platform/mac/ClipboardMac.h:
(WebCore::ClipboardMac::pasteboard):
Provide accessor for underlying NSPasteboard
* platform/mac/ClipboardMac.mm:
(WebCore::ClipboardMac::hasData):
(WebCore::ClipboardMac::writeRange):
(WebCore::ClipboardMac::writeURL):
(WebCore::ClipboardMac::declareAndWriteDragImage):
(WebCore::ClipboardMac::createDragImage):
Implemented new Clipboarid functionality.
(WebCore::ClipboardMac::dragNSImage):
Made this a const method
* platform/mac/DragImageMac.mm: Added.
(WebCore::dragImageSize):
(WebCore::deleteDragImage):
(WebCore::scaleDragImage):
(WebCore::dissolveDragImageToFraction):
(WebCore::createDragImageFromImage):
(WebCore::createDragImageIconForCachedImage):
Implemented platform specific DragImage functions
* platform/mac/PasteboardMac.mm:
(WebCore::writeSelection):
(WebCore::Pasteboard::writeSelection):
(WebCore::writeURL):
(WebCore::Pasteboard::writeURL):
Extracted member implementations of these functions, so that
Clipboard could also make use of this functionality.
Pasteboard methods now call the new non-member implementations.
Also fixed implementations to respect the list of requested types.
* platform/qt/DragImageQt.cpp: Added.
(WebCore::dragImageSize):
(WebCore::deleteDragImage):
(WebCore::scaleDragImage):
(WebCore::dissolveDragImageToFraction):
(WebCore::createDragImageFromImage):
(WebCore::createDragImageIconForCachedImage):
Stubs
2007-02-17 David Hyatt <hyatt@apple.com>
Fix textarea resizers to not fill with black by making sure the fill color starts off as
......
......@@ -197,6 +197,7 @@ __ZN7WebCore12AtomicString3addEPNS_10StringImplE
__ZN7WebCore12EventHandler10mouseMovedEP7NSEvent
__ZN7WebCore12EventHandler10wheelEventEP7NSEvent
__ZN7WebCore12EventHandler12mouseDraggedEP7NSEvent
__ZN7WebCore12EventHandler14currentNSEventEv
__ZN7WebCore12EventHandler20handleTextInputEventERKNS_6StringEPNS_5EventEbb
__ZN7WebCore12EventHandler20hitTestResultAtPointERKNS_8IntPointEb
__ZN7WebCore12EventHandler20sendContextMenuEventERKNS_18PlatformMouseEventE
......
......@@ -1655,6 +1655,9 @@
A7CA595D0B27BD9E00FA021D /* DragController.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA595B0B27BD9E00FA021D /* DragController.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7CA595E0B27BD9E00FA021D /* DragController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7CA595C0B27BD9E00FA021D /* DragController.cpp */; };
A7CA59630B27C1F200FA021D /* DragClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA59620B27C1F200FA021D /* DragClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7CFB3D10B7ED10A0070C32D /* DragImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */; };
A7CFB3D20B7ED10A0070C32D /* DragImage.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CFB3D00B7ED10A0070C32D /* DragImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7CFB3D50B7ED1180070C32D /* DragImageMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A7CFB3D40B7ED1180070C32D /* DragImageMac.mm */; };
A7D3C5240B576B4B002CA450 /* PasteboardHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D3C5230B576B4B002CA450 /* PasteboardHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };
A809F1470B73793A002E4D7F /* RenderSVGGradientStop.h in Headers */ = {isa = PBXBuildFile; fileRef = A809F1450B73793A002E4D7F /* RenderSVGGradientStop.h */; };
A809F1480B73793B002E4D7F /* RenderSVGGradientStop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A809F1460B73793A002E4D7F /* RenderSVGGradientStop.cpp */; };
......@@ -4667,8 +4670,11 @@
A79546420B5C4CB4007B438F /* DragData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DragData.cpp; sourceTree = "<group>"; };
A7B6E69D0B291A9600D0529F /* DragData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragData.h; sourceTree = "<group>"; };
A7CA595B0B27BD9E00FA021D /* DragController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragController.h; sourceTree = "<group>"; };
A7CA595C0B27BD9E00FA021D /* DragController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DragController.cpp; sourceTree = "<group>"; };
A7CA595C0B27BD9E00FA021D /* DragController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = DragController.cpp; sourceTree = "<group>"; };
A7CA59620B27C1F200FA021D /* DragClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragClient.h; sourceTree = "<group>"; };
A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DragImage.cpp; sourceTree = "<group>"; };
A7CFB3D00B7ED10A0070C32D /* DragImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DragImage.h; sourceTree = "<group>"; };
A7CFB3D40B7ED1180070C32D /* DragImageMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DragImageMac.mm; sourceTree = "<group>"; };
A7D3C5230B576B4B002CA450 /* PasteboardHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PasteboardHelper.h; sourceTree = "<group>"; };
A809F1450B73793A002E4D7F /* RenderSVGGradientStop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGGradientStop.h; sourceTree = "<group>"; };
A809F1460B73793A002E4D7F /* RenderSVGGradientStop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGGradientStop.cpp; sourceTree = "<group>"; };
......@@ -6801,6 +6807,7 @@
6582A14809999D6C00BEEB6D /* mac */ = {
isa = PBXGroup;
children = (
A7CFB3D40B7ED1180070C32D /* DragImageMac.mm */,
A795463D0B5C4C80007B438F /* DragDataMac.mm */,
06027CB20B1CC03D00884B2D /* ContextMenuItemMac.mm */,
65A640F00533BB1F0085E777 /* BlockExceptions.h */,
......@@ -9052,6 +9059,8 @@
F587853C02DE375901EA4122 /* DeprecatedValueListImpl.cpp */,
F587853B02DE375901EA4122 /* DeprecatedValueListImpl.h */,
A7B6E69D0B291A9600D0529F /* DragData.h */,
A7CFB3D00B7ED10A0070C32D /* DragImage.h */,
A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */,
934FE9E40B5CA539003E4A73 /* FileChooser.cpp */,
066C772A0AB603B700238CC4 /* FileChooser.h */,
BC6D6DD009AF906600F59759 /* Font.cpp */,
......@@ -9640,6 +9649,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
A7CFB3D20B7ED10A0070C32D /* DragImage.h in Headers */,
A7D3C5240B576B4B002CA450 /* PasteboardHelper.h in Headers */,
A718760E0B2A120100A16ECE /* DragActions.h in Headers */,
A7B6E69F0B291A9600D0529F /* DragData.h in Headers */,
......@@ -11149,6 +11159,7 @@
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
knownRegions = (
English,
......@@ -11163,6 +11174,7 @@
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
shouldCheckCompatibility = 1;
targets = (
93F198A508245E59001E9ABC /* WebCore */,
DD041FBE09D9DDBE0010AF2A /* Derived Sources */,
......@@ -12469,6 +12481,8 @@
933A142E0B7D188600A53FFD /* TextEvent.cpp in Sources */,
933A14AA0B7D1D0900A53FFD /* DOMTextEvent.mm in Sources */,
933A14B80B7D1D5200A53FFD /* JSTextEvent.cpp in Sources */,
A7CFB3D10B7ED10A0070C32D /* DragImage.cpp in Sources */,
A7CFB3D50B7ED1180070C32D /* DragImageMac.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -26,8 +26,24 @@
#include "config.h"
#include "Clipboard.h"
#include "DOMImplementation.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "Image.h"
#include "PlugInInfoStore.h"
namespace WebCore {
bool Clipboard::canSaveAsWebArchive(Frame* frame)
{
ASSERT(frame);
String mimeType = frame->loader()->responseMIMEType();
return !(DOMImplementation::isTextMIMEType(mimeType) ||
Image::supportsType(mimeType) ||
PlugInInfoStore::supportsMIMEType(mimeType));
}
void Clipboard::setAccessPolicy(ClipboardAccessPolicy policy)
{
// once you go numb, can never go back
......
......@@ -30,13 +30,20 @@
#include "AtomicString.h"
#include "ClipboardAccessPolicy.h"
#include "DragActions.h"
#include "DragImage.h"
#include "Node.h"
#include "Shared.h"
namespace WebCore {
class CachedImage;
class Element;
class Frame;
class Image;
class IntPoint;
class KURL;
class Range;
class String;
// State available during IE's events for drag and drop and copy/paste
class Clipboard : public Shared<Clipboard> {
......@@ -65,7 +72,15 @@ namespace WebCore {
virtual void setDragImage(CachedImage*, const IntPoint&) = 0;
virtual Node* dragImageElement() = 0;
virtual void setDragImageElement(Node*, const IntPoint&) = 0;
//Provides the DOM specified
virtual DragImageRef createDragImage(IntPoint& dragLoc) const = 0;
virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*) = 0;
virtual void writeURL(const KURL&, const String&, Frame*) = 0;
virtual void writeRange(Range*, Frame*) = 0;
virtual bool hasData() = 0;
void setAccessPolicy(ClipboardAccessPolicy);
bool sourceOperation(DragOperation&) const;
......@@ -74,6 +89,7 @@ namespace WebCore {
void setDestinationOperation(DragOperation);
void setDragHasStarted() { m_dragStarted = true; }
static bool canSaveAsWebArchive(Frame*);
protected:
ClipboardAccessPolicy policy() const { return m_policy; }
bool dragStarted() const { return m_dragStarted; }
......
......@@ -28,21 +28,50 @@
#define DragClient_h
#include "DragActions.h"
#include "DragImage.h"
#include "IntPoint.h"
namespace WebCore {
#if PLATFORM(MAC)
#ifdef __OBJC__
@class DOMElement;
@class NSURL;
@class NSString;
@class NSPasteboard;
#else
class DOMElement;
class NSURL;
class NSString;
class NSPasteboard;
#endif
#endif
namespace WebCore {
class Clipboard;
class DragData;
class Frame;
class Image;
class HTMLImageElement;
class DragClient {
public:
virtual void willPerformDragDestinationAction(DragDestinationAction, DragData*) = 0;
virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*) = 0;
virtual DragDestinationAction actionMaskForDrag(DragData*) = 0;
virtual void dragControllerDestroyed() = 0;
//We work in window rather than view coordinates here
virtual DragSourceAction dragSourceActionMaskForPoint(const IntPoint& windowPoint) = 0;
virtual void startDrag(DragImageRef dragImage, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, Frame*, bool linkDrag = false) = 0;
virtual DragImageRef createDragImageForLink(KURL&, const String& label, Frame*) = 0;
virtual void dragControllerDestroyed() = 0;
#if PLATFORM(MAC)
//Mac specific helper functions to allow access to functionality in webkit -- such as
//web archives and NSPasteboard extras
//not abstract as that would require another #if PLATFORM(MAC) for the SVGImage client empty impl
virtual void declareAndWriteDragImage(NSPasteboard*, DOMElement*, NSURL*, NSString*, Frame*, bool canSaveAsWebArchive) {};
#endif
virtual ~DragClient() {};
};
......
......@@ -38,21 +38,25 @@
#include "EventHandler.h"
#include "DragClient.h"
#include "DragData.h"
#include "FloatRect.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameView.h"
#include "HTMLAnchorElement.h"
#include "Image.h"
#include "markup.h"
#include "MoveSelectionCommand.h"
#include "Node.h"
#include "Page.h"
#include "PlugInInfoStore.h"
#include "RenderImage.h"
#include "ReplaceSelectionCommand.h"
#include "ResourceRequest.h"
#include "SelectionController.h"
#include "Settings.h"
#include "SystemTime.h"
#include "Text.h"
#include "wtf/RefPtr.h"
#include <wtf/RefPtr.h>
namespace WebCore {
......@@ -167,7 +171,7 @@ void DragController::dragExited(DragData* dragData)
ASSERT(dragData);
Frame* mainFrame = m_page->mainFrame();
if (mainFrame->view()) {
if (RefPtr<FrameView> v = mainFrame->view()) {
ClipboardAccessPolicy policy = mainFrame->loader()->baseURL().isLocalFile() ? ClipboardReadable : ClipboardTypesReadable;
RefPtr<Clipboard> clipboard = dragData->createClipboard(policy);
clipboard->setSourceOperation(dragData->draggingSourceOperationMask());
......@@ -191,7 +195,7 @@ bool DragController::performDrag(DragData* dragData)
if (m_isHandlingDrag) {
ASSERT(m_dragDestinationAction & DragDestinationActionDHTML);
m_client->willPerformDragDestinationAction(DragDestinationActionDHTML, dragData);
Frame* mainFrame = m_page->mainFrame();
RefPtr<Frame> mainFrame = m_page->mainFrame();
if (mainFrame->view()) {
// Sending an event can result in the destruction of the view and part.
RefPtr<Clipboard> clipboard = dragData->createClipboard(ClipboardReadable);
......@@ -251,7 +255,7 @@ DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinatio
operation = tryDHTMLDrag(dragData);
m_isHandlingDrag = operation != DragOperationNone;
FrameView *frameView = 0;
RefPtr<FrameView> frameView = 0;
if (!m_document || !(frameView = m_document->view()))
return operation;
......@@ -386,8 +390,9 @@ DragOperation DragController::tryDHTMLDrag(DragData* dragData)
{
ASSERT(dragData);
DragOperation op = DragOperationNone;
Frame* frame = m_page->mainFrame();
if (!frame->view())
RefPtr<Frame> frame = m_page->mainFrame();
RefPtr<FrameView> viewProtector = frame->view();
if (!viewProtector)
return DragOperationNone;
ClipboardAccessPolicy policy = frame->loader()->baseURL().isLocalFile() ? ClipboardReadable : ClipboardTypesReadable;
......@@ -448,5 +453,225 @@ bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPo
return false;
}
static CachedImage* getCachedImage(Element* element)
{
ASSERT(element);
RenderObject* renderer = element->renderer();
if (!renderer || !renderer->isImage())
return 0;
RenderImage* image = static_cast<RenderImage*>(renderer);
return image->cachedImage();
}
static Image* getImage(Element* element)
{
ASSERT(element);
RenderObject* renderer = element->renderer();
if (!renderer || !renderer->isImage())
return 0;
RenderImage* image = static_cast<RenderImage*>(renderer);
if (image->cachedImage() && !image->cachedImage()->isErrorImage())
return image->cachedImage()->image();
return 0;
}
static void prepareClipboardForImageDrag(Frame* src, Clipboard* clipboard, Element* node, const KURL& linkURL, const KURL& imageURL, const String& label)
{
RefPtr<Range> range = src->document()->createRange();
ExceptionCode ec = 0;
range->selectNode(node, ec);
ASSERT(ec == 0);
src->selectionController()->setSelection(Selection(range.get(), DOWNSTREAM));
clipboard->declareAndWriteDragImage(node, !linkURL.isEmpty() ? linkURL : imageURL, label, src);
}
static IntPoint dragLocForDHTMLDrag(const IntPoint& mouseDraggedPoint, const IntPoint& dragOrigin, const IntPoint& dragImageOffset, bool isLinkImage)
{
// dragImageOffset is the cursor position relative to the lower-left corner of the image.
#if PLATFORM(MAC)
// We add in the Y dimension because we are a flipped view, so adding moves the image down.
const int yOffset = dragImageOffset.y();
#else
const int yOffset = -dragImageOffset.y();
#endif
if (isLinkImage)
return IntPoint(mouseDraggedPoint.x() - dragImageOffset.x(), mouseDraggedPoint.y() + yOffset);
return IntPoint(dragOrigin.x() - dragImageOffset.x(), dragOrigin.y() + yOffset);
}
static IntPoint dragLocForSelectionDrag(Frame* src)
{
IntRect draggingRect = enclosingIntRect(src->visibleSelectionRect());
int xpos = draggingRect.right();
xpos = draggingRect.x() < xpos ? draggingRect.x() : xpos;
int ypos = draggingRect.bottom();
#if PLATFORM(MAC)
// Deal with flipped coordinates on Mac
ypos = draggingRect.y() > ypos ? draggingRect.y() : ypos;
#else
ypos = draggingRect.y() < ypos ? draggingRect.y() : ypos;
#endif
return IntPoint(xpos, ypos);
}
bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, bool isDHTMLDrag)
{
ASSERT(src);
ASSERT(clipboard);
if (!src->view() || !src->renderer())
return false;
HitTestResult dragSource = HitTestResult(dragOrigin);
dragSource = src->eventHandler()->hitTestResultAtPoint(dragOrigin, true);
KURL linkURL = dragSource.absoluteLinkURL();
KURL imageURL = dragSource.absoluteImageURL();
bool isSelected = dragSource.isSelected();
IntPoint mouseDraggedPoint = src->view()->windowToContents(dragEvent.pos());
m_draggingImageURL = KURL();
m_dragOperation = srcOp;
DragImageRef dragImage = 0;
IntPoint dragLoc(0, 0);
IntPoint dragImageOffset(0, 0);
if (isDHTMLDrag)
dragImage = clipboard->createDragImage(dragImageOffset);
// We allow DHTML/JS to set the drag image, even if its a link, image or text we're dragging.
// This is in the spirit of the IE API, which allows overriding of pasteboard data and DragOp.
if (dragImage) {
dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, !linkURL.isEmpty());
m_dragOffset = dragImageOffset;
}
bool startedDrag = true; // optimism - we almost always manage to start the drag
Node* node = dragSource.innerNonSharedNode();
if (!imageURL.isEmpty() && node && node->isElementNode()
&& getImage(static_cast<Element*>(node))
&& (m_dragSourceAction & DragSourceActionImage)) {
Element* element = static_cast<Element*>(node);
if (!clipboard->hasData()) {
m_draggingImageURL = imageURL;
prepareClipboardForImageDrag(src, clipboard, element, linkURL, imageURL, dragSource.altDisplayString());
}
m_client->willPerformDragSourceAction(DragSourceActionImage, dragOrigin, clipboard);
if (!dragImage) {
IntRect imageRect = dragSource.imageRect();
imageRect.setLocation(m_page->mainFrame()->view()->windowToContents(src->view()->contentsToWindow(imageRect.location())));
doImageDrag(element, dragOrigin, dragSource.imageRect(), clipboard, src, m_dragOffset);
} else
// DHTML defined drag image
doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
} else if (!linkURL.isEmpty() && (m_dragSourceAction & DragSourceActionLink)) {
if (!clipboard->hasData())
clipboard->writeURL(linkURL, dragSource.textContent(), src);
m_client->willPerformDragSourceAction(DragSourceActionLink, dragOrigin, clipboard);
if (!dragImage) {
dragImage = m_client->createDragImageForLink(linkURL, dragSource.textContent(), src);
IntSize size = dragImageSize(dragImage);
m_dragOffset = IntPoint(-size.width() / 2, -LinkDragBorderInset);
dragLoc = IntPoint(mouseDraggedPoint.x() + m_dragOffset.x(), mouseDraggedPoint.y() + m_dragOffset.y());
}
doSystemDrag(dragImage, dragLoc, src->view()->contentsToWindow(mouseDraggedPoint), clipboard, src, true);
} else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
RefPtr<Range> selectionRange = src->selectionController()->toRange();
ASSERT(selectionRange);
if (!clipboard->hasData())
clipboard->writeRange(selectionRange.get(), src);
m_client->willPerformDragSourceAction(DragSourceActionSelection, dragOrigin, clipboard);
if (!dragImage) {
dragImage = createDragImageForSelection(src);
dragLoc = dragLocForSelectionDrag(src);
m_dragOffset = IntPoint((int)(dragOrigin.x() - dragLoc.x()), (int)(dragOrigin.y() - dragLoc.y()));
}
doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
} else if (isDHTMLDrag) {
ASSERT(m_dragSourceAction & DragSourceActionDHTML);
m_client->willPerformDragSourceAction(DragSourceActionDHTML, dragOrigin, clipboard);
doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
} else {
// Only way I know to get here is if to get here is if the original element clicked on in the mousedown is no longer
// under the mousedown point, so linkURL, imageURL and isSelected are all false/empty.
startedDrag = false;
}
if (dragImage)
deleteDragImage(dragImage);
return startedDrag;
}
void DragController::doImageDrag(Element* element, const IntPoint& dragOrigin, const IntRect& rect, Clipboard* clipboard, Frame* frame, IntPoint& dragImageOffset)
{
IntPoint mouseDownPoint = dragOrigin;
DragImageRef dragImage;
IntPoint origin;
Image* image = getImage(element);
if (image && image->size().height() * image->size().width() <= MaxOriginalImageArea) {
IntSize originalSize = rect.size();
origin = rect.location();
dragImage = createDragImageFromImage(image);
IntSize newSize;
if (dragImage) {
dragImage = fitDragImageToMaxSize(dragImage, MaxDragImageSize);
dragImage = dissolveDragImageToFraction(dragImage, DragImageAlpha);
newSize = dragImageSize(dragImage);
}
// Properly orient the drag image and orient it differently if it's smaller than the original
float scale = newSize.width() / (float)originalSize.width();
float dx = origin.x() - mouseDownPoint.x();
dx *= scale;
origin.setX((int)(dx + 0.5));
#if PLATFORM(MAC)
//Compensate for accursed flipped coordinates in cocoa
origin.setY(origin.y() + originalSize.height());
#endif
float dy = origin.y() - mouseDownPoint.y();
dy *= scale;
origin.setY((int)(dy + 0.5));
} else {
dragImage = createDragImageIconForCachedImage(getCachedImage(element));
if (dragImage)
origin = IntPoint(DragIconRightInset - dragImageSize(dragImage).width(), DragIconBottomInset);
}
dragImageOffset.setX(mouseDownPoint.x() + origin.x());
dragImageOffset.setY(mouseDownPoint.y() + origin.y());
doSystemDrag(dragImage, dragImageOffset, dragOrigin, clipboard, frame, false);
deleteDragImage(dragImage);