• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "DragData.h"
28 
29 #include "COMPtr.h"
30 #include "ClipboardUtilitiesWin.h"
31 #include "Frame.h"
32 #include "DocumentFragment.h"
33 #include "PlatformString.h"
34 #include "Markup.h"
35 #include "TextEncoding.h"
36 #include <objidl.h>
37 #include <shlwapi.h>
38 #include <wininet.h>
39 #include <wtf/Forward.h>
40 #include <wtf/Hashmap.h>
41 #include <wtf/PassRefPtr.h>
42 #include <wtf/RefPtr.h>
43 
44 namespace WebCore {
45 
DragData(const DragDataMap & data,const IntPoint & clientPosition,const IntPoint & globalPosition,DragOperation sourceOperationMask,DragApplicationFlags flags)46 DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, const IntPoint& globalPosition,
47     DragOperation sourceOperationMask, DragApplicationFlags flags)
48     : m_clientPosition(clientPosition)
49     , m_globalPosition(globalPosition)
50     , m_platformDragData(0)
51     , m_draggingSourceOperationMask(sourceOperationMask)
52     , m_applicationFlags(flags)
53     , m_dragDataMap(data)
54 {
55 }
56 
containsURL(Frame *,FilenameConversionPolicy filenamePolicy) const57 bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const
58 {
59     if (m_platformDragData)
60         return SUCCEEDED(m_platformDragData->QueryGetData(urlWFormat()))
61             || SUCCEEDED(m_platformDragData->QueryGetData(urlFormat()))
62             || (filenamePolicy == ConvertFilenames
63                 && (SUCCEEDED(m_platformDragData->QueryGetData(filenameWFormat()))
64                     || SUCCEEDED(m_platformDragData->QueryGetData(filenameFormat()))));
65     return m_dragDataMap.contains(urlWFormat()->cfFormat) || m_dragDataMap.contains(urlFormat()->cfFormat)
66         || (filenamePolicy == ConvertFilenames && (m_dragDataMap.contains(filenameWFormat()->cfFormat) || m_dragDataMap.contains(filenameFormat()->cfFormat)));
67 }
68 
dragDataMap()69 const DragDataMap& DragData::dragDataMap()
70 {
71     if (!m_dragDataMap.isEmpty() || !m_platformDragData)
72         return m_dragDataMap;
73     // Enumerate clipboard content and load it in the map.
74     COMPtr<IEnumFORMATETC> itr;
75 
76     if (FAILED(m_platformDragData->EnumFormatEtc(DATADIR_GET, &itr)) || !itr)
77         return m_dragDataMap;
78 
79     FORMATETC dataFormat;
80     while (itr->Next(1, &dataFormat, 0) == S_OK) {
81         Vector<String> dataStrings;
82         getClipboardData(m_platformDragData, &dataFormat, dataStrings);
83         if (!dataStrings.isEmpty())
84             m_dragDataMap.set(dataFormat.cfFormat, dataStrings);
85     }
86     return m_dragDataMap;
87 }
88 
asURL(Frame *,FilenameConversionPolicy filenamePolicy,String * title) const89 String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const
90 {
91     bool success;
92     return (m_platformDragData) ? getURL(m_platformDragData, filenamePolicy, success, title) : getURL(&m_dragDataMap, filenamePolicy, title);
93 }
94 
containsFiles() const95 bool DragData::containsFiles() const
96 {
97     return (m_platformDragData) ? SUCCEEDED(m_platformDragData->QueryGetData(cfHDropFormat())) : m_dragDataMap.contains(cfHDropFormat()->cfFormat);
98 }
99 
asFilenames(Vector<String> & result) const100 void DragData::asFilenames(Vector<String>& result) const
101 {
102     if (m_platformDragData) {
103         WCHAR filename[MAX_PATH];
104 
105         STGMEDIUM medium;
106         if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium)))
107             return;
108 
109         HDROP hdrop = (HDROP)GlobalLock(medium.hGlobal);
110 
111         if (!hdrop)
112             return;
113 
114         const unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
115         for (unsigned i = 0; i < numFiles; i++) {
116             if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename)))
117                 continue;
118             result.append((UChar*)filename);
119         }
120 
121         // Free up memory from drag
122         DragFinish(hdrop);
123 
124         GlobalUnlock(medium.hGlobal);
125         return;
126     }
127     result = m_dragDataMap.get(cfHDropFormat()->cfFormat);
128 }
129 
containsPlainText() const130 bool DragData::containsPlainText() const
131 {
132     if (m_platformDragData)
133         return SUCCEEDED(m_platformDragData->QueryGetData(plainTextWFormat()))
134             || SUCCEEDED(m_platformDragData->QueryGetData(plainTextFormat()));
135     return m_dragDataMap.contains(plainTextWFormat()->cfFormat) || m_dragDataMap.contains(plainTextFormat()->cfFormat);
136 }
137 
asPlainText(Frame *) const138 String DragData::asPlainText(Frame*) const
139 {
140     bool success;
141     return (m_platformDragData) ? getPlainText(m_platformDragData, success) : getPlainText(&m_dragDataMap);
142 }
143 
containsColor() const144 bool DragData::containsColor() const
145 {
146     return false;
147 }
148 
canSmartReplace() const149 bool DragData::canSmartReplace() const
150 {
151     if (m_platformDragData)
152         return SUCCEEDED(m_platformDragData->QueryGetData(smartPasteFormat()));
153     return m_dragDataMap.contains(smartPasteFormat()->cfFormat);
154 }
155 
containsCompatibleContent() const156 bool DragData::containsCompatibleContent() const
157 {
158     return containsPlainText() || containsURL(0)
159         || ((m_platformDragData) ? (containsHTML(m_platformDragData) || containsFilenames(m_platformDragData))
160             : (containsHTML(&m_dragDataMap) || containsFilenames(&m_dragDataMap)))
161         || containsColor();
162 }
163 
asFragment(Frame * frame,PassRefPtr<Range>,bool,bool &) const164 PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const
165 {
166     /*
167      * Order is richest format first. On OSX this is:
168      * * Web Archive
169      * * Filenames
170      * * HTML
171      * * RTF
172      * * TIFF
173      * * PICT
174      */
175 
176     if (m_platformDragData) {
177         if (containsFilenames(m_platformDragData)) {
178             if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(frame->document(), m_platformDragData))
179                 return fragment;
180         }
181 
182         if (containsHTML(m_platformDragData)) {
183             if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(frame->document(), m_platformDragData))
184                 return fragment;
185         }
186     } else {
187         if (containsFilenames(&m_dragDataMap)) {
188             if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(frame->document(), &m_dragDataMap))
189                 return fragment;
190         }
191 
192         if (containsHTML(&m_dragDataMap)) {
193             if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(frame->document(), &m_dragDataMap))
194                 return fragment;
195         }
196     }
197     return 0;
198 }
199 
asColor() const200 Color DragData::asColor() const
201 {
202     return Color();
203 }
204 
205 }
206