Changeset 19689 in webkit


Ignore:
Timestamp:
Feb 18, 2007 4:30:55 AM (17 years ago)
Author:
oliver
Message:

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



Location:
trunk
Files:
4 added
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r19687 r19689  
     12007-02-18  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Adam.
     4
     5        More drag and drop migration, now the entirety of the
     6        drag initiation logic has been rendered platform independent
     7        This has required a number of new interfaces, and a reasonable
     8        amount of logic migration.
     9
     10        As a side effect, this patch also fixes rdar://problem/4945341
     11
     12        There are some basic Qt stubs that should stop the build from failing,
     13        however the absence of ClipboardQt means any attempt to initiate a drag
     14        may cause a crash.
     15
     16        * WebCore.exp:
     17           Exporting new symbols
     18
     19        * WebCore.xcodeproj/project.pbxproj:
     20           New files
     21
     22        * dom/Clipboard.cpp:
     23        (WebCore::Clipboard::canSaveAsWebArchive):
     24          Migrated from WebKit
     25
     26        * dom/Clipboard.h:
     27          Added more methods to allow Clipboard to be used as a
     28          platform independent container for drag and drop
     29
     30        * page/DragClient.h:
     31        (WebCore::DragClient::declareAndWriteDragImage):
     32          This is a mac only helper function, so i've made it have an empty implementation,
     33          that way we won't need a PLATFORM(MAC) block in SVGImageEmptyClients
     34
     35        * page/DragController.cpp:
     36        (WebCore::DragController::dragExited):
     37        (WebCore::DragController::performDrag):
     38        (WebCore::DragController::tryDocumentDrag):
     39        (WebCore::DragController::tryDHTMLDrag):
     40          Using RefPtrs now
     41        (WebCore::getCachedImage):
     42        (WebCore::getImage):
     43          Helper functions                   
     44        (WebCore::dragLocForDHTMLDrag):
     45        (WebCore::dragLocForSelectionDrag):
     46        (WebCore::DragController::startDrag):
     47        (WebCore::DragController::doImageDrag):
     48        (WebCore::DragController::doSystemDrag):
     49          Logic that generates drag images and clipboard content, and
     50          initiates the actual system drag operation
     51
     52        * page/DragController.h:
     53          Method and variable declarations
     54
     55        * page/EventHandler.cpp:
     56        (WebCore::EventHandler::handleDrag):
     57          handleDrag is now platform independent
     58        (WebCore::EventHandler::handleTextInputEvent):
     59           formatting
     60
     61        * page/EventHandler.h:
     62        (WebCore::EventHandler::eventLoopHandleMouseDragged):
     63          Forgot to define this stub function
     64
     65        * page/Frame.h:
     66          Declaring dragImageForSelection to provide drag image for selected content
     67
     68        * page/mac/DragControllerMac.mm:
     69          Defining drag images control vars
     70
     71        * page/mac/EventHandlerMac.mm:
     72        (WebCore::EventHandler::createDraggingClipboard):
     73          Migrated old clipboard creation to here
     74
     75        * page/mac/FrameMac.mm:
     76        (WebCore::Frame::dragImageForSelection):
     77          Wrap FrameMac::selectionImage
     78
     79        * page/qt/DragControllerQt.cpp:
     80          Defining drag images control vars
     81
     82        * page/qt/EventHandlerQt.cpp:
     83        (WebCore::EventHandler::createDraggingClipboard):
     84          stub
     85
     86        * page/qt/FrameQt.cpp:
     87        (WebCore::Frame::dragImageForSelection):
     88          stub
     89
     90        * platform/DragImage.cpp: Added.
     91        (WebCore::fitDragImageToMaxSize):
     92        (WebCore::createDragImageForSelection):
     93           Platform independent processing for drag images
     94
     95        * platform/DragImage.h: Added.
     96           Declaring typedefs and wrapper functions to abstract the handling
     97           of drag images
     98
     99        * platform/Pasteboard.h:
     100          Declaring extracted writeURL and writeSelection methods
     101
     102        * platform/graphics/svg/SVGImageEmptyClients.h:
     103        (WebCore::SVGEmptyDragClient::willPerformDragSourceAction):
     104        (WebCore::SVGEmptyDragClient::startDrag):
     105        (WebCore::SVGEmptyDragClient::createDragImageForLink):
     106          Stubs FTW!
     107
     108        * platform/mac/ClipboardMac.h:
     109        (WebCore::ClipboardMac::pasteboard):
     110          Provide accessor for underlying NSPasteboard
     111
     112        * platform/mac/ClipboardMac.mm:
     113        (WebCore::ClipboardMac::hasData):
     114        (WebCore::ClipboardMac::writeRange):
     115        (WebCore::ClipboardMac::writeURL):
     116        (WebCore::ClipboardMac::declareAndWriteDragImage):
     117        (WebCore::ClipboardMac::createDragImage):
     118           Implemented new Clipboarid functionality.
     119        (WebCore::ClipboardMac::dragNSImage):
     120           Made this a const method
     121
     122        * platform/mac/DragImageMac.mm: Added.
     123        (WebCore::dragImageSize):
     124        (WebCore::deleteDragImage):
     125        (WebCore::scaleDragImage):
     126        (WebCore::dissolveDragImageToFraction):
     127        (WebCore::createDragImageFromImage):
     128        (WebCore::createDragImageIconForCachedImage):
     129           Implemented platform specific DragImage functions
     130
     131        * platform/mac/PasteboardMac.mm:
     132        (WebCore::writeSelection):
     133        (WebCore::Pasteboard::writeSelection):
     134        (WebCore::writeURL):
     135        (WebCore::Pasteboard::writeURL):
     136           Extracted member implementations of these functions, so that
     137           Clipboard could also make use of this functionality.
     138           Pasteboard methods now call the new non-member implementations.
     139           Also fixed implementations to respect the list of requested types.
     140
     141        * platform/qt/DragImageQt.cpp: Added.
     142        (WebCore::dragImageSize):
     143        (WebCore::deleteDragImage):
     144        (WebCore::scaleDragImage):
     145        (WebCore::dissolveDragImageToFraction):
     146        (WebCore::createDragImageFromImage):
     147        (WebCore::createDragImageIconForCachedImage): 
     148          Stubs
     149
    11502007-02-17  David Hyatt  <hyatt@apple.com>
    2151
  • trunk/WebCore/WebCore.exp

    r19579 r19689  
    198198__ZN7WebCore12EventHandler10wheelEventEP7NSEvent
    199199__ZN7WebCore12EventHandler12mouseDraggedEP7NSEvent
     200__ZN7WebCore12EventHandler14currentNSEventEv
    200201__ZN7WebCore12EventHandler20handleTextInputEventERKNS_6StringEPNS_5EventEbb
    201202__ZN7WebCore12EventHandler20hitTestResultAtPointERKNS_8IntPointEb
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r19650 r19689  
    16561656                A7CA595E0B27BD9E00FA021D /* DragController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7CA595C0B27BD9E00FA021D /* DragController.cpp */; };
    16571657                A7CA59630B27C1F200FA021D /* DragClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CA59620B27C1F200FA021D /* DragClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1658                A7CFB3D10B7ED10A0070C32D /* DragImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */; };
     1659                A7CFB3D20B7ED10A0070C32D /* DragImage.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CFB3D00B7ED10A0070C32D /* DragImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1660                A7CFB3D50B7ED1180070C32D /* DragImageMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A7CFB3D40B7ED1180070C32D /* DragImageMac.mm */; };
    16581661                A7D3C5240B576B4B002CA450 /* PasteboardHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D3C5230B576B4B002CA450 /* PasteboardHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };
    16591662                A809F1470B73793A002E4D7F /* RenderSVGGradientStop.h in Headers */ = {isa = PBXBuildFile; fileRef = A809F1450B73793A002E4D7F /* RenderSVGGradientStop.h */; };
     
    46684671                A7B6E69D0B291A9600D0529F /* DragData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragData.h; sourceTree = "<group>"; };
    46694672                A7CA595B0B27BD9E00FA021D /* DragController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragController.h; sourceTree = "<group>"; };
    4670                 A7CA595C0B27BD9E00FA021D /* DragController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DragController.cpp; sourceTree = "<group>"; };
     4673                A7CA595C0B27BD9E00FA021D /* DragController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = DragController.cpp; sourceTree = "<group>"; };
    46714674                A7CA59620B27C1F200FA021D /* DragClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragClient.h; sourceTree = "<group>"; };
     4675                A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DragImage.cpp; sourceTree = "<group>"; };
     4676                A7CFB3D00B7ED10A0070C32D /* DragImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DragImage.h; sourceTree = "<group>"; };
     4677                A7CFB3D40B7ED1180070C32D /* DragImageMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = DragImageMac.mm; sourceTree = "<group>"; };
    46724678                A7D3C5230B576B4B002CA450 /* PasteboardHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PasteboardHelper.h; sourceTree = "<group>"; };
    46734679                A809F1450B73793A002E4D7F /* RenderSVGGradientStop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGGradientStop.h; sourceTree = "<group>"; };
     
    68026808                        isa = PBXGroup;
    68036809                        children = (
     6810                                A7CFB3D40B7ED1180070C32D /* DragImageMac.mm */,
    68046811                                A795463D0B5C4C80007B438F /* DragDataMac.mm */,
    68056812                                06027CB20B1CC03D00884B2D /* ContextMenuItemMac.mm */,
     
    90539060                                F587853B02DE375901EA4122 /* DeprecatedValueListImpl.h */,
    90549061                                A7B6E69D0B291A9600D0529F /* DragData.h */,
     9062                                A7CFB3D00B7ED10A0070C32D /* DragImage.h */,
     9063                                A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */,
    90559064                                934FE9E40B5CA539003E4A73 /* FileChooser.cpp */,
    90569065                                066C772A0AB603B700238CC4 /* FileChooser.h */,
     
    96419650                        buildActionMask = 2147483647;
    96429651                        files = (
     9652                                A7CFB3D20B7ED10A0070C32D /* DragImage.h in Headers */,
    96439653                                A7D3C5240B576B4B002CA450 /* PasteboardHelper.h in Headers */,
    96449654                                A718760E0B2A120100A16ECE /* DragActions.h in Headers */,
     
    1115011160                        isa = PBXProject;
    1115111161                        buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
     11162                        compatibilityVersion = "Xcode 2.4";
    1115211163                        hasScannedForEncodings = 1;
    1115311164                        knownRegions = (
     
    1116411175                        projectDirPath = "";
    1116511176                        projectRoot = "";
     11177                        shouldCheckCompatibility = 1;
    1116611178                        targets = (
    1116711179                                93F198A508245E59001E9ABC /* WebCore */,
     
    1247012482                                933A14AA0B7D1D0900A53FFD /* DOMTextEvent.mm in Sources */,
    1247112483                                933A14B80B7D1D5200A53FFD /* JSTextEvent.cpp in Sources */,
     12484                                A7CFB3D10B7ED10A0070C32D /* DragImage.cpp in Sources */,
     12485                                A7CFB3D50B7ED1180070C32D /* DragImageMac.mm in Sources */,
    1247212486                        );
    1247312487                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/WebCore/dom/Clipboard.cpp

    r19327 r19689  
    2727#include "Clipboard.h"
    2828
     29#include "DOMImplementation.h"
     30#include "Frame.h"
     31#include "FrameLoader.h"
     32#include "Image.h"
     33#include "PlugInInfoStore.h"
     34
    2935namespace WebCore {
    3036
     37bool Clipboard::canSaveAsWebArchive(Frame* frame)
     38{
     39    ASSERT(frame);
     40    String mimeType = frame->loader()->responseMIMEType();
     41   
     42    return !(DOMImplementation::isTextMIMEType(mimeType) ||
     43             Image::supportsType(mimeType) ||
     44             PlugInInfoStore::supportsMIMEType(mimeType));
     45}
     46   
    3147void Clipboard::setAccessPolicy(ClipboardAccessPolicy policy)
    3248{
  • trunk/WebCore/dom/Clipboard.h

    r19327 r19689  
    3131#include "ClipboardAccessPolicy.h"
    3232#include "DragActions.h"
     33#include "DragImage.h"
    3334#include "Node.h"
    3435#include "Shared.h"
     
    3738
    3839    class CachedImage;
     40    class Element;
     41    class Frame;
     42    class Image;
    3943    class IntPoint;
     44    class KURL;
     45    class Range;
     46    class String;
    4047
    4148    // State available during IE's events for drag and drop and copy/paste
     
    6673        virtual Node* dragImageElement() = 0;
    6774        virtual void setDragImageElement(Node*, const IntPoint&) = 0;
     75       
     76        //Provides the DOM specified
     77        virtual DragImageRef createDragImage(IntPoint& dragLoc) const = 0;
     78        virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*) = 0;
     79        virtual void writeURL(const KURL&, const String&, Frame*) = 0;
     80        virtual void writeRange(Range*, Frame*) = 0;
    6881
     82        virtual bool hasData() = 0;
     83       
    6984        void setAccessPolicy(ClipboardAccessPolicy);
    7085
     
    7590       
    7691        void setDragHasStarted() { m_dragStarted = true; }
     92        static bool canSaveAsWebArchive(Frame*);
    7793    protected:
    7894        ClipboardAccessPolicy policy() const { return m_policy; }
  • trunk/WebCore/page/DragClient.h

    r19327 r19689  
    2929
    3030#include "DragActions.h"
     31#include "DragImage.h"
    3132#include "IntPoint.h"
    3233
     34#if PLATFORM(MAC)
     35#ifdef __OBJC__
     36@class DOMElement;
     37@class NSURL;
     38@class NSString;
     39@class NSPasteboard;
     40#else
     41class DOMElement;
     42class NSURL;
     43class NSString;
     44class NSPasteboard;
     45#endif
     46#endif
     47
    3348namespace WebCore {
    34 
     49   
     50    class Clipboard;
    3551    class DragData;
     52    class Frame;
     53    class Image;
     54    class HTMLImageElement;
    3655   
    3756    class DragClient {
    3857    public:
    3958        virtual void willPerformDragDestinationAction(DragDestinationAction, DragData*) = 0;
     59        virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*) = 0;
    4060        virtual DragDestinationAction actionMaskForDrag(DragData*) = 0;
    41         virtual void dragControllerDestroyed() = 0;
    42        
    4361        //We work in window rather than view coordinates here
    4462        virtual DragSourceAction dragSourceActionMaskForPoint(const IntPoint& windowPoint) = 0;
    45 
     63       
     64        virtual void startDrag(DragImageRef dragImage, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, Frame*, bool linkDrag = false) = 0;
     65        virtual DragImageRef createDragImageForLink(KURL&, const String& label, Frame*) = 0;
     66       
     67        virtual void dragControllerDestroyed() = 0;
     68#if PLATFORM(MAC)
     69        //Mac specific helper functions to allow access to functionality in webkit -- such as
     70        //web archives and NSPasteboard extras
     71        //not abstract as that would require another #if PLATFORM(MAC) for the SVGImage client empty impl
     72        virtual void declareAndWriteDragImage(NSPasteboard*, DOMElement*, NSURL*, NSString*, Frame*, bool canSaveAsWebArchive) {};
     73#endif
     74       
    4675        virtual ~DragClient() {};
    4776    };
  • trunk/WebCore/page/DragController.cpp

    r19327 r19689  
    3939#include "DragClient.h"
    4040#include "DragData.h"
     41#include "FloatRect.h"
    4142#include "Frame.h"
    4243#include "FrameLoader.h"
    4344#include "FrameView.h"
    4445#include "HTMLAnchorElement.h"
     46#include "Image.h"
    4547#include "markup.h"
    4648#include "MoveSelectionCommand.h"
    4749#include "Node.h"
    4850#include "Page.h"
     51#include "PlugInInfoStore.h"
     52#include "RenderImage.h"
    4953#include "ReplaceSelectionCommand.h"
    5054#include "ResourceRequest.h"
     
    5357#include "SystemTime.h"
    5458#include "Text.h"
    55 #include "wtf/RefPtr.h"
     59#include <wtf/RefPtr.h>
    5660
    5761namespace WebCore {
     
    168172    Frame* mainFrame = m_page->mainFrame();
    169173   
    170     if (mainFrame->view()) {
     174    if (RefPtr<FrameView> v = mainFrame->view()) {
    171175        ClipboardAccessPolicy policy = mainFrame->loader()->baseURL().isLocalFile() ? ClipboardReadable : ClipboardTypesReadable;
    172176        RefPtr<Clipboard> clipboard = dragData->createClipboard(policy);
     
    192196        ASSERT(m_dragDestinationAction & DragDestinationActionDHTML);
    193197        m_client->willPerformDragDestinationAction(DragDestinationActionDHTML, dragData);
    194         Frame* mainFrame = m_page->mainFrame();
     198        RefPtr<Frame> mainFrame = m_page->mainFrame();
    195199        if (mainFrame->view()) {
    196200            // Sending an event can result in the destruction of the view and part.
     
    252256    m_isHandlingDrag = operation != DragOperationNone;
    253257
    254     FrameView *frameView = 0;
     258    RefPtr<FrameView> frameView = 0;
    255259    if (!m_document || !(frameView = m_document->view()))
    256260        return operation;
     
    387391    ASSERT(dragData);
    388392    DragOperation op = DragOperationNone;
    389     Frame* frame = m_page->mainFrame();
    390     if (!frame->view())
     393    RefPtr<Frame> frame = m_page->mainFrame();
     394    RefPtr<FrameView> viewProtector = frame->view();
     395    if (!viewProtector)
    391396        return DragOperationNone;
    392397   
     
    449454
    450455}
    451 
    452 }
     456   
     457static CachedImage* getCachedImage(Element* element)
     458{
     459    ASSERT(element);
     460    RenderObject* renderer = element->renderer();
     461    if (!renderer || !renderer->isImage())
     462        return 0;
     463    RenderImage* image = static_cast<RenderImage*>(renderer);
     464    return image->cachedImage();
     465}
     466   
     467static Image* getImage(Element* element)
     468{
     469    ASSERT(element);
     470    RenderObject* renderer = element->renderer();
     471    if (!renderer || !renderer->isImage())
     472        return 0;
     473   
     474    RenderImage* image = static_cast<RenderImage*>(renderer);
     475    if (image->cachedImage() && !image->cachedImage()->isErrorImage())
     476        return image->cachedImage()->image();
     477    return 0;
     478}
     479   
     480static void prepareClipboardForImageDrag(Frame* src, Clipboard* clipboard, Element* node, const KURL& linkURL, const KURL& imageURL, const String& label)
     481{
     482    RefPtr<Range> range = src->document()->createRange();
     483    ExceptionCode ec = 0;
     484    range->selectNode(node, ec);
     485    ASSERT(ec == 0);
     486    src->selectionController()->setSelection(Selection(range.get(), DOWNSTREAM));           
     487    clipboard->declareAndWriteDragImage(node, !linkURL.isEmpty() ? linkURL : imageURL, label, src);
     488}
     489   
     490static IntPoint dragLocForDHTMLDrag(const IntPoint& mouseDraggedPoint, const IntPoint& dragOrigin, const IntPoint& dragImageOffset, bool isLinkImage)
     491{
     492    // dragImageOffset is the cursor position relative to the lower-left corner of the image.
     493#if PLATFORM(MAC)
     494    // We add in the Y dimension because we are a flipped view, so adding moves the image down.
     495    const int yOffset = dragImageOffset.y();
     496#else
     497    const int yOffset = -dragImageOffset.y();
     498#endif
     499   
     500    if (isLinkImage)
     501        return IntPoint(mouseDraggedPoint.x() - dragImageOffset.x(), mouseDraggedPoint.y() + yOffset);
     502   
     503    return IntPoint(dragOrigin.x() - dragImageOffset.x(), dragOrigin.y() + yOffset);
     504}
     505   
     506static IntPoint dragLocForSelectionDrag(Frame* src)
     507{
     508    IntRect draggingRect = enclosingIntRect(src->visibleSelectionRect());
     509    int xpos = draggingRect.right();
     510    xpos = draggingRect.x() < xpos ? draggingRect.x() : xpos;
     511    int ypos = draggingRect.bottom();
     512#if PLATFORM(MAC)
     513    // Deal with flipped coordinates on Mac
     514    ypos = draggingRect.y() > ypos ? draggingRect.y() : ypos;
     515#else
     516    ypos = draggingRect.y() < ypos ? draggingRect.y() : ypos;
     517#endif
     518    return IntPoint(xpos, ypos);
     519}
     520   
     521bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, bool isDHTMLDrag)
     522{   
     523    ASSERT(src);
     524    ASSERT(clipboard);
     525   
     526    if (!src->view() || !src->renderer())
     527        return false;
     528   
     529    HitTestResult dragSource = HitTestResult(dragOrigin);
     530    dragSource = src->eventHandler()->hitTestResultAtPoint(dragOrigin, true);
     531    KURL linkURL = dragSource.absoluteLinkURL();
     532    KURL imageURL = dragSource.absoluteImageURL();
     533    bool isSelected = dragSource.isSelected();
     534   
     535    IntPoint mouseDraggedPoint = src->view()->windowToContents(dragEvent.pos());
     536   
     537    m_draggingImageURL = KURL();
     538    m_dragOperation = srcOp;
     539   
     540    DragImageRef dragImage = 0;
     541    IntPoint dragLoc(0, 0);
     542    IntPoint dragImageOffset(0, 0);
     543   
     544    if (isDHTMLDrag)
     545        dragImage = clipboard->createDragImage(dragImageOffset);
     546   
     547    // We allow DHTML/JS to set the drag image, even if its a link, image or text we're dragging.
     548    // This is in the spirit of the IE API, which allows overriding of pasteboard data and DragOp.
     549    if (dragImage) {
     550        dragLoc = dragLocForDHTMLDrag(mouseDraggedPoint, dragOrigin, dragImageOffset, !linkURL.isEmpty());
     551        m_dragOffset = dragImageOffset;
     552    }
     553   
     554    bool startedDrag = true; // optimism - we almost always manage to start the drag
     555   
     556    Node* node = dragSource.innerNonSharedNode();
     557   
     558    if (!imageURL.isEmpty() && node && node->isElementNode()
     559            && getImage(static_cast<Element*>(node))
     560            && (m_dragSourceAction & DragSourceActionImage)) {
     561        Element* element = static_cast<Element*>(node);
     562        if (!clipboard->hasData()) {
     563            m_draggingImageURL = imageURL;
     564            prepareClipboardForImageDrag(src, clipboard, element, linkURL, imageURL, dragSource.altDisplayString());
     565        }
     566       
     567        m_client->willPerformDragSourceAction(DragSourceActionImage, dragOrigin, clipboard);
     568       
     569        if (!dragImage) {
     570            IntRect imageRect = dragSource.imageRect();
     571            imageRect.setLocation(m_page->mainFrame()->view()->windowToContents(src->view()->contentsToWindow(imageRect.location())));
     572            doImageDrag(element, dragOrigin, dragSource.imageRect(), clipboard, src, m_dragOffset);
     573        } else
     574            // DHTML defined drag image
     575            doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
     576
     577    } else if (!linkURL.isEmpty() && (m_dragSourceAction & DragSourceActionLink)) {
     578        if (!clipboard->hasData())
     579            clipboard->writeURL(linkURL, dragSource.textContent(), src);
     580       
     581        m_client->willPerformDragSourceAction(DragSourceActionLink, dragOrigin, clipboard);
     582        if (!dragImage) {
     583            dragImage = m_client->createDragImageForLink(linkURL, dragSource.textContent(), src);
     584            IntSize size = dragImageSize(dragImage);
     585            m_dragOffset = IntPoint(-size.width() / 2, -LinkDragBorderInset);
     586            dragLoc = IntPoint(mouseDraggedPoint.x() + m_dragOffset.x(), mouseDraggedPoint.y() + m_dragOffset.y());
     587        }
     588        doSystemDrag(dragImage, dragLoc, src->view()->contentsToWindow(mouseDraggedPoint), clipboard, src, true);
     589    } else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
     590        RefPtr<Range> selectionRange = src->selectionController()->toRange();
     591        ASSERT(selectionRange);
     592        if (!clipboard->hasData())
     593            clipboard->writeRange(selectionRange.get(), src);
     594        m_client->willPerformDragSourceAction(DragSourceActionSelection, dragOrigin, clipboard);
     595        if (!dragImage) {
     596            dragImage = createDragImageForSelection(src);
     597            dragLoc = dragLocForSelectionDrag(src);
     598            m_dragOffset = IntPoint((int)(dragOrigin.x() - dragLoc.x()), (int)(dragOrigin.y() - dragLoc.y()));
     599        }
     600        doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
     601    } else if (isDHTMLDrag) {
     602        ASSERT(m_dragSourceAction & DragSourceActionDHTML);
     603        m_client->willPerformDragSourceAction(DragSourceActionDHTML, dragOrigin, clipboard);
     604        doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
     605    } else {
     606        // 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
     607        // under the mousedown point, so linkURL, imageURL and isSelected are all false/empty.
     608        startedDrag = false;
     609    }
     610   
     611    if (dragImage)
     612        deleteDragImage(dragImage);
     613    return startedDrag;
     614}
     615   
     616void DragController::doImageDrag(Element* element, const IntPoint& dragOrigin, const IntRect& rect, Clipboard* clipboard, Frame* frame, IntPoint& dragImageOffset)
     617{
     618    IntPoint mouseDownPoint = dragOrigin;
     619    DragImageRef dragImage;
     620    IntPoint origin;
     621   
     622    Image* image = getImage(element);
     623    if (image && image->size().height() * image->size().width() <= MaxOriginalImageArea) {
     624        IntSize originalSize = rect.size();
     625        origin = rect.location();
     626       
     627        dragImage = createDragImageFromImage(image);
     628   
     629        IntSize newSize;
     630        if (dragImage) {
     631            dragImage = fitDragImageToMaxSize(dragImage, MaxDragImageSize);
     632            dragImage = dissolveDragImageToFraction(dragImage, DragImageAlpha);
     633            newSize = dragImageSize(dragImage);
     634        }
     635       
     636        // Properly orient the drag image and orient it differently if it's smaller than the original
     637        float scale = newSize.width() / (float)originalSize.width();
     638        float dx = origin.x() - mouseDownPoint.x();
     639        dx *= scale;
     640        origin.setX((int)(dx + 0.5));
     641#if PLATFORM(MAC)
     642        //Compensate for accursed flipped coordinates in cocoa
     643        origin.setY(origin.y() + originalSize.height());
     644#endif
     645        float dy = origin.y() - mouseDownPoint.y();
     646        dy *= scale;
     647        origin.setY((int)(dy + 0.5));
     648    } else {
     649        dragImage = createDragImageIconForCachedImage(getCachedImage(element));
     650        if (dragImage)
     651            origin = IntPoint(DragIconRightInset - dragImageSize(dragImage).width(), DragIconBottomInset);
     652    }
     653   
     654    dragImageOffset.setX(mouseDownPoint.x() + origin.x());
     655    dragImageOffset.setY(mouseDownPoint.y() + origin.y());
     656    doSystemDrag(dragImage, dragImageOffset, dragOrigin, clipboard, frame, false);
     657   
     658    deleteDragImage(dragImage);
     659}
     660   
     661void DragController::doSystemDrag(DragImageRef image, const IntPoint& dragLoc, const IntPoint& eventPos, Clipboard* clipboard, Frame* frame, bool forLink)
     662{
     663    m_didInitiateDrag = true;
     664    m_dragInitiator = frame->document();
     665    // Protect this frame and view, as a load may occur mid drag and attempt to unload this frame
     666    RefPtr<Frame> frameProtector = m_page->mainFrame();
     667    RefPtr<FrameView> viewProtector = frameProtector->view();
     668    m_client->startDrag(image, viewProtector->windowToContents(frame->view()->contentsToWindow(dragLoc)), eventPos, clipboard, frameProtector.get(), forLink);
     669   
     670    // Drag has ended, dragEnded *should* have been called, however it is possible 
     671    // for the UIDelegate to take over the drag, and fail to send the appropriate
     672    // drag termination event.  As dragEnded just resets drag variables, we just
     673    // call it anyway to be on the safe side
     674    dragEnded();
     675}
     676   
     677}
  • trunk/WebCore/page/DragController.h

    r19327 r19689  
    2828
    2929#include "DragActions.h"
     30#include "DragImage.h"
    3031#include "IntPoint.h"
     32#include "IntRect.h"
    3133#include "KURL.h"
    3234
     
    3739    class DragClient;
    3840    class DragData;
     41    class Element;
    3942    class Frame;
     43    class Image;
     44    class Node;
    4045    class Page;
     46    class PlatformMouseEvent;
     47    class Range;
    4148    class SelectionController;
    4249   
     
    7582        void dragEnded() { m_dragInitiator = 0; m_didInitiateDrag = false; }
    7683       
     84        bool startDrag(Frame* src, Clipboard*, DragOperation srcOp, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin, bool isDHTMLDrag);
     85       
     86        static const int LinkDragBorderInset;
     87        static const IntSize MaxDragImageSize;
     88        static const int MaxOriginalImageArea;
     89        static const int DragIconRightInset;
     90        static const int DragIconBottomInset;       
     91        static const float DragImageAlpha;
    7792    private:
    7893        bool canProcessDrag(DragData*);
     
    86101        bool dragIsMove(SelectionController*, DragData*);
    87102        bool isCopyKeyDown();
    88        
     103
     104        IntRect selectionDraggingRect(Frame*);
     105        bool doDrag(Frame* src, Clipboard* clipboard, DragImageRef dragImage, const KURL& linkURL, const KURL& imageURL, Node* node, IntPoint& dragLoc, IntPoint& dragImageOffset);
     106        void doImageDrag(Element*, const IntPoint&, const IntRect&, Clipboard*, Frame*, IntPoint&);
     107        void doSystemDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool forLink);
    89108        Page* m_page;
    90109        DragClient* m_client;
  • trunk/WebCore/page/EventHandler.cpp

    r19682 r19689  
    13541354    return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragClipboard.get());
    13551355}
    1356 
     1356   
     1357bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
     1358{
     1359    if (event.event().button() != LeftButton || event.event().eventType() != MouseEventMoved) {
     1360        // If we allowed the other side of the bridge to handle a drag
     1361        // last time, then m_mousePressed might still be set. So we
     1362        // clear it now to make sure the next move after a drag
     1363        // doesn't look like a drag.
     1364        m_mousePressed = false;
     1365        return false;
     1366    }
     1367   
     1368    if (eventLoopHandleMouseDragged(event))
     1369        return true;
     1370   
     1371    // Careful that the drag starting logic stays in sync with eventMayStartDrag()
     1372   
     1373    if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
     1374        allowDHTMLDrag(dragState().m_dragSrcMayBeDHTML, dragState().m_dragSrcMayBeUA);
     1375        if (!dragState().m_dragSrcMayBeDHTML && !dragState().m_dragSrcMayBeUA)
     1376            m_mouseDownMayStartDrag = false;     // no element is draggable
     1377    }
     1378   
     1379    if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
     1380        // try to find an element that wants to be dragged
     1381        HitTestRequest request(true, false);
     1382        HitTestResult result(m_mouseDownPos);
     1383        m_frame->renderer()->layer()->hitTest(request, result);
     1384        Node* node = result.innerNode();
     1385        if (node && node->renderer())
     1386            dragState().m_dragSrc = node->renderer()->draggableNode(dragState().m_dragSrcMayBeDHTML, dragState().m_dragSrcMayBeUA,
     1387                                                                    m_mouseDownPos.x(), m_mouseDownPos.y(), dragState().m_dragSrcIsDHTML);
     1388        else
     1389            dragState().m_dragSrc = 0;
     1390       
     1391        if (!dragState().m_dragSrc)
     1392            m_mouseDownMayStartDrag = false;     // no element is draggable
     1393        else {
     1394            // remember some facts about this source, while we have a HitTestResult handy
     1395            node = result.URLElement();
     1396            dragState().m_dragSrcIsLink = node && node->isLink();
     1397           
     1398            node = result.innerNonSharedNode();
     1399            dragState().m_dragSrcIsImage = node && node->renderer() && node->renderer()->isImage();
     1400           
     1401            dragState().m_dragSrcInSelection = m_frame->selectionController()->contains(m_mouseDownPos);
     1402        }               
     1403    }
     1404   
     1405    // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
     1406    // or else we bail on the dragging stuff and allow selection to occur
     1407    if (m_mouseDownMayStartDrag && dragState().m_dragSrcInSelection && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
     1408        m_mouseDownMayStartDrag = false;
     1409        // ...but if this was the first click in the window, we don't even want to start selection
     1410        if (eventActivatedView(event.event()))
     1411            m_mouseDownMayStartSelect = false;
     1412    }
     1413   
     1414    if (!m_mouseDownMayStartDrag)
     1415        return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
     1416   
     1417    // We are starting a text/image/url drag, so the cursor should be an arrow
     1418    m_frame->view()->setCursor(pointerCursor());
     1419   
     1420    if (!dragHysteresisExceeded(event.event().pos()))
     1421        return true;
     1422   
     1423    // Once we're past the hysteresis point, we don't want to treat this gesture as a click
     1424    invalidateClick();
     1425   
     1426    DragOperation srcOp = DragOperationNone;       
     1427    if (dragState().m_dragSrcMayBeDHTML) {
     1428        freeClipboard();    // would only happen if we missed a dragEnd.  Do it anyway, just
     1429                            // to make sure it gets numbified
     1430       
     1431        dragState().m_dragClipboard = createDraggingClipboard();
     1432       
     1433        // Check to see if the is a DOM based drag, if it is get the DOM specified drag
     1434        // image and offset
     1435        if (dragState().m_dragSrcIsDHTML) {
     1436            int srcX, srcY;
     1437            dragState().m_dragSrc->renderer()->absolutePosition(srcX, srcY);
     1438            IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY);
     1439            dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
     1440        }
     1441       
     1442        m_mouseDownMayStartDrag = dispatchDragSrcEvent(dragstartEvent, m_mouseDown)
     1443            && !m_frame->selectionController()->isInPasswordField();
     1444       
     1445        // Invalidate clipboard here against anymore pasteboard writing for security.  The drag
     1446        // image can still be changed as we drag, but not the pasteboard data.
     1447        dragState().m_dragClipboard->setAccessPolicy(ClipboardImageWritable);
     1448       
     1449        if (m_mouseDownMayStartDrag) {
     1450            // gather values from DHTML element, if it set any
     1451            dragState().m_dragClipboard->sourceOperation(srcOp);
     1452           
     1453            // Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with
     1454            // dragImage!  Because of that dumb reentrancy, we may think we've not started the
     1455            // drag when that happens.  So we have to assume it's started before we kick it off.
     1456            dragState().m_dragClipboard->setDragHasStarted();
     1457        }
     1458    }
     1459   
     1460    if (m_mouseDownMayStartDrag) {
     1461        DragController* dragController = m_frame->page() ? m_frame->page()->dragController() : 0;
     1462        bool startedDrag = dragController && dragController->startDrag(m_frame, dragState().m_dragClipboard.get(), srcOp, event.event(), m_mouseDownPos, dragState().m_dragSrcIsDHTML);
     1463        if (!startedDrag && dragState().m_dragSrcMayBeDHTML) {
     1464            // Drag was canned at the last minute - we owe m_dragSrc a DRAGEND event
     1465            PlatformMouseEvent event(PlatformMouseEvent::currentEvent);
     1466            dispatchDragSrcEvent(dragendEvent, event);
     1467            m_mouseDownMayStartDrag = false;
     1468        }
     1469    }
     1470   
     1471    if (!m_mouseDownMayStartDrag) {
     1472        // something failed to start the drag, cleanup
     1473        freeClipboard();
     1474        dragState().m_dragSrc = 0;
     1475    }
     1476   
     1477    // No more default handling (like selection), whether we're past the hysteresis bounds or not
     1478    return true;
     1479}
     1480 
    13571481bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent,
    1358     bool isLineBreak, bool isBackTab)
     1482                                        bool isLineBreak, bool isBackTab)
    13591483{
    13601484    if (!m_frame)
     
    13741498    return target->dispatchEvent(event.release(), ec, true);
    13751499}
    1376 
     1500   
     1501   
    13771502void EventHandler::defaultTextInputEventHandler(TextEvent* event)
    13781503{
  • trunk/WebCore/page/EventHandler.h

    r19579 r19689  
    171171    };
    172172    static EventHandlerDragState& dragState();
    173 
     173   
     174    Clipboard* createDraggingClipboard() const;
     175   
    174176    bool eventActivatedView(const PlatformMouseEvent&) const;
    175177    void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& event);
     
    244246#else
    245247    bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&) { return false; }
     248    bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&) { return false; }
    246249#endif
    247250
     
    286289    IntPoint m_mouseDownPos; // in our view's coords
    287290    double m_mouseDownTimestamp;
     291    PlatformMouseEvent m_mouseDown;
    288292
    289293#if PLATFORM(MAC)
    290294    NSView *m_mouseDownView;
    291295    bool m_sendingEventToSubview;
    292     PlatformMouseEvent m_mouseDown;
    293296    int m_activationEventNumber;
    294297#endif
  • trunk/WebCore/page/Frame.h

    r19522 r19689  
    3131#include "Color.h"
    3232#include "EditAction.h"
     33#include "DragImage.h"
    3334#include "RenderLayer.h"
    3435#include "TextGranularity.h"
     
    126127    friend class FrameWin;
    127128
     129    DragImageRef dragImageForSelection();
     130   
    128131private:
    129132    FramePrivate* d;
  • trunk/WebCore/page/mac/DragControllerMac.mm

    r19084 r19689  
    3434namespace WebCore {
    3535
     36const int DragController::LinkDragBorderInset = -2;
     37
     38const IntSize DragController::MaxDragImageSize(400, 400);
     39const int DragController::MaxOriginalImageArea = 1500 * 1500;
     40const int DragController::DragIconRightInset = 7;
     41const int DragController::DragIconBottomInset = 3;
     42
     43const float DragController::DragImageAlpha = 0.75f;
     44
    3645bool DragController::isCopyKeyDown()
    3746{
  • trunk/WebCore/page/mac/EventHandlerMac.mm

    r19579 r19689  
    3131#include "Cursor.h"
    3232#include "Document.h"
     33#include "DragController.h"
    3334#include "EventNames.h"
    3435#include "FloatPoint.h"
     
    341342}
    342343   
    343 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
    344 {
    345     BEGIN_BLOCK_OBJC_EXCEPTIONS;
    346     if (event.event().button() != LeftButton || event.event().eventType() != MouseEventMoved) {
    347         // If we allowed the other side of the bridge to handle a drag
    348         // last time, then m_mousePressed might still be set. So we
    349         // clear it now to make sure the next move after a drag
    350         // doesn't look like a drag.
    351         m_mousePressed = false;
    352         return false;
    353     }
    354    
    355     if (eventLoopHandleMouseDragged(event))
    356         return true;
    357    
    358     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
    359    
    360     if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
    361         allowDHTMLDrag(dragState().m_dragSrcMayBeDHTML, dragState().m_dragSrcMayBeUA);
    362         if (!dragState().m_dragSrcMayBeDHTML && !dragState().m_dragSrcMayBeUA)
    363             m_mouseDownMayStartDrag = false;     // no element is draggable
    364     }
    365    
    366     if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
    367         // try to find an element that wants to be dragged
    368         HitTestRequest request(true, false);
    369         HitTestResult result(m_mouseDownPos);
    370         m_frame->renderer()->layer()->hitTest(request, result);
    371         Node* node = result.innerNode();
    372         if (node && node->renderer())
    373             dragState().m_dragSrc = node->renderer()->draggableNode(dragState().m_dragSrcMayBeDHTML, dragState().m_dragSrcMayBeUA,
    374                                                                     m_mouseDownPos.x(), m_mouseDownPos.y(), dragState().m_dragSrcIsDHTML);
    375         else
    376             dragState().m_dragSrc = 0;
    377        
    378         if (!dragState().m_dragSrc)
    379             m_mouseDownMayStartDrag = false;     // no element is draggable
    380         else {
    381             // remember some facts about this source, while we have a HitTestResult handy
    382             node = result.URLElement();
    383             dragState().m_dragSrcIsLink = node && node->isLink();
    384            
    385             node = result.innerNonSharedNode();
    386             dragState().m_dragSrcIsImage = node && node->renderer() && node->renderer()->isImage();
    387            
    388             dragState().m_dragSrcInSelection = m_frame->selectionController()->contains(m_mouseDownPos);
    389         }               
    390     }
    391    
    392     // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
    393     // or else we bail on the dragging stuff and allow selection to occur
    394     if (m_mouseDownMayStartDrag && dragState().m_dragSrcInSelection && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
    395         m_mouseDownMayStartDrag = false;
    396         // ...but if this was the first click in the window, we don't even want to start selection
    397         if (eventActivatedView(event.event()))
    398             m_mouseDownMayStartSelect = false;
    399     }
    400    
    401     if (!m_mouseDownMayStartDrag)
    402         return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
    403    
    404     // We are starting a text/image/url drag, so the cursor should be an arrow
    405     m_frame->view()->setCursor(pointerCursor());
    406    
    407     if (!dragHysteresisExceeded(event.event().pos()))
    408         return true;
    409    
    410     // Once we're past the hysteresis point, we don't want to treat this gesture as a click
    411     invalidateClick();
    412    
    413     NSImage *dragImage = nil;       // we use these values if WC is out of the loop
    414     NSPoint dragLoc = NSZeroPoint;
    415     DragOperation srcOp = DragOperationNone;               
    416     BOOL wcWrotePasteboard = NO;
    417     if (dragState().m_dragSrcMayBeDHTML) {
    418         NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
    419         // Must be done before ondragstart adds types and data to the pboard,
    420         // also done for security, as it erases data from the last drag
    421         [pasteboard declareTypes:[NSArray array] owner:nil];
    422        
    423         freeClipboard();    // would only happen if we missed a dragEnd.  Do it anyway, just
    424         // to make sure it gets numbified
    425         dragState().m_dragClipboard = new ClipboardMac(true, pasteboard, ClipboardWritable, Mac(m_frame));
    426        
    427         // If this is drag of an element, get set up to generate a default image.  Otherwise
    428         // WebKit will generate the default, the element doesn't override.
    429         if (dragState().m_dragSrcIsDHTML) {
    430             int srcX, srcY;
    431             dragState().m_dragSrc->renderer()->absolutePosition(srcX, srcY);
    432             IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY);
    433             dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
    434         }
    435        
    436         m_mouseDownMayStartDrag = dispatchDragSrcEvent(dragstartEvent, m_mouseDown)
    437             && !m_frame->selectionController()->isInPasswordField();
    438        
    439         // Invalidate clipboard here against anymore pasteboard writing for security.  The drag
    440         // image can still be changed as we drag, but not the pasteboard data.
    441         dragState().m_dragClipboard->setAccessPolicy(ClipboardImageWritable);
    442        
    443         if (m_mouseDownMayStartDrag) {
    444             // gather values from DHTML element, if it set any
    445             dragState().m_dragClipboard->sourceOperation(srcOp);
    446            
    447             NSArray *types = [pasteboard types];
    448             wcWrotePasteboard = types && [types count] > 0;
    449            
    450             if (dragState().m_dragSrcMayBeDHTML)
    451                 dragImage = static_cast<ClipboardMac*>(dragState().m_dragClipboard.get())->dragNSImage(dragLoc);
    452            
    453             // Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with
    454             // dragImage!  Because of that dumb reentrancy, we may think we've not started the
    455             // drag when that happens.  So we have to assume it's started before we kick it off.
    456             dragState().m_dragClipboard->setDragHasStarted();
    457         }
    458     }
    459    
    460     if (m_mouseDownMayStartDrag) {
    461         bool startedDrag = [Mac(m_frame)->bridge() startDraggingImage:dragImage at:dragLoc operation:srcOp event:currentEvent sourceIsDHTML:dragState().m_dragSrcIsDHTML DHTMLWroteData:wcWrotePasteboard];
    462         if (!startedDrag && dragState().m_dragSrcMayBeDHTML) {
    463             // WebKit canned the drag at the last minute - we owe m_dragSrc a DRAGEND event
    464             PlatformMouseEvent event(PlatformMouseEvent::currentEvent);
    465             dispatchDragSrcEvent(dragendEvent, event);
    466             m_mouseDownMayStartDrag = false;
    467         }
    468     }
    469    
    470     if (!m_mouseDownMayStartDrag) {
    471         // something failed to start the drag, cleanup
    472         freeClipboard();
    473         dragState().m_dragSrc = 0;
    474     }
    475    
    476     // No more default handling (like selection), whether we're past the hysteresis bounds or not
    477     return true;   
    478    
    479     END_BLOCK_OBJC_EXCEPTIONS;
    480    
    481     return false;
    482    
    483 }
    484 
     344Clipboard* EventHandler::createDraggingClipboard() const
     345{
     346    NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
     347    // Must be done before ondragstart adds types and data to the pboard,
     348    // also done for security, as it erases data from the last drag
     349    [pasteboard declareTypes:[NSArray array] owner:nil];
     350    return new ClipboardMac(true, pasteboard, ClipboardWritable, Mac(m_frame));
     351}
    485352   
    486353bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
  • trunk/WebCore/page/mac/FrameMac.mm

    r19522 r19689  
    983983    [_bridge paintCustomHighlight:type forBox:boxRect onLine:lineRect behindText:text entireLine:line];
    984984}
     985   
     986DragImageRef Frame::dragImageForSelection()
     987{
     988    if (!selectionController()->isRange())
     989        return nil;
     990    return static_cast<FrameMac*>(this)->selectionImage();
     991}
    985992
    986993} // namespace WebCore
  • trunk/WebCore/page/qt/DragControllerQt.cpp

    r19039 r19689  
    3535{
    3636
     37// FIXME: These values are straight out of DragControllerMac, so probably have
     38// little correlation with Qt standards...
     39const int DragController::LinkDragBorderInset = 2;
     40const IntSize DragController::MaxDragImageSize(400, 400);
     41const int DragController::MaxOriginalImageArea = 1500 * 1500;
     42const int DragController::DragIconRightInset = 7;
     43const int DragController::DragIconBottomInset = 3;
     44
     45const float DragController::DragImageAlpha = 0.75f;
     46
     47
    3748bool DragController::isCopyKeyDown()
    3849{
  • trunk/WebCore/page/qt/EventHandlerQt.cpp

    r19465 r19689  
    101101}
    102102
    103 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
    104 {
    105     //notImplemented();
    106     return false;
    107 }
    108 
    109103bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const
    110104{
     
    125119    notImplemented();
    126120    return false;
     121}
     122   
     123Clipboard* EventHandler::createDraggingClipboard() const
     124{
     125    notImplemented();
     126    return 0;
    127127}
    128128
  • trunk/WebCore/page/qt/FrameQt.cpp

    r19297 r19689  
    273273}
    274274
     275DragImageRef Frame::dragImageForSelection()
     276{
     277    return 0;
     278}
     279   
     280
    275281}
    276282// vim: ts=4 sw=4 et
  • trunk/WebCore/platform/Pasteboard.h

    r18960 r19689  
    3737#if PLATFORM(MAC)
    3838class NSPasteboard;
     39class NSArray;
    3940#endif
    4041
     
    6061class Range;
    6162class String;
    62 
     63   
    6364class Pasteboard : Noncopyable {
    6465public:
     66#if PLATFORM(MAC)
     67    //Helper functions to allow Clipboard to share code
     68    static void writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame);
     69    static void writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& url, const String& titleStr, Frame* frame);
     70#endif
     71   
    6572    static Pasteboard* generalPasteboard();
    6673    void writeSelection(Range*, bool canSmartCopyOrDelete, Frame*);
  • trunk/WebCore/platform/graphics/svg/SVGImageEmptyClients.h

    r19650 r19689  
    348348    virtual ~SVGEmptyDragClient() {}
    349349    virtual void willPerformDragDestinationAction(DragDestinationAction, DragData*) { }
     350    virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*) { }
    350351    virtual DragDestinationAction actionMaskForDrag(DragData*) { return DragDestinationActionNone; }
    351352    virtual DragSourceAction dragSourceActionMaskForPoint(const IntPoint&) { return DragSourceActionNone; }
     353    virtual void startDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool) { }
     354    virtual DragImageRef createDragImageForLink(KURL&, const String& label, Frame*) { return 0; }
    352355    virtual void dragControllerDestroyed() { }
    353356};
  • trunk/WebCore/platform/mac/ClipboardMac.h

    r19327 r19689  
    5959    String getData(const String& type, bool& success) const;
    6060    bool setData(const String& type, const String& data);
    61        
     61   
     62    virtual bool hasData();
     63   
    6264    // extensions beyond IE's API
    6365    virtual HashSet<String> types() const;
     
    6870    Node* dragImageElement();
    6971    void setDragImageElement(Node *, const IntPoint&);
    70 
     72   
     73    virtual DragImageRef createDragImage(IntPoint& dragLoc) const;
     74    virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
     75    virtual void writeRange(Range*, Frame* frame);
     76    virtual void writeURL(const KURL&, const String&, Frame* frame);
     77   
    7178    // Methods for getting info in Cocoa's type system
    72     NSImage *dragNSImage(NSPoint&); // loc converted from dragLoc, based on whole image size
    73    
     79    NSImage *dragNSImage(NSPoint&) const; // loc converted from dragLoc, based on whole image size
     80    NSPasteboard *pasteboard() { return m_pasteboard.get(); }
    7481private:
    7582    void setDragImage(CachedImage*, Node*, const IntPoint&);
  • trunk/WebCore/platform/mac/ClipboardMac.mm

    r19327 r19689  
    2828
    2929#import "CachedImage.h"
     30#import "Document.h"
     31#import "DOMElementInternal.h"
     32#import "DragClient.h"
     33#import "DragController.h"
     34#import "Editor.h"
    3035#import "EventHandler.h"
    3136#import "FloatRect.h"
    3237#import "FoundationExtras.h"
    3338#import "FrameMac.h"
     39#import "HTMLImageElement.h"
    3440#import "Image.h"
     41#import "Page.h"
     42#import "Pasteboard.h"
     43#import "Range.h"
     44#import "RenderImage.h"
     45#import "WebCoreFrameBridge.h"
    3546#import "WebCoreSystemInterface.h"
     47
     48@class WebArchive;
    3649
    3750namespace WebCore {
     
    5164}
    5265
     66bool ClipboardMac::hasData()
     67{
     68    return m_pasteboard && [m_pasteboard.get() types] && [[m_pasteboard.get() types] count] > 0;
     69}
     70   
    5371bool ClipboardMac::isForDragging() const
    5472{
     
    318336    }
    319337}
    320 
    321 NSImage *ClipboardMac::dragNSImage(NSPoint& loc)
     338   
     339void ClipboardMac::writeRange(Range* range, Frame* frame)
     340{
     341    ASSERT(range);
     342    ASSERT(frame);
     343    Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selectionGranularity() == WordGranularity, frame);
     344}
     345   
     346void ClipboardMac::writeURL(const KURL& url, const String& title, Frame* frame)
     347{   
     348    ASSERT(frame);
     349    ASSERT(m_pasteboard);
     350    Pasteboard::writeURL(m_pasteboard.get(), nil, url, title, frame);
     351}
     352   
     353void ClipboardMac::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
     354{
     355    ASSERT(frame);
     356    if (Page* page = frame->page())
     357        page->dragController()->client()->declareAndWriteDragImage(m_pasteboard.get(), [DOMElement _elementWith:element], url.getNSURL(), title, frame, Clipboard::canSaveAsWebArchive(frame));
     358}
     359   
     360DragImageRef ClipboardMac::createDragImage(IntPoint& loc) const
     361{
     362    NSPoint nsloc = {loc.x(), loc.y()};
     363    DragImageRef result = dragNSImage(nsloc);
     364    loc = IntPoint(nsloc.x, nsloc.y);
     365    return result;
     366}
     367   
     368NSImage *ClipboardMac::dragNSImage(NSPoint& loc) const
    322369{
    323370    NSImage *result = nil;
  • trunk/WebCore/platform/mac/PasteboardMac.mm

    r18962 r19689  
    115115}
    116116
    117 void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
    118 {
     117void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
     118{
     119    if (WebArchivePboardType == nil)
     120        Pasteboard::generalPasteboard(); //Initialises pasteboard types
     121   
    119122    NSAttributedString *attributedString = [[[NSAttributedString alloc] _initWithDOMRange:[DOMRange _rangeWith:selectedRange]] autorelease];
    120123#ifdef BUILDING_ON_TIGER
     
    131134        types = mutableTypes;
    132135    }
    133     [m_pasteboard declareTypes:types owner:nil];   
     136    [pasteboard declareTypes:types owner:nil];   
    134137#else
    135138    NSArray *types = selectionPasteboardTypes(canSmartCopyOrDelete, [attributedString containsAttachments]);
    136     [m_pasteboard declareTypes:types owner:nil];
     139    [pasteboard declareTypes:types owner:nil];
    137140    frame->editor()->client()->didSetSelectionTypesForPasteboard();
    138141#endif
    139 
     142   
    140143    // Put HTML on the pasteboard.
    141144    if ([types containsObject:WebArchivePboardType]) {
    142         [m_pasteboard setData:frame->editor()->client()->dataForArchivedSelection(frame) forType:WebArchivePboardType];
    143     }
    144 
     145        [pasteboard setData:frame->editor()->client()->dataForArchivedSelection(frame) forType:WebArchivePboardType];
     146    }
     147   
    145148    // Put the attributed string on the pasteboard (RTF/RTFD format).
    146149    if ([types containsObject:NSRTFDPboardType]) {
    147150        NSData *RTFDData = [attributedString RTFDFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil];
    148         [m_pasteboard setData:RTFDData forType:NSRTFDPboardType];
     151        [pasteboard setData:RTFDData forType:NSRTFDPboardType];
    149152    }
    150153    if ([types containsObject:NSRTFPboardType]) {
     
    152155            attributedString = stripAttachmentCharacters(attributedString);
    153156        NSData *RTFData = [attributedString RTFFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:nil];
    154         [m_pasteboard setData:RTFData forType:NSRTFPboardType];
     157        [pasteboard setData:RTFData forType:NSRTFPboardType];
    155158    }
    156159   
     
    165168        NSString *NonBreakingSpaceString = [NSString stringWithCharacters:&noBreakSpace length:1];
    166169        [s replaceOccurrencesOfString:NonBreakingSpaceString withString:@" " options:0 range:NSMakeRange(0, [s length])];
    167         [m_pasteboard setString:s forType:NSStringPboardType];
     170        [pasteboard setString:s forType:NSStringPboardType];
    168171        [s release];
    169172    }
    170173   
    171174    if ([types containsObject:WebSmartPastePboardType]) {
    172         [m_pasteboard setData:nil forType:WebSmartPastePboardType];
    173     }
    174 }
    175 
    176 void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
    177 {
     175        [pasteboard setData:nil forType:WebSmartPastePboardType];
     176    }
     177}
     178   
     179void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
     180{
     181    Pasteboard::writeSelection(m_pasteboard, selectedRange, canSmartCopyOrDelete, frame);
     182}
     183
     184void Pasteboard::writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& url, const String& titleStr, Frame* frame)
     185{
     186    if (WebArchivePboardType == nil)
     187        Pasteboard::generalPasteboard(); //Initialises pasteboard types
     188   
     189    if (types == nil) {
     190        types = writableTypesForURL();
     191        [pasteboard declareTypes:types owner:nil];
     192    }
     193   
    178194    ASSERT(!url.isEmpty());
    179195   
    180196    NSURL *URL = url.getNSURL();
    181197    NSString *userVisibleString = frame->editor()->client()->userVisibleString(URL);
    182 
     198   
    183199    NSString *title = (NSString*)titleStr;
    184200    if ([title length] == 0) {
     
    187203            title = userVisibleString;
    188204    }
    189 
    190     NSArray *types = writableTypesForURL();
    191     [m_pasteboard declareTypes:types owner:nil];
    192 
    193     [m_pasteboard setPropertyList:[NSArray arrayWithObjects:[NSArray arrayWithObject:userVisibleString],
    194                                                             [NSArray arrayWithObject:(NSString*)titleStr.stripWhiteSpace()],
    195                                                             nil]
    196                           forType:WebURLsWithTitlesPboardType];
    197     [URL writeToPasteboard:m_pasteboard];
    198     [m_pasteboard setString:userVisibleString forType:WebURLPboardType];
    199     [m_pasteboard setString:title forType:WebURLNamePboardType];
    200     [m_pasteboard setString:userVisibleString forType:NSStringPboardType];
     205       
     206    if ([types containsObject:WebURLsWithTitlesPboardType])
     207        [pasteboard setPropertyList:[NSArray arrayWithObjects:[NSArray arrayWithObject:userVisibleString],
     208                                     [NSArray arrayWithObject:(NSString*)titleStr.stripWhiteSpace()],
     209                                     nil]
     210                            forType:WebURLsWithTitlesPboardType];
     211    if ([types containsObject:NSURLPboardType])
     212        [URL writeToPasteboard:pasteboard];
     213    if ([types containsObject:WebURLPboardType])
     214        [pasteboard setString:userVisibleString forType:WebURLPboardType];
     215    if ([types containsObject:WebURLNamePboardType])
     216        [pasteboard setString:title forType:WebURLNamePboardType];
     217    if ([types containsObject:NSStringPboardType])
     218        [pasteboard setString:userVisibleString forType:NSStringPboardType];
     219}
     220   
     221void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
     222{
     223    Pasteboard::writeURL(m_pasteboard, nil, url, titleStr, frame);
    201224}
    202225
  • trunk/WebKit/ChangeLog

    r19670 r19689  
     12007-02-18  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Adam.
     4
     5        Moving the drag initiation logic to WebCore.
     6        The redundant code in webkit will be moved out in a later patch.
     7
     8        * WebCoreSupport/WebDragClient.h:
     9        * WebCoreSupport/WebDragClient.mm:
     10        (getTopHTMLView):
     11          Helper function
     12        (WebDragClient::willPerformDragSourceAction):
     13        (WebDragClient::startDrag):
     14        (WebDragClient::createDragImageForLink):
     15          Implemented new DragClient methods
     16        (WebDragClient::declareAndWriteDragImage):
     17          Helper function for the Mac to allow new drag and drop
     18          code to match behaviour
     19         
     20        * WebView/WebHTMLView.mm:
     21        (-[WebHTMLView _dragImageForURL:withLabel:]):
     22        (-[WebHTMLView _dragImageForLinkElement:]):
     23          Refactoring old _dragImageForLinkElement function so that
     24          the link drag image can be created with just a URL and label,
     25          rather than requiring the original element
     26        (-[WebHTMLView dragImage:at:offset:event:pasteboard:source:slideBack:]):
     27          Removed logic that is no longer necessary                 
     28        (-[WebHTMLView _mouseDownEvent]):
     29          The WebDragClient may need the original mouseDownEvent of a drag when initiating
     30          a drag
     31        * WebView/WebHTMLViewInternal.h:
     32          Declaring _mouseDownEvent
     33
     34        * WebView/WebHTMLViewPrivate.h:
     35          Declaring _dragImageForURL
     36
    1372007-02-16  John Sullivan  <sullivan@apple.com>
    238
  • trunk/WebKit/WebCoreSupport/WebDragClient.h

    r19230 r19689  
    3232    WebDragClient(WebView*);
    3333    virtual void willPerformDragDestinationAction(WebCore::DragDestinationAction, WebCore::DragData*);
     34    virtual void willPerformDragSourceAction(WebCore::DragSourceAction, const WebCore::IntPoint&, WebCore::Clipboard*);
    3435    virtual WebCore::DragDestinationAction actionMaskForDrag(WebCore::DragData*);
    3536    virtual void dragControllerDestroyed();
    3637    virtual WebCore::DragSourceAction dragSourceActionMaskForPoint(const WebCore::IntPoint& windowPoint);
     38    virtual void startDrag(WebCore::DragImageRef dragImage, const WebCore::IntPoint& dragPos, const WebCore::IntPoint& eventPos, WebCore::Clipboard*, WebCore::Frame*, bool linkDrag);
     39    virtual WebCore::DragImageRef createDragImageForLink(WebCore::KURL& url, const WebCore::String& label, WebCore::Frame*);
     40    virtual void declareAndWriteDragImage(NSPasteboard*, DOMElement*, NSURL*, NSString*, WebCore::Frame*, bool canSaveAsWebArchive);
    3741private:
    3842    WebView* m_webView;
  • trunk/WebKit/WebCoreSupport/WebDragClient.mm

    r19230 r19689  
    2626#import "WebDragClient.h"
    2727
     28#import "WebArchive.h"
     29#import "WebArchiver.h"
     30#import "WebDOMOperations.h"
    2831#import "WebFrame.h"
     32#import "WebFrameInternal.h"
     33#import "WebHTMLViewInternal.h"
     34#import "WebHTMLViewPrivate.h"
     35#import "WebNSPasteboardExtras.h"
     36#import "WebNSURLExtras.h"
    2937#import "WebUIDelegate.h"
     38#import "WebUIDelegatePrivate.h"
    3039#import "WebViewInternal.h"
     40#import <WebCore/ClipboardMac.h>
    3141#import <WebCore/DragData.h>
     42#import <WebCore/EventHandler.h>
     43#import <WebCore/FrameMac.h>
     44#import <WebCore/FrameView.h>
     45#import <WebCore/Image.h>
     46#import <WebCore/Page.h>
     47
     48using namespace WebCore;
    3249
    3350WebDragClient::WebDragClient(WebView* webView)
    3451    : m_webView(webView)
    3552{
     53}
     54
     55static WebHTMLView *getTopHTMLView(Frame* frame)
     56{
     57    ASSERT(frame);
     58    ASSERT(frame->page());
     59    return (WebHTMLView*)[[kit(frame->page()->mainFrame()) frameView] documentView];
    3660}
    3761
     
    4771
    4872
    49 WebCore::DragSourceAction WebDragClient::dragSourceActionMaskForPoint(const WebCore::IntPoint& windowPoint)
     73WebCore::DragSourceAction WebDragClient::dragSourceActionMaskForPoint(const IntPoint& windowPoint)
    5074{
    5175    NSPoint viewPoint = [m_webView convertPoint:windowPoint fromView:nil];
    52     return (WebCore::DragSourceAction)[[m_webView _UIDelegateForwarder] webView:m_webView dragSourceActionMaskForPoint:viewPoint];
     76    return (DragSourceAction)[[m_webView _UIDelegateForwarder] webView:m_webView dragSourceActionMaskForPoint:viewPoint];
     77}
     78
     79void WebDragClient::willPerformDragSourceAction(WebCore::DragSourceAction action, const WebCore::IntPoint& mouseDownPoint, WebCore::Clipboard* clipboard)
     80{
     81    ASSERT(clipboard);
     82    [[m_webView _UIDelegateForwarder] webView:m_webView willPerformDragSourceAction:(WebDragSourceAction)action fromPoint:mouseDownPoint withPasteboard:static_cast<WebCore::ClipboardMac*>(clipboard)->pasteboard()];
     83}
     84
     85void WebDragClient::startDrag(DragImageRef dragImage, const IntPoint& at, const IntPoint& eventPos, Clipboard* clipboard, Frame* frame, bool linkDrag)
     86{
     87    if (!frame)
     88        return;
     89    ASSERT(clipboard);
     90    RetainPtr<WebHTMLView> htmlView = (WebHTMLView*)[[kit(frame) frameView] documentView];
     91    if (![htmlView.get() isKindOfClass:[WebHTMLView class]])
     92        return;
     93   
     94    NSEvent *event = linkDrag ? frame->eventHandler()->currentNSEvent() : [htmlView.get() _mouseDownEvent];
     95    WebHTMLView* topHTMLView = getTopHTMLView(frame);
     96    RetainPtr<WebHTMLView> topViewProtector = topHTMLView;
     97   
     98    [topHTMLView _stopAutoscrollTimer];
     99    NSPasteboard *pasteboard = static_cast<ClipboardMac*>(clipboard)->pasteboard();
     100   
     101    // note per kwebster, the offset arg below is always ignored in positioning the image
     102    id UIDelegate = [m_webView UIDelegate];
     103    if ([UIDelegate respondsToSelector:@selector(webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:)])
     104        [UIDelegate webView:m_webView dragImage:dragImage.get() at:(NSPoint)at offset:NSMakeSize(0, 0) event:event pasteboard:pasteboard source:htmlView.get() slideBack:YES forView:topHTMLView];
     105    else
     106        [topHTMLView dragImage:dragImage.get() at:(NSPoint)at offset:NSMakeSize(0, 0) event:event pasteboard:pasteboard source:htmlView.get() slideBack:YES];
     107}
     108
     109DragImageRef WebDragClient::createDragImageForLink(KURL& url, const String& title, Frame* frame)
     110{
     111    if (!frame)
     112        return nil;
     113    WebHTMLView* htmlView = (WebHTMLView*)[[kit(frame) frameView] documentView];
     114    NSString *label = 0;
     115    if (!title.isEmpty())
     116        label = (NSString*)title;
     117    return [htmlView _dragImageForURL:[url.getNSURL() _web_userVisibleString] withLabel:label];
     118}
     119
     120
     121void WebDragClient::declareAndWriteDragImage(NSPasteboard* pasteboard, DOMElement* element, NSURL* URL, NSString* title, WebCore::Frame* frame, bool canSaveAsWebArchive)
     122{
     123    ASSERT(pasteboard);
     124    ASSERT(element);
     125    id source = (WebHTMLView*)[[kit(frame) frameView] documentView];       
     126   
     127    WebArchive *archive;
     128   
     129    // If the image element comes from an ImageDocument, we don't want to
     130    // create a web archive from the image element.
     131    if (canSaveAsWebArchive)
     132        archive = [element webArchive];
     133    else
     134        archive = [WebArchiver archiveMainResourceForFrame:kit(frame)];
     135    ASSERT(archive);
     136    [pasteboard _web_declareAndWriteDragImageForElement:element URL:URL title:title archive:archive source:source];
    53137}
    54138
  • trunk/WebKit/WebView/WebHTMLView.mm

    r19614 r19689  
    175175
    176176#define DRAG_LABEL_BORDER_X             4.0f
     177//Keep border_y in synch with DragController::LinkDragBorderInset
    177178#define DRAG_LABEL_BORDER_Y             2.0f
    178179#define DRAG_LABEL_RADIUS               5.0f
     
    12561257}
    12571258
    1258 - (NSImage *)_dragImageForLinkElement:(NSDictionary *)element
    1259 {
    1260     NSURL *linkURL = [element objectForKey: WebElementLinkURLKey];
    1261 
     1259- (NSImage *)_dragImageForURL:(NSString*)urlString withLabel:(NSString*)label
     1260{
    12621261    BOOL drawURLString = YES;
    12631262    BOOL clipURLString = NO, clipLabelString = NO;
    1264    
    1265     NSString *label = [element objectForKey: WebElementLinkLabelKey];
    1266     NSString *urlString = [linkURL _web_userVisibleString];
    12671263   
    12681264    if (!label) {
     
    12721268   
    12731269    NSFont *labelFont = [[NSFontManager sharedFontManager] convertFont:[NSFont systemFontOfSize:DRAG_LINK_LABEL_FONT_SIZE]
    1274                                                    toHaveTrait:NSBoldFontMask];
     1270                                                           toHaveTrait:NSBoldFontMask];
    12751271    NSFont *urlFont = [NSFont systemFontOfSize: DRAG_LINK_URL_FONT_SIZE];
    12761272    NSSize labelSize;
     
    13121308    [path appendBezierPathWithRect: NSMakeRect(imageSize.width - DRAG_LABEL_RADIUS - 20.0f, DRAG_LABEL_RADIUS, DRAG_LABEL_RADIUS + 20.0f, imageSize.height - 2.0f * DRAG_LABEL_RADIUS)];
    13131309    [path fill];
    1314        
     1310   
    13151311    NSColor *topColor = [NSColor colorWithCalibratedWhite:0.0f alpha:0.75f];
    13161312    NSColor *bottomColor = [NSColor colorWithCalibratedWhite:1.0f alpha:0.5f];
     
    13181314        if (clipURLString)
    13191315            urlString = [WebStringTruncator centerTruncateString: urlString toWidth:imageSize.width - (DRAG_LABEL_BORDER_X * 2.0f) withFont:urlFont];
    1320 
     1316       
    13211317        [urlString _web_drawDoubledAtPoint:NSMakePoint(DRAG_LABEL_BORDER_X, DRAG_LABEL_BORDER_Y - [urlFont descender])
    1322              withTopColor:topColor bottomColor:bottomColor font:urlFont];
    1323     }
    1324 
     1318                              withTopColor:topColor bottomColor:bottomColor font:urlFont];
     1319    }
     1320   
    13251321    if (clipLabelString)
    13261322        label = [WebStringTruncator rightTruncateString: label toWidth:imageSize.width - (DRAG_LABEL_BORDER_X * 2.0f) withFont:labelFont];
    13271323    [label _web_drawDoubledAtPoint:NSMakePoint (DRAG_LABEL_BORDER_X, imageSize.height - DRAG_LABEL_BORDER_Y_OFFSET - [labelFont pointSize])
    1328              withTopColor:topColor bottomColor:bottomColor font:labelFont];
     1324                      withTopColor:topColor bottomColor:bottomColor font:labelFont];
    13291325   
    13301326    [dragImage unlockFocus];
    13311327   
    13321328    return dragImage;
     1329}
     1330
     1331- (NSImage *)_dragImageForLinkElement:(NSDictionary *)element
     1332{
     1333    NSURL *linkURL = [element objectForKey: WebElementLinkURLKey];
     1334   
     1335    NSString *label = [element objectForKey: WebElementLinkLabelKey];
     1336    NSString *urlString = [linkURL _web_userVisibleString];
     1337    return [self _dragImageForURL:urlString withLabel:label];
    13331338}
    13341339
     
    28842889        slideBack:(BOOL)slideBack
    28852890{
    2886     [self _stopAutoscrollTimer];
    2887 
    2888     WebHTMLView *topHTMLView = [self _topHTMLView];
    2889     if (self != topHTMLView) {
    2890         [topHTMLView dragImage:dragImage at:[self convertPoint:at toView:topHTMLView]
    2891             offset:offset event:event pasteboard:pasteboard source:source slideBack:slideBack];
    2892         return;
    2893     }
    2894 
    2895     WebView *webView = [self _webView];
    2896     Page *page = core(webView);
    2897     ASSERT(page);
    2898     page->dragController()->setDidInitiateDrag(true);
    2899    
    2900     // Retain this view during the drag because it may be released before the drag ends.
    2901     [self retain];
    2902 
    2903     id UIDelegate = [webView UIDelegate];
    2904     // If a delegate takes over the drag but never calls draggedImage: endedAt:, we'll leak the WebHTMLView.
    2905     if ([UIDelegate respondsToSelector:@selector(webView:dragImage:at:offset:event:pasteboard:source:slideBack:forView:)])
    2906         [UIDelegate webView:webView dragImage:dragImage at:at offset:offset event:event pasteboard:pasteboard source:source slideBack:slideBack forView:self];
    2907     else
    2908         [super dragImage:dragImage at:at offset:offset event:event pasteboard:pasteboard source:source slideBack:slideBack];
     2891    ASSERT(self == [self _topHTMLView]);
     2892    [super dragImage:dragImage at:at offset:offset event:event pasteboard:pasteboard source:source slideBack:slideBack];
    29092893}
    29102894
     
    29822966                                         eventNumber:0 clickCount:0 pressure:0];
    29832967    [self mouseUp:fakeEvent]; // This will also update the mouseover state.
    2984    
    2985     // Balance the previous retain from when the drag started.
    2986     [self release];
    29872968}
    29882969
     
    49374918{
    49384919    return textView == _private->firstResponderTextViewAtMouseDownTime;
     4920}
     4921
     4922
     4923- (NSEvent *)_mouseDownEvent
     4924{
     4925    return _private->mouseDownEvent;
    49394926}
    49404927
  • trunk/WebKit/WebView/WebHTMLViewInternal.h

    r19579 r19689  
    113113- (BOOL)_interceptEditingKeyEvent:(WebCore::KeyboardEvent *)event;
    114114- (DOMDocumentFragment*)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard;
     115- (NSEvent *)_mouseDownEvent;
    115116#ifndef BUILDING_ON_TIGER
    116117- (BOOL)isGrammarCheckingEnabled;
  • trunk/WebKit/WebView/WebHTMLViewPrivate.h

    r19327 r19689  
    7070
    7171- (NSImage *)_dragImageForLinkElement:(NSDictionary *)element;
     72- (NSImage *)_dragImageForURL:(NSString*)linkURL withLabel:(NSString*)label;
    7273- (BOOL)_startDraggingImage:(NSImage *)dragImage at:(NSPoint)dragLoc operation:(NSDragOperation)op event:(NSEvent *)event sourceIsDHTML:(BOOL)flag DHTMLWroteData:(BOOL)dhtmlWroteData;
    7374- (void)_handleAutoscrollForMouseDragged:(NSEvent *)event;
Note: See TracChangeset for help on using the changeset viewer.