Changeset 150772 in webkit


Ignore:
Timestamp:
May 27, 2013 12:51:49 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Move Windows port off legacy clipboard.
https://bugs.webkit.org/show_bug.cgi?id=116258

Patch by Xueqing Huang <huangxueqing@baidu.com> on 2013-05-27
Reviewed by Darin Adler.

Source/WebCore:

Clipboard refactor, no new tests.

  • dom/Clipboard.h:
  • page/win/EventHandlerWin.cpp:

(WebCore::EventHandler::createDraggingClipboard): Create Clipboard instead of ClipboardWin.

  • platform/Pasteboard.h:

(WebCore::Pasteboard::dataObject): Get IDataObject by Clipborad.
(WebCore::Pasteboard::writableDataObject): Get WCDataObject by Clipborad.

  • platform/win/ClipboardWin.cpp:

(WebCore::Clipboard::createDragImage): Change parameter name loc to dragLocation.
(WebCore::Clipboard::declareAndWriteDragImage): Implement declareAndWriteDragImage use WCDataObject exposed by Pasteboard.

  • platform/win/ClipboardWin.h: Removed.
  • platform/win/EditorWin.cpp:

(WebCore::Editor::newGeneralClipboard): Create Clipboard instead of ClipboardWin.

  • platform/win/PasteboardWin.cpp:

(WebCore::Pasteboard::createForCopyAndPaste): Create a Pasteboard.
(WebCore::Pasteboard::createPrivate): Ditto.
(WebCore::Pasteboard::createForDragAndDrop): Ditto.
(WebCore::Pasteboard::finishCreatingPasteboard): Create Pasteboard use Windows API.
(WebCore::Pasteboard::Pasteboard):
(WebCore::clipboardTypeFromMIMEType): Copied from ClipboardWin.cpp.
(WebCore::Pasteboard::clear): Ditto.
(WebCore::Pasteboard::hasData): Ditto.
(WebCore::addMimeTypesForFormat): Ditto.
(WebCore::Pasteboard::types): Ditto.
(WebCore::Pasteboard::readString): Ditto.
(WebCore::Pasteboard::readFilenames): Ditto.
(WebCore::writeURL): Ditto.
(WebCore::Pasteboard::writeString): Ditto.
(WebCore::Pasteboard::setDragImage): Ditto.
(WebCore::Pasteboard::writeRangeToDataObject): Write range to WCDataObject.
(WebCore::Pasteboard::writeSelection):
(WebCore::Pasteboard::writePlainTextToDataObject): Write PlainText to WCDataObject.
(WebCore::Pasteboard::writePlainText):
(WebCore::pathRemoveBadFSCharacters): Copied from ClipboardWin.cpp.
(WebCore::filesystemPathFromUrlOrTitle): Ditto.
(WebCore::writeFileToDataObject): Ditto.
(WebCore::Pasteboard::writeURLToDataObject): Write URL to WCDataObject.
(WebCore::Pasteboard::writeURL): Copied from ClipboardWin.cpp.
(WebCore::Pasteboard::writePasteboard): Copied from Pasteboard::writeClipboard.
(WebCore::Pasteboard::documentFragment): Copied from ClipboardWin.cpp.
(WebCore::Pasteboard::setExternalDataObject): Clipboard can set new IDataObject.
(WebCore::getCachedImage): Copied from ClipboardWin.cpp.
(WebCore::createGlobalImageFileDescriptor): Ditto.
(WebCore::createGlobalImageFileContent): Ditto.
(WebCore::createGlobalHDropContent): Ditto.
(WebCore::Pasteboard::writeImageToDataObject): Expose to make Clipboard implement declareAndWriteDragImage.
(WebCore::Pasteboard::writeURLToWritableDataObject): Ditto.

Source/WebKit/win:

  • WebCoreSupport/WebDragClient.cpp:

(WebDragClient::willPerformDragSourceAction): Get IDataObject from Pasteboard instead of Clipboard.
(WebDragClient::startDrag): Ditto.

Location:
trunk/Source
Files:
1 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r150771 r150772  
     12013-05-27  Xueqing Huang  <huangxueqing@baidu.com>
     2
     3        Move Windows port off legacy clipboard.
     4        https://bugs.webkit.org/show_bug.cgi?id=116258
     5
     6        Reviewed by Darin Adler.
     7
     8        Clipboard refactor, no new tests.
     9
     10        * dom/Clipboard.h:
     11        * page/win/EventHandlerWin.cpp:
     12        (WebCore::EventHandler::createDraggingClipboard): Create Clipboard instead of ClipboardWin.
     13        * platform/Pasteboard.h:
     14        (WebCore::Pasteboard::dataObject): Get IDataObject by Clipborad.
     15        (WebCore::Pasteboard::writableDataObject): Get WCDataObject by Clipborad.
     16        * platform/win/ClipboardWin.cpp:
     17        (WebCore::Clipboard::createDragImage): Change parameter name loc to dragLocation.
     18        (WebCore::Clipboard::declareAndWriteDragImage): Implement declareAndWriteDragImage use WCDataObject exposed by Pasteboard.
     19        * platform/win/ClipboardWin.h: Removed.
     20        * platform/win/EditorWin.cpp:
     21        (WebCore::Editor::newGeneralClipboard): Create Clipboard instead of ClipboardWin.
     22        * platform/win/PasteboardWin.cpp:
     23        (WebCore::Pasteboard::createForCopyAndPaste): Create a Pasteboard.
     24        (WebCore::Pasteboard::createPrivate): Ditto.
     25        (WebCore::Pasteboard::createForDragAndDrop): Ditto.
     26        (WebCore::Pasteboard::finishCreatingPasteboard): Create Pasteboard use Windows API.
     27        (WebCore::Pasteboard::Pasteboard):
     28        (WebCore::clipboardTypeFromMIMEType): Copied from ClipboardWin.cpp.
     29        (WebCore::Pasteboard::clear): Ditto.
     30        (WebCore::Pasteboard::hasData): Ditto.
     31        (WebCore::addMimeTypesForFormat): Ditto.
     32        (WebCore::Pasteboard::types): Ditto.
     33        (WebCore::Pasteboard::readString): Ditto.
     34        (WebCore::Pasteboard::readFilenames): Ditto.
     35        (WebCore::writeURL): Ditto.
     36        (WebCore::Pasteboard::writeString): Ditto.
     37        (WebCore::Pasteboard::setDragImage): Ditto.
     38        (WebCore::Pasteboard::writeRangeToDataObject): Write range to WCDataObject.
     39        (WebCore::Pasteboard::writeSelection):
     40        (WebCore::Pasteboard::writePlainTextToDataObject): Write PlainText to WCDataObject.
     41        (WebCore::Pasteboard::writePlainText):
     42        (WebCore::pathRemoveBadFSCharacters): Copied from ClipboardWin.cpp.
     43        (WebCore::filesystemPathFromUrlOrTitle): Ditto.
     44        (WebCore::writeFileToDataObject): Ditto.
     45        (WebCore::Pasteboard::writeURLToDataObject): Write URL to WCDataObject.
     46        (WebCore::Pasteboard::writeURL): Copied from ClipboardWin.cpp.
     47        (WebCore::Pasteboard::writePasteboard): Copied from Pasteboard::writeClipboard.
     48        (WebCore::Pasteboard::documentFragment): Copied from ClipboardWin.cpp.
     49        (WebCore::Pasteboard::setExternalDataObject): Clipboard can set new IDataObject.
     50        (WebCore::getCachedImage): Copied from ClipboardWin.cpp.
     51        (WebCore::createGlobalImageFileDescriptor): Ditto.
     52        (WebCore::createGlobalImageFileContent): Ditto.
     53        (WebCore::createGlobalHDropContent): Ditto.
     54        (WebCore::Pasteboard::writeImageToDataObject): Expose to make Clipboard implement declareAndWriteDragImage.
     55        (WebCore::Pasteboard::writeURLToWritableDataObject): Ditto.
     56
    1572013-05-27  Tim Horton  <timothy_horton@apple.com>
    258
  • trunk/Source/WebCore/dom/Clipboard.h

    r150373 r150772  
    3535// Specifically, the class currently named Pasteboard. The legacy style instead
    3636// uses this as an abstract base class.
    37 #define WTF_USE_LEGACY_STYLE_ABSTRACT_CLIPBOARD_CLASS (PLATFORM(IOS) || PLATFORM(QT) || PLATFORM(WIN))
     37#define WTF_USE_LEGACY_STYLE_ABSTRACT_CLIPBOARD_CLASS (PLATFORM(IOS) || PLATFORM(QT))
    3838
    3939#if USE(LEGACY_STYLE_ABSTRACT_CLIPBOARD_CLASS)
  • trunk/Source/WebCore/page/win/EventHandlerWin.cpp

    r145913 r150772  
    2828#include "EventHandler.h"
    2929
     30#include "COMPtr.h"
     31#include "Clipboard.h"
    3032#include "Cursor.h"
    3133#include "FloatPoint.h"
     
    4345#include "WCDataObject.h"
    4446#include "NotImplemented.h"
    45 
    46 #if OS(WINCE)
    47 #include "Clipboard.h"
    48 #else
    49 #include "ClipboardWin.h"
    50 #endif
    5147
    5248namespace WebCore {
     
    10298    return 0;
    10399#else
    104     COMPtr<WCDataObject> dataObject;
    105     WCDataObject::createInstance(&dataObject);
    106     return ClipboardWin::create(Clipboard::DragAndDrop, dataObject.get(), ClipboardWritable, m_frame);
     100    return Clipboard::createForDragAndDrop();
    107101#endif
    108102}
  • trunk/Source/WebCore/platform/Pasteboard.h

    r150334 r150772  
    3939
    4040#if PLATFORM(WIN)
     41#include "COMPtr.h"
     42#include "WCDataObject.h"
     43#include <objidl.h>
    4144#include <windows.h>
    4245typedef struct HWND__* HWND;
     
    6568class DocumentFragment;
    6669class DragData;
     70class Element;
    6771class Frame;
    6872class HitTestResult;
     
    154158#endif
    155159
     160#if PLATFORM(WIN)
     161    COMPtr<IDataObject> dataObject() const { return m_dataObject; }
     162    void setExternalDataObject(IDataObject*);
     163    void writeURLToWritableDataObject(const KURL&, const String&);
     164    COMPtr<WCDataObject> writableDataObject() const { return m_writableDataObject; }
     165    void writeImageToDataObject(Element*, const KURL&);
     166#endif
     167
    156168#if PLATFORM(GTK)
    157169    ~Pasteboard();
     
    164176    Pasteboard(PassRefPtr<DataObjectGtk>);
    165177    Pasteboard(GtkClipboard*);
     178#endif
     179
     180#if PLATFORM(WIN)
     181    explicit Pasteboard(IDataObject*);
     182    explicit Pasteboard(WCDataObject*);
     183    explicit Pasteboard(const DragDataMap&);
    166184#endif
    167185
     
    176194
    177195#if PLATFORM(WIN)
     196    void finishCreatingPasteboard();
     197    void writeRangeToDataObject(Range*, Frame*);
     198    void writeURLToDataObject(const KURL&, const String&, Frame*);
     199    void writePlainTextToDataObject(const String&, SmartReplaceOption);
     200
    178201    HWND m_owner;
     202    COMPtr<IDataObject> m_dataObject;
     203    COMPtr<WCDataObject> m_writableDataObject;
     204    DragDataMap m_dragDataMap;
    179205#endif
    180206
  • trunk/Source/WebCore/platform/win/ClipboardWin.cpp

    r150373 r150772  
    11/*
    22 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
     3 * Copyright (C) 2013 Xueqing Huang <huangxueqing@baidu.com>
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2526
    2627#include "config.h"
    27 #include "ClipboardWin.h"
     28#include "Clipboard.h"
    2829
    2930#include "CachedImage.h"
    3031#include "ClipboardUtilitiesWin.h"
    3132#include "Document.h"
    32 #include "DragData.h"
    33 #include "Editor.h"
    3433#include "Element.h"
    35 #include "EventHandler.h"
    36 #include "FileList.h"
    3734#include "Frame.h"
    38 #include "FrameLoader.h"
    39 #include "FrameView.h"
    4035#include "HTMLNames.h"
    4136#include "HTMLParserIdioms.h"
    42 #include "Image.h"
    43 #include "MIMETypeRegistry.h"
    44 #include "NotImplemented.h"
    45 #include "Page.h"
    4637#include "Pasteboard.h"
    47 #include "PlatformMouseEvent.h"
    48 #include "Range.h"
    49 #include "RenderImage.h"
    50 #include "ResourceResponse.h"
    51 #include "SharedBuffer.h"
    52 #include "WCDataObject.h"
    5338#include "markup.h"
    54 #include <shlwapi.h>
    55 #include <wininet.h>
    56 #include <wtf/RefPtr.h>
    57 #include <wtf/text/CString.h>
    58 #include <wtf/text/WTFString.h>
    59 #include <wtf/text/StringHash.h>
    60 
    61 using namespace std;
    6239
    6340namespace WebCore {
    6441
    65 using namespace HTMLNames;
    66 
    67 // We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
    68 // see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
    69 
    70 enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardDataTypeText, ClipboardDataTypeTextHTML };
    71 
    72 static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
    73 {
    74     String qType = type.stripWhiteSpace().lower();
    75 
    76     // two special cases for IE compatibility
    77     if (qType == "text" || qType == "text/plain" || qType.startsWith("text/plain;"))
    78         return ClipboardDataTypeText;
    79     if (qType == "url" || qType == "text/uri-list")
    80         return ClipboardDataTypeURL;
    81     if (qType == "text/html")
    82         return ClipboardDataTypeTextHTML;
    83 
    84     return ClipboardDataTypeNone;
    85 }
    86 
    87 #if !OS(WINCE)
    88 static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length)
    89 {
    90     size_t writeTo = 0;
    91     size_t readFrom = 0;
    92     while (readFrom < length) {
    93         UINT type = PathGetCharType(psz[readFrom]);
    94         if (!psz[readFrom] || type & (GCT_LFNCHAR | GCT_SHORTCHAR))
    95             psz[writeTo++] = psz[readFrom];
    96 
    97         readFrom++;
    98     }
    99     psz[writeTo] = 0;
    100 }
    101 #endif
    102 
    103 static String filesystemPathFromUrlOrTitle(const String& url, const String& title, const UChar* extension, bool isLink)
    104 {
    105 #if OS(WINCE)
    106     notImplemented();
    107     return String();
    108 #else
    109     static const size_t fsPathMaxLengthExcludingNullTerminator = MAX_PATH - 1;
    110     bool usedURL = false;
    111     WCHAR fsPathBuffer[MAX_PATH];
    112     fsPathBuffer[0] = 0;
    113     int extensionLen = extension ? lstrlen(extension) : 0;
    114     int fsPathMaxLengthExcludingExtension = fsPathMaxLengthExcludingNullTerminator - extensionLen;
    115 
    116     if (!title.isEmpty()) {
    117         size_t len = min<size_t>(title.length(), fsPathMaxLengthExcludingExtension);
    118         CopyMemory(fsPathBuffer, title.characters(), len * sizeof(UChar));
    119         fsPathBuffer[len] = 0;
    120         pathRemoveBadFSCharacters(fsPathBuffer, len);
    121     }
    122 
    123     if (!lstrlen(fsPathBuffer)) {
    124         KURL kurl(ParsedURLString, url);
    125         usedURL = true;
    126         // The filename for any content based drag or file url should be the last element of
    127         // the path.  If we can't find it, or we're coming up with the name for a link
    128         // we just use the entire url.
    129         DWORD len = fsPathMaxLengthExcludingExtension;
    130         String lastComponent = kurl.lastPathComponent();
    131         if (kurl.isLocalFile() || (!isLink && !lastComponent.isEmpty())) {
    132             len = min<DWORD>(fsPathMaxLengthExcludingExtension, lastComponent.length());
    133             CopyMemory(fsPathBuffer, lastComponent.characters(), len * sizeof(UChar));
    134         } else {
    135             len = min<DWORD>(fsPathMaxLengthExcludingExtension, url.length());
    136             CopyMemory(fsPathBuffer, url.characters(), len * sizeof(UChar));
    137         }
    138         fsPathBuffer[len] = 0;
    139         pathRemoveBadFSCharacters(fsPathBuffer, len);
    140     }
    141 
    142     if (!extension)
    143         return String(static_cast<UChar*>(fsPathBuffer));
    144 
    145     if (!isLink && usedURL) {
    146         PathRenameExtension(fsPathBuffer, extension);
    147         return String(static_cast<UChar*>(fsPathBuffer));
    148     }
    149 
    150     return makeString(static_cast<const UChar*>(fsPathBuffer), extension);
    151 #endif
    152 }
    153 
    154 static HGLOBAL createGlobalImageFileContent(SharedBuffer* data)
    155 {
    156     HGLOBAL memObj = GlobalAlloc(GPTR, data->size());
    157     if (!memObj)
    158         return 0;
    159 
    160     char* fileContents = (PSTR)GlobalLock(memObj);
    161 
    162     CopyMemory(fileContents, data->data(), data->size());
    163    
    164     GlobalUnlock(memObj);
    165    
    166     return memObj;
    167 }
    168 
    169 static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, SharedBuffer* data)
    170 {
    171     if (fileName.isEmpty() || !data)
    172         return 0;
    173 
    174     WCHAR filePath[MAX_PATH];
    175 
    176     if (url.isLocalFile()) {
    177         String localPath = decodeURLEscapeSequences(url.path());
    178         // windows does not enjoy a leading slash on paths
    179         if (localPath[0] == '/')
    180             localPath = localPath.substring(1);
    181         LPCWSTR localPathStr = localPath.charactersWithNullTermination();
    182         if (wcslen(localPathStr) + 1 < MAX_PATH)
    183             wcscpy_s(filePath, MAX_PATH, localPathStr);
    184         else
    185             return 0;
    186     } else {
    187 #if OS(WINCE)
    188         notImplemented();
    189         return 0;
    190 #else
    191         WCHAR tempPath[MAX_PATH];
    192         WCHAR extension[MAX_PATH];
    193         if (!::GetTempPath(WTF_ARRAY_LENGTH(tempPath), tempPath))
    194             return 0;
    195         if (!::PathAppend(tempPath, fileName.charactersWithNullTermination()))
    196             return 0;
    197         LPCWSTR foundExtension = ::PathFindExtension(tempPath);
    198         if (foundExtension) {
    199             if (wcscpy_s(extension, MAX_PATH, foundExtension))
    200                 return 0;
    201         } else
    202             *extension = 0;
    203         ::PathRemoveExtension(tempPath);
    204         for (int i = 1; i < 10000; i++) {
    205             if (swprintf_s(filePath, MAX_PATH, TEXT("%s-%d%s"), tempPath, i, extension) == -1)
    206                 return 0;
    207             if (!::PathFileExists(filePath))
    208                 break;
    209         }
    210         HANDLE tempFileHandle = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    211         if (tempFileHandle == INVALID_HANDLE_VALUE)
    212             return 0;
    213 
    214         // Write the data to this temp file.
    215         DWORD written;
    216         BOOL tempWriteSucceeded = WriteFile(tempFileHandle, data->data(), data->size(), &written, 0);
    217         CloseHandle(tempFileHandle);
    218         if (!tempWriteSucceeded)
    219             return 0;
    220 #endif
    221     }
    222 
    223     SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * (wcslen(filePath) + 2));
    224     HGLOBAL memObj = GlobalAlloc(GHND | GMEM_SHARE, dropFilesSize);
    225     if (!memObj)
    226         return 0;
    227 
    228     DROPFILES* dropFiles = (DROPFILES*) GlobalLock(memObj);
    229     dropFiles->pFiles = sizeof(DROPFILES);
    230     dropFiles->fWide = TRUE;
    231     wcscpy((LPWSTR)(dropFiles + 1), filePath);   
    232     GlobalUnlock(memObj);
    233    
    234     return memObj;
    235 }
    236 
    237 static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& title, CachedImage* image)
    238 {
    239     ASSERT_ARG(image, image);
    240     ASSERT(image->image()->data());
    241 
    242     HRESULT hr = S_OK;
    243     HGLOBAL memObj = 0;
    244     String fsPath;
    245     memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
    246     if (!memObj)
    247         return 0;
    248 
    249     FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj);
    250     memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR));
    251     fgd->cItems = 1;
    252     fgd->fgd[0].dwFlags = FD_FILESIZE;
    253     fgd->fgd[0].nFileSizeLow = image->image()->data()->size();
    254    
    255     const String& preferredTitle = title.isEmpty() ? image->response().suggestedFilename() : title;
    256     String extension = image->image()->filenameExtension();
    257     if (extension.isEmpty()) {
    258         // Do not continue processing in the rare and unusual case where a decoded image is not able
    259         // to provide a filename extension. Something tricky (like a bait-n-switch) is going on
    260         return 0;
    261     }
    262     extension.insert(".", 0);
    263     fsPath = filesystemPathFromUrlOrTitle(url, preferredTitle, extension.charactersWithNullTermination(), false);
    264 
    265     if (fsPath.length() <= 0) {
    266         GlobalUnlock(memObj);
    267         GlobalFree(memObj);
    268         return 0;
    269     }
    270 
    271     int maxSize = min(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
    272     CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar));
    273     GlobalUnlock(memObj);
    274    
    275     return memObj;
    276 }
    277 
    278 
    279 // writeFileToDataObject takes ownership of fileDescriptor and fileContent
    280 static HRESULT writeFileToDataObject(IDataObject* dataObject, HGLOBAL fileDescriptor, HGLOBAL fileContent, HGLOBAL hDropContent)
    281 {
    282     HRESULT hr = S_OK;
    283     FORMATETC* fe;
    284     STGMEDIUM medium = {0};
    285     medium.tymed = TYMED_HGLOBAL;
    286 
    287     if (!fileDescriptor || !fileContent)
    288         goto exit;
    289 
    290     // Descriptor
    291     fe = fileDescriptorFormat();
    292 
    293     medium.hGlobal = fileDescriptor;
    294 
    295     if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))
    296         goto exit;
    297 
    298     // Contents
    299     fe = fileContentFormatZero();
    300     medium.hGlobal = fileContent;
    301     if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))
    302         goto exit;
    303 
    304 #if USE(CF)
    305     // HDROP
    306     if (hDropContent) {
    307         medium.hGlobal = hDropContent;
    308         hr = dataObject->SetData(cfHDropFormat(), &medium, TRUE);
    309     }
    310 #endif
    311 
    312 exit:
    313     if (FAILED(hr)) {
    314         if (fileDescriptor)
    315             GlobalFree(fileDescriptor);
    316         if (fileContent)
    317             GlobalFree(fileContent);
    318         if (hDropContent)
    319             GlobalFree(hDropContent);
    320     }
    321     return hr;
    322 }
    323 
    324 PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame* frame)
    325 {
    326     if (dragData->platformData())
    327         return ClipboardWin::create(DragAndDrop, dragData->platformData(), policy, frame);
    328     return ClipboardWin::create(DragAndDrop, dragData->dragDataMap(), policy, frame);
    329 }
    330 
    331 ClipboardWin::ClipboardWin(ClipboardType clipboardType, IDataObject* dataObject, ClipboardAccessPolicy policy, Frame* frame)
    332     : Clipboard(policy, clipboardType)
    333     , m_dataObject(dataObject)
    334     , m_writableDataObject(0)
    335     , m_frame(frame)
    336 {
    337 }
    338 
    339 ClipboardWin::ClipboardWin(ClipboardType clipboardType, WCDataObject* dataObject, ClipboardAccessPolicy policy, Frame* frame)
    340     : Clipboard(policy, clipboardType)
    341     , m_dataObject(dataObject)
    342     , m_writableDataObject(dataObject)
    343     , m_frame(frame)
    344 {
    345 }
    346 
    347 ClipboardWin::ClipboardWin(ClipboardType clipboardType, const DragDataMap& dataMap, ClipboardAccessPolicy policy, Frame* frame)
    348     : Clipboard(policy, clipboardType)
    349     , m_dataObject(0)
    350     , m_writableDataObject(0)
    351     , m_frame(frame)
    352     , m_dragDataMap(dataMap)
    353 {
    354 }
    355 
    356 ClipboardWin::~ClipboardWin()
    357 {
    358     if (m_dragImage)
    359         m_dragImage->removeClient(this);
    360 }
    361 
    362 static bool writeURL(WCDataObject *data, const KURL& url, String title, bool withPlainText, bool withHTML)
    363 {
    364     ASSERT(data);
    365 
    366     if (url.isEmpty())
    367         return false;
    368    
    369     if (title.isEmpty()) {
    370         title = url.lastPathComponent();
    371         if (title.isEmpty())
    372             title = url.host();
    373     }
    374 
    375     STGMEDIUM medium = {0};
    376     medium.tymed = TYMED_HGLOBAL;
    377 
    378     medium.hGlobal = createGlobalData(url, title);
    379     bool success = false;
    380     if (medium.hGlobal && FAILED(data->SetData(urlWFormat(), &medium, TRUE)))
    381         ::GlobalFree(medium.hGlobal);
    382     else
    383         success = true;
    384 
    385     if (withHTML) {
    386         Vector<char> cfhtmlData;
    387         markupToCFHTML(urlToMarkup(url, title), "", cfhtmlData);
    388         medium.hGlobal = createGlobalData(cfhtmlData);
    389         if (medium.hGlobal && FAILED(data->SetData(htmlFormat(), &medium, TRUE)))
    390             ::GlobalFree(medium.hGlobal);
    391         else
    392             success = true;
    393     }
    394 
    395     if (withPlainText) {
    396         medium.hGlobal = createGlobalData(url.string());
    397         if (medium.hGlobal && FAILED(data->SetData(plainTextWFormat(), &medium, TRUE)))
    398             ::GlobalFree(medium.hGlobal);
    399         else
    400             success = true;
    401     }
    402 
    403     return success;
    404 }
    405 
    406 void ClipboardWin::clearData(const String& type)
    407 {
    408     // FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941>
    409     ASSERT(isForDragAndDrop());
    410     if (!canWriteData() || !m_writableDataObject)
    411         return;
    412 
    413     ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
    414 
    415     if (dataType == ClipboardDataTypeURL) {
    416         m_writableDataObject->clearData(urlWFormat()->cfFormat);
    417         m_writableDataObject->clearData(urlFormat()->cfFormat);
    418     }
    419     if (dataType == ClipboardDataTypeText) {
    420         m_writableDataObject->clearData(plainTextFormat()->cfFormat);
    421         m_writableDataObject->clearData(plainTextWFormat()->cfFormat);
    422     }
    423 
    424 }
    425 
    426 void ClipboardWin::clearData()
    427 {
    428     // FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941>
    429     ASSERT(isForDragAndDrop());
    430     if (!canWriteData())
    431         return;
    432    
    433     m_writableDataObject = 0;
    434     WCDataObject::createInstance(&m_writableDataObject);
    435     m_dataObject = m_writableDataObject;
    436 }
    437 
    438 String ClipboardWin::getData(const String& type) const
    439 {     
    440     if (!canReadData() || (!m_dataObject && m_dragDataMap.isEmpty()))
    441         return "";
    442 
    443     ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
    444     if (dataType == ClipboardDataTypeText)
    445         return m_dataObject ? getPlainText(m_dataObject.get()) : getPlainText(&m_dragDataMap);
    446     if (dataType == ClipboardDataTypeURL)
    447         return m_dataObject ? getURL(m_dataObject.get(), DragData::DoNotConvertFilenames) : getURL(&m_dragDataMap, DragData::DoNotConvertFilenames);
    448     else if (dataType == ClipboardDataTypeTextHTML) {
    449         String data = m_dataObject ? getTextHTML(m_dataObject.get()) : getTextHTML(&m_dragDataMap);
    450         if (!data.isEmpty())
    451             return data;
    452         return m_dataObject ? getCFHTML(m_dataObject.get()) : getCFHTML(&m_dragDataMap);
    453     }
    454    
    455     return "";
    456 }
    457 
    458 bool ClipboardWin::setData(const String& type, const String& data)
    459 {
    460     // FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941>
    461     ASSERT(isForDragAndDrop());
    462     if (!canWriteData() || !m_writableDataObject)
    463         return false;
    464 
    465     ClipboardDataType winType = clipboardTypeFromMIMEType(type);
    466 
    467     if (winType == ClipboardDataTypeURL)
    468         return WebCore::writeURL(m_writableDataObject.get(), KURL(ParsedURLString, data), String(), false, true);
    469 
    470     if (winType == ClipboardDataTypeText) {
    471         STGMEDIUM medium = {0};
    472         medium.tymed = TYMED_HGLOBAL;
    473         medium.hGlobal = createGlobalData(data);
    474         if (!medium.hGlobal)
    475             return false;
    476 
    477         if (FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE))) {
    478             ::GlobalFree(medium.hGlobal);
    479             return false;
    480         }
    481         return true;
    482     }
    483 
    484     return false;
    485 }
    486 
    487 static void addMimeTypesForFormat(ListHashSet<String>& results, const FORMATETC& format)
    488 {
    489     // URL and Text are provided for compatibility with IE's model
    490     if (format.cfFormat == urlFormat()->cfFormat || format.cfFormat == urlWFormat()->cfFormat) {
    491         results.add("URL");
    492         results.add("text/uri-list");
    493     }
    494 
    495     if (format.cfFormat == plainTextWFormat()->cfFormat || format.cfFormat == plainTextFormat()->cfFormat) {
    496         results.add("Text");
    497         results.add("text/plain");
    498     }
    499 }
    500 
    501 // extensions beyond IE's API
    502 ListHashSet<String> ClipboardWin::types() const
    503 {
    504     ListHashSet<String> results;
    505     if (!canReadTypes())
    506         return results;
    507 
    508     if (!m_dataObject && m_dragDataMap.isEmpty())
    509         return results;
    510 
    511     if (m_dataObject) {
    512         COMPtr<IEnumFORMATETC> itr;
    513 
    514         if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
    515             return results;
    516 
    517         if (!itr)
    518             return results;
    519 
    520         FORMATETC data;
    521 
    522         // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
    523         while (itr->Next(1, &data, 0) == S_OK)
    524             addMimeTypesForFormat(results, data);
    525     } else {
    526         for (DragDataMap::const_iterator it = m_dragDataMap.begin(); it != m_dragDataMap.end(); ++it) {
    527             FORMATETC data;
    528             data.cfFormat = (*it).key;
    529             addMimeTypesForFormat(results, data);
    530         }
    531     }
    532 
    533     return results;
    534 }
    535 
    536 PassRefPtr<FileList> ClipboardWin::files() const
    537 {
    538 #if USE(CF)
    539     RefPtr<FileList> files = FileList::create();
    540     if (!canReadData())
    541         return files.release();
    542 
    543     if (!m_dataObject && m_dragDataMap.isEmpty())
    544         return files.release();
    545 
    546     if (m_dataObject) {
    547         STGMEDIUM medium;
    548         if (FAILED(m_dataObject->GetData(cfHDropFormat(), &medium)))
    549             return files.release();
    550 
    551         HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(medium.hGlobal));
    552         if (!hdrop)
    553             return files.release();
    554 
    555         WCHAR filename[MAX_PATH];
    556         UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
    557         for (UINT i = 0; i < fileCount; i++) {
    558             if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
    559                 continue;
    560             files->append(File::create(reinterpret_cast<UChar*>(filename), File::AllContentTypes));
    561         }
    562 
    563         GlobalUnlock(medium.hGlobal);
    564         ReleaseStgMedium(&medium);
    565         return files.release();
    566     }
    567     if (!m_dragDataMap.contains(cfHDropFormat()->cfFormat))
    568         return files.release();
    569     Vector<String> filesVector = m_dragDataMap.get(cfHDropFormat()->cfFormat);
    570     for (Vector<String>::iterator it = filesVector.begin(); it != filesVector.end(); ++it)
    571         files->append(File::create(*it));
    572     return files.release();
    573 #else
    574     notImplemented();
    575     return 0;
    576 #endif
    577 }
    578 
    579 void ClipboardWin::setDragImage(CachedImage* image, Node *node, const IntPoint &loc)
    580 {
    581     if (!canSetDragImage())
    582         return;
    583        
    584     if (m_dragImage)
    585         m_dragImage->removeClient(this);
    586     m_dragImage = image;
    587     if (m_dragImage)
    588         m_dragImage->addClient(this);
    589 
    590     m_dragLoc = loc;
    591     m_dragImageElement = node;
    592 }
    593 
    594 void ClipboardWin::setDragImage(CachedImage* img, const IntPoint &loc)
    595 {
    596     setDragImage(img, 0, loc);
    597 }
    598 
    599 void ClipboardWin::setDragImageElement(Node *node, const IntPoint &loc)
    600 {
    601     setDragImage(0, node, loc);
    602 }
    603 
    604 DragImageRef ClipboardWin::createDragImage(IntPoint& loc) const
     42DragImageRef Clipboard::createDragImage(IntPoint& dragLocation) const
    60543{
    60644    HBITMAP result = 0;
     
    60846#if USE(CAIRO) || USE(CG)
    60947        result = createDragImageFromImage(m_dragImage->image());       
    610         loc = m_dragLoc;
     48        dragLocation = m_dragLoc;
    61149#else
    61250        notImplemented();
     
    61553        Node* node = m_dragImageElement.get();
    61654        result = node->document()->frame()->nodeImage(node);
    617         loc = m_dragLoc;
     55        dragLocation = m_dragLoc;
    61856    }
    61957    return result;
    62058}
    62159
    622 static CachedImage* getCachedImage(Element* element)
    623 {
    624     // Attempt to pull CachedImage from element
    625     ASSERT(element);
    626     RenderObject* renderer = element->renderer();
    627     if (!renderer || !renderer->isImage())
    628         return 0;
    629    
    630     RenderImage* image = toRenderImage(renderer);
    631     if (image->cachedImage() && !image->cachedImage()->errorOccurred())
    632         return image->cachedImage();
    633 
    634     return 0;
    635 }
    636 
    637 static void writeImageToDataObject(IDataObject* dataObject, Element* element, const KURL& url)
    638 {
    639     // Shove image data into a DataObject for use as a file
    640     CachedImage* cachedImage = getCachedImage(element);
    641     if (!cachedImage || !cachedImage->imageForRenderer(element->renderer()) || !cachedImage->isLoaded())
    642         return;
    643 
    644     SharedBuffer* imageBuffer = cachedImage->imageForRenderer(element->renderer())->data();
    645     if (!imageBuffer || !imageBuffer->size())
    646         return;
    647 
    648     HGLOBAL imageFileDescriptor = createGlobalImageFileDescriptor(url.string(), element->getAttribute(altAttr), cachedImage);
    649     if (!imageFileDescriptor)
    650         return;
    651 
    652     HGLOBAL imageFileContent = createGlobalImageFileContent(imageBuffer);
    653     if (!imageFileContent) {
    654         GlobalFree(imageFileDescriptor);
    655         return;
    656     }
    657 
    658     String fileName = cachedImage->response().suggestedFilename();
    659     HGLOBAL hDropContent = createGlobalHDropContent(url, fileName, imageBuffer);
    660     if (!hDropContent) {
    661         GlobalFree(hDropContent);
    662         return;
    663     }
    664 
    665     writeFileToDataObject(dataObject, imageFileDescriptor, imageFileContent, hDropContent);
    666 }
    667 
    668 void ClipboardWin::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
     60void Clipboard::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
    66961{
    67062    // Order is important here for Explorer's sake
    671     if (!m_writableDataObject)
    672          return;
    673     WebCore::writeURL(m_writableDataObject.get(), url, title, true, false);
    674 
    675     writeImageToDataObject(m_writableDataObject.get(), element, url);
    676 
    677     AtomicString imageURL = element->getAttribute(srcAttr);
     63    if (!m_pasteboard->writableDataObject())
     64        return;
     65    m_pasteboard->writeURLToWritableDataObject(url, title);
     66    m_pasteboard->writeImageToDataObject(element, url);
     67    AtomicString imageURL = element->getAttribute(HTMLNames::srcAttr);
    67868    if (imageURL.isEmpty())
    67969        return;
     
    68979    markupToCFHTML(createMarkup(element, IncludeNode, 0, ResolveAllURLs), "", data);
    69080    medium.hGlobal = createGlobalData(data);
    691     if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE)))
     81    if (medium.hGlobal && FAILED(m_pasteboard->writableDataObject()->SetData(htmlFormat(), &medium, TRUE)))
    69282        ::GlobalFree(medium.hGlobal);
    69383}
    69484
    695 void ClipboardWin::writeURL(const KURL& kurl, const String& titleStr, Frame*)
    696 {
    697     if (!m_writableDataObject)
    698          return;
    699     WebCore::writeURL(m_writableDataObject.get(), kurl, titleStr, true, true);
    700 
    701     String url = kurl.string();
    702     ASSERT(url.containsOnlyASCII()); // KURL::string() is URL encoded.
    703 
    704     String fsPath = filesystemPathFromUrlOrTitle(url, titleStr, L".URL", true);
    705     String contentString("[InternetShortcut]\r\nURL=" + url + "\r\n");
    706     CString content = contentString.latin1();
    707 
    708     if (fsPath.length() <= 0)
    709         return;
    710 
    711     HGLOBAL urlFileDescriptor = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
    712     if (!urlFileDescriptor)
    713         return;
    714 
    715     HGLOBAL urlFileContent = GlobalAlloc(GPTR, content.length());
    716     if (!urlFileContent) {
    717         GlobalFree(urlFileDescriptor);
    718         return;
    719     }
    720 
    721     FILEGROUPDESCRIPTOR* fgd = static_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(urlFileDescriptor));
    722     ZeroMemory(fgd, sizeof(FILEGROUPDESCRIPTOR));
    723     fgd->cItems = 1;
    724     fgd->fgd[0].dwFlags = FD_FILESIZE;
    725     fgd->fgd[0].nFileSizeLow = content.length();
    726 
    727     unsigned maxSize = min(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
    728     CopyMemory(fgd->fgd[0].cFileName, fsPath.characters(), maxSize * sizeof(UChar));
    729     GlobalUnlock(urlFileDescriptor);
    730 
    731     char* fileContents = static_cast<char*>(GlobalLock(urlFileContent));
    732     CopyMemory(fileContents, content.data(), content.length());
    733     GlobalUnlock(urlFileContent);
    734 
    735     writeFileToDataObject(m_writableDataObject.get(), urlFileDescriptor, urlFileContent, 0);
    736 }
    737 
    738 void ClipboardWin::writeRange(Range* selectedRange, Frame* frame)
    739 {
    740     ASSERT(selectedRange);
    741     if (!m_writableDataObject)
    742          return;
    743 
    744     STGMEDIUM medium = {0};
    745     medium.tymed = TYMED_HGLOBAL;
    746 
    747     Vector<char> data;
    748     markupToCFHTML(createMarkup(selectedRange, 0, AnnotateForInterchange),
    749         selectedRange->startContainer()->document()->url().string(), data);
    750     medium.hGlobal = createGlobalData(data);
    751     if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE)))
    752         ::GlobalFree(medium.hGlobal);
    753 
    754     String str = frame->editor().selectedTextForClipboard();
    755     replaceNewlinesWithWindowsStyleNewlines(str);
    756     replaceNBSPWithSpace(str);
    757     medium.hGlobal = createGlobalData(str);
    758     if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE)))
    759         ::GlobalFree(medium.hGlobal);
    760 
    761     medium.hGlobal = 0;
    762     if (frame->editor().canSmartCopyOrDelete())
    763         m_writableDataObject->SetData(smartPasteFormat(), &medium, TRUE);
    764 }
    765 
    766 void ClipboardWin::writePlainText(const String& text)
    767 {
    768     if (!m_writableDataObject)
    769         return;
    770    
    771     STGMEDIUM medium = {0};
    772     medium.tymed = TYMED_HGLOBAL;
    773    
    774     String str = text;
    775     replaceNewlinesWithWindowsStyleNewlines(str);
    776     replaceNBSPWithSpace(str);
    777     medium.hGlobal = createGlobalData(str);
    778     if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE)))
    779         ::GlobalFree(medium.hGlobal);       
    780 
    781     medium.hGlobal = 0;
    782 }
    783    
    784 bool ClipboardWin::hasData()
    785 {
    786     if (!m_dataObject && m_dragDataMap.isEmpty())
    787         return false;
    788 
    789     if (m_dataObject) {
    790         COMPtr<IEnumFORMATETC> itr;
    791         if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
    792             return false;
    793 
    794         if (!itr)
    795             return false;
    796 
    797         FORMATETC data;
    798 
    799         // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
    800         if (itr->Next(1, &data, 0) == S_OK) {
    801             // There is at least one item in the IDataObject
    802             return true;
    803         }
    804 
    805         return false;
    806     }
    807     return !m_dragDataMap.isEmpty();
    808 }
    809 
    810 void ClipboardWin::setExternalDataObject(IDataObject *dataObject)
    811 {
    812     ASSERT(isForDragAndDrop());
    813 
    814     m_writableDataObject = 0;
    815     m_dataObject = dataObject;
    816 }
    817 
    81885} // namespace WebCore
  • trunk/Source/WebCore/platform/win/EditorWin.cpp

    r144911 r150772  
    2626#include "config.h"
    2727#include "Editor.h"
     28
     29#include "COMPtr.h"
     30#include "Clipboard.h"
     31#include "Document.h"
    2832#include "EditorClient.h"
    29 
    30 #include "ClipboardWin.h"
    31 #include "Document.h"
    3233#include "Element.h"
    3334#include "Frame.h"
    34 #include "htmlediting.h"
     35#include "Pasteboard.h"
    3536#include "TextIterator.h"
    3637#include "VisibleUnits.h"
     38#include "htmlediting.h"
    3739
    3840#include <windows.h>
     
    4749        clipboardData = 0;
    4850#endif
    49 
    50     return ClipboardWin::create(Clipboard::CopyAndPaste, clipboardData.get(), policy, frame);
     51    RefPtr<Clipboard> clipboard = Clipboard::createForCopyAndPaste(policy);
     52    const_cast<Pasteboard&>(clipboard->pasteboard()).setExternalDataObject(clipboardData.get());
     53    return clipboard.release();
    5154}
    5255
  • trunk/Source/WebCore/platform/win/PasteboardWin.cpp

    r150140 r150772  
    11/*
    22 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
     3 * Copyright (C) 2013 Xueqing Huang <huangxueqing@baidu.com>
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    3536#include "Element.h"
    3637#include "Frame.h"
     38#include "HTMLNames.h"
     39#include "HTMLParserIdioms.h"
    3740#include "HWndDC.h"
    3841#include "HitTestResult.h"
     
    4346#include "Range.h"
    4447#include "RenderImage.h"
     48#include "SharedBuffer.h"
    4549#include "TextEncoding.h"
    4650#include "WebCoreInstanceHandle.h"
     
    5054
    5155namespace WebCore {
     56
     57// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
     58// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
    5259
    5360static UINT HTMLClipboardFormat = 0;
     
    9097}
    9198
    92 Pasteboard::Pasteboard()
     99PassOwnPtr<Pasteboard> Pasteboard::createForCopyAndPaste()
     100{
     101    return adoptPtr(new Pasteboard);
     102}
     103
     104PassOwnPtr<Pasteboard> Pasteboard::createPrivate()
     105{
     106    // Windows has no "Private pasteboard" concept.
     107    return createForCopyAndPaste();
     108}
     109
     110#if ENABLE(DRAG_SUPPORT)
     111PassOwnPtr<Pasteboard> Pasteboard::createForDragAndDrop()
     112{
     113    COMPtr<WCDataObject> dataObject;
     114    WCDataObject::createInstance(&dataObject);
     115    return adoptPtr(new Pasteboard(dataObject.get()));
     116}
     117
     118// static
     119PassOwnPtr<Pasteboard> Pasteboard::createForDragAndDrop(const DragData& dragData)
     120{
     121    if (dragData.platformData())
     122        return adoptPtr(new Pasteboard(dragData.platformData()));
     123    // FIXME: Should add a const overload of dragDataMap so we don't need a const_cast here.
     124    return adoptPtr(new Pasteboard(const_cast<DragData&>(dragData).dragDataMap()));
     125}
     126#endif
     127
     128void Pasteboard::finishCreatingPasteboard()
    93129{
    94130    WNDCLASS wc;
     
    107143}
    108144
     145Pasteboard::Pasteboard()
     146    : m_dataObject(0)
     147    , m_writableDataObject(0)
     148{
     149    finishCreatingPasteboard();
     150}
     151
     152Pasteboard::Pasteboard(IDataObject* dataObject)
     153    : m_dataObject(dataObject)
     154    , m_writableDataObject(0)
     155{
     156    finishCreatingPasteboard();
     157}
     158
     159Pasteboard::Pasteboard(WCDataObject* dataObject)
     160    : m_dataObject(dataObject)
     161    , m_writableDataObject(dataObject)
     162{
     163    finishCreatingPasteboard();
     164}
     165
     166Pasteboard::Pasteboard(const DragDataMap& dataMap)
     167    : m_dataObject(0)
     168    , m_writableDataObject(0)
     169    , m_dragDataMap(dataMap)
     170{
     171    finishCreatingPasteboard();
     172}
     173
    109174void Pasteboard::clear()
    110175{
     
    113178        ::CloseClipboard();
    114179    }
     180}
     181
     182enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardDataTypeText, ClipboardDataTypeTextHTML };
     183
     184static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
     185{
     186    String qType = type.stripWhiteSpace().lower();
     187
     188    // two special cases for IE compatibility
     189    if (qType == "text" || qType == "text/plain" || qType.startsWith("text/plain;"))
     190        return ClipboardDataTypeText;
     191    if (qType == "url" || qType == "text/uri-list")
     192        return ClipboardDataTypeURL;
     193    if (qType == "text/html")
     194        return ClipboardDataTypeTextHTML;
     195
     196    return ClipboardDataTypeNone;
     197}
     198
     199void Pasteboard::clear(const String& type)
     200{
     201    if (!m_writableDataObject)
     202        return;
     203
     204    ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
     205
     206    if (dataType == ClipboardDataTypeURL) {
     207        m_writableDataObject->clearData(urlWFormat()->cfFormat);
     208        m_writableDataObject->clearData(urlFormat()->cfFormat);
     209    }
     210    if (dataType == ClipboardDataTypeText) {
     211        m_writableDataObject->clearData(plainTextFormat()->cfFormat);
     212        m_writableDataObject->clearData(plainTextWFormat()->cfFormat);
     213    }
     214}
     215
     216bool Pasteboard::hasData()
     217{
     218    if (!m_dataObject && m_dragDataMap.isEmpty())
     219        return false;
     220
     221    if (m_dataObject) {
     222        COMPtr<IEnumFORMATETC> itr;
     223        if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
     224            return false;
     225
     226        if (!itr)
     227            return false;
     228
     229        FORMATETC data;
     230
     231        // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
     232        if (itr->Next(1, &data, 0) == S_OK) {
     233            // There is at least one item in the IDataObject
     234            return true;
     235        }
     236
     237        return false;
     238    }
     239    return !m_dragDataMap.isEmpty();
     240}
     241
     242static void addMimeTypesForFormat(ListHashSet<String>& results, const FORMATETC& format)
     243{
     244    // URL and Text are provided for compatibility with IE's model
     245    if (format.cfFormat == urlFormat()->cfFormat || format.cfFormat == urlWFormat()->cfFormat) {
     246        results.add("URL");
     247        results.add("text/uri-list");
     248    }
     249
     250    if (format.cfFormat == plainTextWFormat()->cfFormat || format.cfFormat == plainTextFormat()->cfFormat) {
     251        results.add("Text");
     252        results.add("text/plain");
     253    }
     254}
     255
     256ListHashSet<String> Pasteboard::types()
     257{
     258    ListHashSet<String> results;
     259
     260    if (!m_dataObject && m_dragDataMap.isEmpty())
     261        return results;
     262
     263    if (m_dataObject) {
     264        COMPtr<IEnumFORMATETC> itr;
     265
     266        if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
     267            return results;
     268
     269        if (!itr)
     270            return results;
     271
     272        FORMATETC data;
     273
     274        // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
     275        while (itr->Next(1, &data, 0) == S_OK)
     276            addMimeTypesForFormat(results, data);
     277    } else {
     278        for (DragDataMap::const_iterator it = m_dragDataMap.begin(); it != m_dragDataMap.end(); ++it) {
     279            FORMATETC data;
     280            data.cfFormat = (*it).key;
     281            addMimeTypesForFormat(results, data);
     282        }
     283    }
     284
     285    return results;
     286}
     287
     288String Pasteboard::readString(const String& type)
     289{
     290    if (!m_dataObject && m_dragDataMap.isEmpty())
     291        return "";
     292
     293    ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
     294    if (dataType == ClipboardDataTypeText)
     295        return m_dataObject ? getPlainText(m_dataObject.get()) : getPlainText(&m_dragDataMap);
     296    if (dataType == ClipboardDataTypeURL)
     297        return m_dataObject ? getURL(m_dataObject.get(), DragData::DoNotConvertFilenames) : getURL(&m_dragDataMap, DragData::DoNotConvertFilenames);
     298    if (dataType == ClipboardDataTypeTextHTML) {
     299        String data = m_dataObject ? getTextHTML(m_dataObject.get()) : getTextHTML(&m_dragDataMap);
     300        if (!data.isEmpty())
     301            return data;
     302        return m_dataObject ? getCFHTML(m_dataObject.get()) : getCFHTML(&m_dragDataMap);
     303    }
     304
     305    return "";
     306}
     307
     308Vector<String> Pasteboard::readFilenames()
     309{
     310#if USE(CF)
     311    Vector<String> fileNames;
     312
     313    if (m_dataObject) {
     314        STGMEDIUM medium;
     315        if (FAILED(m_dataObject->GetData(cfHDropFormat(), &medium)))
     316            return fileNames;
     317
     318        HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(medium.hGlobal));
     319        if (!hdrop)
     320            return fileNames;
     321
     322        WCHAR filename[MAX_PATH];
     323        UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
     324        for (UINT i = 0; i < fileCount; i++) {
     325            if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
     326                continue;
     327            fileNames.append(filename);
     328        }
     329
     330        GlobalUnlock(medium.hGlobal);
     331        ReleaseStgMedium(&medium);
     332        return fileNames;
     333    }
     334    if (!m_dragDataMap.contains(cfHDropFormat()->cfFormat))
     335        return fileNames;
     336    return m_dragDataMap.get(cfHDropFormat()->cfFormat);
     337#else
     338    notImplemented();
     339    return 0;
     340#endif
     341}
     342
     343static bool writeURL(WCDataObject *data, const KURL& url, String title, bool withPlainText, bool withHTML)
     344{
     345    ASSERT(data);
     346
     347    if (url.isEmpty())
     348        return false;
     349
     350    if (title.isEmpty()) {
     351        title = url.lastPathComponent();
     352        if (title.isEmpty())
     353            title = url.host();
     354    }
     355
     356    STGMEDIUM medium = {0};
     357    medium.tymed = TYMED_HGLOBAL;
     358
     359    medium.hGlobal = createGlobalData(url, title);
     360    bool success = false;
     361    if (medium.hGlobal && FAILED(data->SetData(urlWFormat(), &medium, TRUE)))
     362        ::GlobalFree(medium.hGlobal);
     363    else
     364        success = true;
     365
     366    if (withHTML) {
     367        Vector<char> cfhtmlData;
     368        markupToCFHTML(urlToMarkup(url, title), "", cfhtmlData);
     369        medium.hGlobal = createGlobalData(cfhtmlData);
     370        if (medium.hGlobal && FAILED(data->SetData(htmlFormat(), &medium, TRUE)))
     371            ::GlobalFree(medium.hGlobal);
     372        else
     373            success = true;
     374    }
     375
     376    if (withPlainText) {
     377        medium.hGlobal = createGlobalData(url.string());
     378        if (medium.hGlobal && FAILED(data->SetData(plainTextWFormat(), &medium, TRUE)))
     379            ::GlobalFree(medium.hGlobal);
     380        else
     381            success = true;
     382    }
     383
     384    return success;
     385}
     386
     387bool Pasteboard::writeString(const String& type, const String& data)
     388{
     389    if (!m_writableDataObject)
     390        return false;
     391
     392    ClipboardDataType winType = clipboardTypeFromMIMEType(type);
     393
     394    if (winType == ClipboardDataTypeURL)
     395        return WebCore::writeURL(m_writableDataObject.get(), KURL(KURL(), data), String(), false, true);
     396
     397    if (winType == ClipboardDataTypeText) {
     398        STGMEDIUM medium = {0};
     399        medium.tymed = TYMED_HGLOBAL;
     400        medium.hGlobal = createGlobalData(data);
     401        if (!medium.hGlobal)
     402            return false;
     403
     404        if (FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE))) {
     405            ::GlobalFree(medium.hGlobal);
     406            return false;
     407        }
     408        return true;
     409    }
     410
     411    return false;
     412}
     413
     414void Pasteboard::setDragImage(DragImageRef, const IntPoint&)
     415{
     416    // Do nothing in Windows.
     417}
     418
     419void Pasteboard::writeRangeToDataObject(Range* selectedRange, Frame* frame)
     420{
     421    ASSERT(selectedRange);
     422    if (!m_writableDataObject)
     423        return;
     424
     425    STGMEDIUM medium = {0};
     426    medium.tymed = TYMED_HGLOBAL;
     427
     428    Vector<char> data;
     429    markupToCFHTML(createMarkup(selectedRange, 0, AnnotateForInterchange),
     430        selectedRange->startContainer()->document()->url().string(), data);
     431    medium.hGlobal = createGlobalData(data);
     432    if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE)))
     433        ::GlobalFree(medium.hGlobal);
     434
     435    String str = frame->editor().selectedTextForClipboard();
     436    replaceNewlinesWithWindowsStyleNewlines(str);
     437    replaceNBSPWithSpace(str);
     438    medium.hGlobal = createGlobalData(str);
     439    if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE)))
     440        ::GlobalFree(medium.hGlobal);
     441
     442    medium.hGlobal = 0;
     443    if (frame->editor().canSmartCopyOrDelete())
     444        m_writableDataObject->SetData(smartPasteFormat(), &medium, TRUE);
    115445}
    116446
     
    147477            ::CloseClipboard();
    148478        }
    149        
    150     }
     479    }
     480
     481    writeRangeToDataObject(selectedRange, frame);
     482}
     483
     484void Pasteboard::writePlainTextToDataObject(const String& text, SmartReplaceOption smartReplaceOption)
     485{
     486    if (!m_writableDataObject)
     487        return;
     488
     489    STGMEDIUM medium = {0};
     490    medium.tymed = TYMED_HGLOBAL;
     491
     492    String str = text;
     493    replaceNewlinesWithWindowsStyleNewlines(str);
     494    replaceNBSPWithSpace(str);
     495    medium.hGlobal = createGlobalData(str);
     496    if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE)))
     497        ::GlobalFree(medium.hGlobal);       
     498
     499    medium.hGlobal = 0;
    151500}
    152501
     
    172521        }
    173522    }
     523
     524    writePlainTextToDataObject(text, smartReplaceOption);
     525}
     526
     527#if !OS(WINCE)
     528static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length)
     529{
     530    size_t writeTo = 0;
     531    size_t readFrom = 0;
     532    while (readFrom < length) {
     533        UINT type = PathGetCharType(psz[readFrom]);
     534        if (!psz[readFrom] || type & (GCT_LFNCHAR | GCT_SHORTCHAR))
     535            psz[writeTo++] = psz[readFrom];
     536
     537        readFrom++;
     538    }
     539    psz[writeTo] = 0;
     540}
     541#endif
     542
     543static String filesystemPathFromUrlOrTitle(const String& url, const String& title, const UChar* extension, bool isLink)
     544{
     545#if OS(WINCE)
     546    notImplemented();
     547    return String();
     548#else
     549    static const size_t fsPathMaxLengthExcludingNullTerminator = MAX_PATH - 1;
     550    bool usedURL = false;
     551    WCHAR fsPathBuffer[MAX_PATH];
     552    fsPathBuffer[0] = 0;
     553    int extensionLen = extension ? lstrlen(extension) : 0;
     554    int fsPathMaxLengthExcludingExtension = fsPathMaxLengthExcludingNullTerminator - extensionLen;
     555
     556    if (!title.isEmpty()) {
     557        size_t len = std::min<size_t>(title.length(), fsPathMaxLengthExcludingExtension);
     558        CopyMemory(fsPathBuffer, title.characters(), len * sizeof(UChar));
     559        fsPathBuffer[len] = 0;
     560        pathRemoveBadFSCharacters(fsPathBuffer, len);
     561    }
     562
     563    if (!lstrlen(fsPathBuffer)) {
     564        KURL kurl(KURL(), url);
     565        usedURL = true;
     566        // The filename for any content based drag or file url should be the last element of
     567        // the path. If we can't find it, or we're coming up with the name for a link
     568        // we just use the entire url.
     569        DWORD len = fsPathMaxLengthExcludingExtension;
     570        String lastComponent = kurl.lastPathComponent();
     571        if (kurl.isLocalFile() || (!isLink && !lastComponent.isEmpty())) {
     572            len = std::min<DWORD>(fsPathMaxLengthExcludingExtension, lastComponent.length());
     573            CopyMemory(fsPathBuffer, lastComponent.characters(), len * sizeof(UChar));
     574        } else {
     575            len = std::min<DWORD>(fsPathMaxLengthExcludingExtension, url.length());
     576            CopyMemory(fsPathBuffer, url.characters(), len * sizeof(UChar));
     577        }
     578        fsPathBuffer[len] = 0;
     579        pathRemoveBadFSCharacters(fsPathBuffer, len);
     580    }
     581
     582    if (!extension)
     583        return String(static_cast<UChar*>(fsPathBuffer));
     584
     585    if (!isLink && usedURL) {
     586        PathRenameExtension(fsPathBuffer, extension);
     587        return String(static_cast<UChar*>(fsPathBuffer));
     588    }
     589
     590    return makeString(static_cast<const UChar*>(fsPathBuffer), extension);
     591#endif
     592}
     593
     594// writeFileToDataObject takes ownership of fileDescriptor and fileContent
     595static HRESULT writeFileToDataObject(IDataObject* dataObject, HGLOBAL fileDescriptor, HGLOBAL fileContent, HGLOBAL hDropContent)
     596{
     597    HRESULT hr = S_OK;
     598    FORMATETC* fe;
     599    STGMEDIUM medium = {0};
     600    medium.tymed = TYMED_HGLOBAL;
     601
     602    if (!fileDescriptor || !fileContent)
     603        goto exit;
     604
     605    // Descriptor
     606    fe = fileDescriptorFormat();
     607
     608    medium.hGlobal = fileDescriptor;
     609
     610    if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))
     611        goto exit;
     612
     613    // Contents
     614    fe = fileContentFormatZero();
     615    medium.hGlobal = fileContent;
     616    if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE)))
     617        goto exit;
     618
     619#if USE(CF)
     620    // HDROP
     621    if (hDropContent) {
     622        medium.hGlobal = hDropContent;
     623        hr = dataObject->SetData(cfHDropFormat(), &medium, TRUE);
     624    }
     625#endif
     626
     627exit:
     628    if (FAILED(hr)) {
     629        if (fileDescriptor)
     630            GlobalFree(fileDescriptor);
     631        if (fileContent)
     632            GlobalFree(fileContent);
     633        if (hDropContent)
     634            GlobalFree(hDropContent);
     635    }
     636    return hr;
     637}
     638
     639void Pasteboard::writeURLToDataObject(const KURL& kurl, const String& titleStr, Frame* frame)
     640{
     641    if (!m_writableDataObject)
     642        return;
     643    WebCore::writeURL(m_writableDataObject.get(), kurl, titleStr, true, true);
     644
     645    String url = kurl.string();
     646    ASSERT(url.containsOnlyASCII()); // KURL::string() is URL encoded.
     647
     648    String fsPath = filesystemPathFromUrlOrTitle(url, titleStr, L".URL", true);
     649    String contentString("[InternetShortcut]\r\nURL=" + url + "\r\n");
     650    CString content = contentString.latin1();
     651
     652    if (fsPath.length() <= 0)
     653        return;
     654
     655    HGLOBAL urlFileDescriptor = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
     656    if (!urlFileDescriptor)
     657        return;
     658
     659    HGLOBAL urlFileContent = GlobalAlloc(GPTR, content.length());
     660    if (!urlFileContent) {
     661        GlobalFree(urlFileDescriptor);
     662        return;
     663    }
     664
     665    FILEGROUPDESCRIPTOR* fgd = static_cast<FILEGROUPDESCRIPTOR*>(GlobalLock(urlFileDescriptor));
     666    ZeroMemory(fgd, sizeof(FILEGROUPDESCRIPTOR));
     667    fgd->cItems = 1;
     668    fgd->fgd[0].dwFlags = FD_FILESIZE;
     669    fgd->fgd[0].nFileSizeLow = content.length();
     670
     671    unsigned maxSize = std::min(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
     672    CopyMemory(fgd->fgd[0].cFileName, fsPath.characters(), maxSize * sizeof(UChar));
     673    GlobalUnlock(urlFileDescriptor);
     674
     675    char* fileContents = static_cast<char*>(GlobalLock(urlFileContent));
     676    CopyMemory(fileContents, content.data(), content.length());
     677    GlobalUnlock(urlFileContent);
     678
     679    writeFileToDataObject(m_writableDataObject.get(), urlFileDescriptor, urlFileContent, 0);
    174680}
    175681
     
    212718        ::CloseClipboard();
    213719    }
     720
     721    writeURLToDataObject(url, titleStr, frame);
    214722}
    215723
     
    255763        ::CloseClipboard();
    256764    }
     765}
     766
     767void Pasteboard::writePasteboard(const Pasteboard& sourcePasteboard)
     768{
     769    notImplemented();
    257770}
    258771
     
    353866}
    354867
     868void Pasteboard::setExternalDataObject(IDataObject *dataObject)
     869{
     870    m_writableDataObject = 0;
     871    m_dataObject = dataObject;
     872}
     873
     874static CachedImage* getCachedImage(Element* element)
     875{
     876    // Attempt to pull CachedImage from element
     877    ASSERT(element);
     878    RenderObject* renderer = element->renderer();
     879    if (!renderer || !renderer->isImage())
     880        return 0;
     881
     882    RenderImage* image = toRenderImage(renderer);
     883    if (image->cachedImage() && !image->cachedImage()->errorOccurred())
     884        return image->cachedImage();
     885
     886    return 0;
     887}
     888
     889static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& title, CachedImage* image)
     890{
     891    ASSERT_ARG(image, image);
     892    ASSERT(image->image()->data());
     893
     894    HRESULT hr = S_OK;
     895    HGLOBAL memObj = 0;
     896    String fsPath;
     897    memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR));
     898    if (!memObj)
     899        return 0;
     900
     901    FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj);
     902    memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR));
     903    fgd->cItems = 1;
     904    fgd->fgd[0].dwFlags = FD_FILESIZE;
     905    fgd->fgd[0].nFileSizeLow = image->image()->data()->size();
     906
     907    const String& preferredTitle = title.isEmpty() ? image->response().suggestedFilename() : title;
     908    String extension = image->image()->filenameExtension();
     909    if (extension.isEmpty()) {
     910        // Do not continue processing in the rare and unusual case where a decoded image is not able
     911        // to provide a filename extension. Something tricky (like a bait-n-switch) is going on
     912        return 0;
     913    }
     914    extension.insert(".", 0);
     915    fsPath = filesystemPathFromUrlOrTitle(url, preferredTitle, extension.charactersWithNullTermination(), false);
     916
     917    if (fsPath.length() <= 0) {
     918        GlobalUnlock(memObj);
     919        GlobalFree(memObj);
     920        return 0;
     921    }
     922
     923    int maxSize = std::min(fsPath.length(), WTF_ARRAY_LENGTH(fgd->fgd[0].cFileName));
     924    CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar));
     925    GlobalUnlock(memObj);
     926
     927    return memObj;
     928}
     929
     930static HGLOBAL createGlobalImageFileContent(SharedBuffer* data)
     931{
     932    HGLOBAL memObj = GlobalAlloc(GPTR, data->size());
     933    if (!memObj)
     934        return 0;
     935
     936    char* fileContents = (PSTR)GlobalLock(memObj);
     937
     938    CopyMemory(fileContents, data->data(), data->size());
     939
     940    GlobalUnlock(memObj);
     941
     942    return memObj;
     943}
     944
     945static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, SharedBuffer* data)
     946{
     947    if (fileName.isEmpty() || !data)
     948        return 0;
     949
     950    WCHAR filePath[MAX_PATH];
     951
     952    if (url.isLocalFile()) {
     953        String localPath = decodeURLEscapeSequences(url.path());
     954        // windows does not enjoy a leading slash on paths
     955        if (localPath[0] == '/')
     956            localPath = localPath.substring(1);
     957        LPCWSTR localPathStr = localPath.charactersWithNullTermination();
     958        if (wcslen(localPathStr) + 1 < MAX_PATH)
     959            wcscpy_s(filePath, MAX_PATH, localPathStr);
     960        else
     961            return 0;
     962    } else {
     963#if OS(WINCE)
     964        notImplemented();
     965        return 0;
     966#else
     967        WCHAR tempPath[MAX_PATH];
     968        WCHAR extension[MAX_PATH];
     969        if (!::GetTempPath(WTF_ARRAY_LENGTH(tempPath), tempPath))
     970            return 0;
     971        if (!::PathAppend(tempPath, fileName.charactersWithNullTermination()))
     972            return 0;
     973        LPCWSTR foundExtension = ::PathFindExtension(tempPath);
     974        if (foundExtension) {
     975            if (wcscpy_s(extension, MAX_PATH, foundExtension))
     976                return 0;
     977        } else
     978            *extension = 0;
     979        ::PathRemoveExtension(tempPath);
     980        for (int i = 1; i < 10000; i++) {
     981            if (swprintf_s(filePath, MAX_PATH, TEXT("%s-%d%s"), tempPath, i, extension) == -1)
     982                return 0;
     983            if (!::PathFileExists(filePath))
     984                break;
     985        }
     986        HANDLE tempFileHandle = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
     987        if (tempFileHandle == INVALID_HANDLE_VALUE)
     988            return 0;
     989
     990        // Write the data to this temp file.
     991        DWORD written;
     992        BOOL tempWriteSucceeded = WriteFile(tempFileHandle, data->data(), data->size(), &written, 0);
     993        CloseHandle(tempFileHandle);
     994        if (!tempWriteSucceeded)
     995            return 0;
     996#endif
     997    }
     998
     999    SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * (wcslen(filePath) + 2));
     1000    HGLOBAL memObj = GlobalAlloc(GHND | GMEM_SHARE, dropFilesSize);
     1001    if (!memObj)
     1002        return 0;
     1003
     1004    DROPFILES* dropFiles = (DROPFILES*) GlobalLock(memObj);
     1005    dropFiles->pFiles = sizeof(DROPFILES);
     1006    dropFiles->fWide = TRUE;
     1007    wcscpy((LPWSTR)(dropFiles + 1), filePath);   
     1008    GlobalUnlock(memObj);
     1009
     1010    return memObj;
     1011}
     1012
     1013void Pasteboard::writeImageToDataObject(Element* element, const KURL& url)
     1014{
     1015    // Shove image data into a DataObject for use as a file
     1016    CachedImage* cachedImage = getCachedImage(element);
     1017    if (!cachedImage || !cachedImage->imageForRenderer(element->renderer()) || !cachedImage->isLoaded())
     1018        return;
     1019
     1020    SharedBuffer* imageBuffer = cachedImage->imageForRenderer(element->renderer())->data();
     1021    if (!imageBuffer || !imageBuffer->size())
     1022        return;
     1023
     1024    HGLOBAL imageFileDescriptor = createGlobalImageFileDescriptor(url.string(), element->getAttribute(HTMLNames::altAttr), cachedImage);
     1025    if (!imageFileDescriptor)
     1026        return;
     1027
     1028    HGLOBAL imageFileContent = createGlobalImageFileContent(imageBuffer);
     1029    if (!imageFileContent) {
     1030        GlobalFree(imageFileDescriptor);
     1031        return;
     1032    }
     1033
     1034    String fileName = cachedImage->response().suggestedFilename();
     1035    HGLOBAL hDropContent = createGlobalHDropContent(url, fileName, imageBuffer);
     1036    if (!hDropContent) {
     1037        GlobalFree(hDropContent);
     1038        return;
     1039    }
     1040
     1041    writeFileToDataObject(m_writableDataObject.get(), imageFileDescriptor, imageFileContent, hDropContent);
     1042}
     1043
     1044void Pasteboard::writeURLToWritableDataObject(const KURL& url, const String& title)
     1045{
     1046    WebCore::writeURL(m_writableDataObject.get(), url, title, true, false);
     1047}
     1048
    3551049} // namespace WebCore
  • trunk/Source/WebKit/win/ChangeLog

    r150718 r150772  
     12013-05-27  Xueqing Huang  <huangxueqing@baidu.com>
     2
     3        Move Windows port off legacy clipboard.
     4        https://bugs.webkit.org/show_bug.cgi?id=116258
     5
     6        Reviewed by Darin Adler.
     7
     8        * WebCoreSupport/WebDragClient.cpp:
     9        (WebDragClient::willPerformDragSourceAction): Get IDataObject from Pasteboard instead of Clipboard.
     10        (WebDragClient::startDrag): Ditto.
     11
    1122013-05-26  Antti Koivisto  <antti@apple.com>
    213
  • trunk/Source/WebKit/win/WebCoreSupport/WebDragClient.cpp

    r148577 r150772  
    3030#include "WebView.h"
    3131
    32 #include <shlobj.h>
    33 
    34 #include <WebCore/ClipboardWin.h>
     32#include <WebCore/Clipboard.h>
    3533#include <WebCore/DragController.h>
    3634#include <WebCore/DragData.h>
    3735#include <WebCore/EventHandler.h>
     36#include <WebCore/Page.h>
     37#include <WebCore/Pasteboard.h>
    3838#include <WebCore/PlatformMouseEvent.h>
    3939#include <WebCore/Frame.h>
    4040#include <WebCore/FrameView.h>
    4141#include <WebCore/GraphicsContext.h>
    42 #include <WebCore/Page.h>
     42#include <shlobj.h>
    4343
    4444using namespace WebCore;
     
    104104
    105105    POINT point = intPoint;
    106     COMPtr<IDataObject> dataObject = static_cast<ClipboardWin*>(clipboard)->dataObject();
     106    COMPtr<IDataObject> dataObject = clipboard->pasteboard().dataObject();
    107107
    108108    COMPtr<IDataObject> newDataObject;
    109109    HRESULT result = uiDelegate->willPerformDragSourceAction(m_webView, static_cast<WebDragSourceAction>(action), &point, dataObject.get(), &newDataObject);
    110110    if (result == S_OK && newDataObject != dataObject)
    111         static_cast<ClipboardWin*>(clipboard)->setExternalDataObject(newDataObject.get());
     111        const_cast<Pasteboard&>(clipboard->pasteboard()).setExternalDataObject(newDataObject.get());
    112112}
    113113
     
    125125        return;
    126126
    127     dataObject = static_cast<ClipboardWin*>(clipboard)->dataObject();
     127    dataObject = clipboard->pasteboard().dataObject();
    128128    if (source && (image || dataObject)) {
    129129        if (image) {
Note: See TracChangeset for help on using the changeset viewer.