/* * Copyright (C) 2007-2020 Apple Inc. All rights reserved. * Copyright (C) 2012 Baidu Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "DragData.h" #include "COMPtr.h" #include "ClipboardUtilitiesWin.h" #include "TextEncoding.h" #include #include #include #include #include #include #include namespace WebCore { DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet sourceOperationMask, OptionSet flags, std::optional pageID) : m_clientPosition(clientPosition) , m_globalPosition(globalPosition) , m_platformDragData(0) , m_draggingSourceOperationMask(sourceOperationMask) , m_applicationFlags(flags) , m_pageID(pageID) , m_dragDataMap(data) { } bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const { if (m_platformDragData) return SUCCEEDED(m_platformDragData->QueryGetData(urlWFormat())) || SUCCEEDED(m_platformDragData->QueryGetData(urlFormat())) || (filenamePolicy == ConvertFilenames && (SUCCEEDED(m_platformDragData->QueryGetData(filenameWFormat())) || SUCCEEDED(m_platformDragData->QueryGetData(filenameFormat())))); return m_dragDataMap.contains(urlWFormat()->cfFormat) || m_dragDataMap.contains(urlFormat()->cfFormat) || (filenamePolicy == ConvertFilenames && (m_dragDataMap.contains(filenameWFormat()->cfFormat) || m_dragDataMap.contains(filenameFormat()->cfFormat))); } const DragDataMap& DragData::dragDataMap() { if (!m_dragDataMap.isEmpty() || !m_platformDragData) return m_dragDataMap; // Enumerate clipboard content and load it in the map. COMPtr itr; if (FAILED(m_platformDragData->EnumFormatEtc(DATADIR_GET, &itr)) || !itr) return m_dragDataMap; FORMATETC dataFormat; while (itr->Next(1, &dataFormat, 0) == S_OK) { Vector dataStrings; getClipboardData(m_platformDragData, &dataFormat, dataStrings); if (!dataStrings.isEmpty()) m_dragDataMap.set(dataFormat.cfFormat, dataStrings); } return m_dragDataMap; } void DragData::getDragFileDescriptorData(int& size, String& pathname) { size = 0; if (m_platformDragData) getFileDescriptorData(m_platformDragData, size, pathname); } void DragData::getDragFileContentData(int size, void* dataBlob) { if (m_platformDragData) getFileContentData(m_platformDragData, size, dataBlob); } String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const { return (m_platformDragData) ? getURL(m_platformDragData, filenamePolicy, title) : getURL(&m_dragDataMap, filenamePolicy, title); } bool DragData::containsFiles() const { #if USE(CF) return (m_platformDragData) ? SUCCEEDED(m_platformDragData->QueryGetData(cfHDropFormat())) : m_dragDataMap.contains(cfHDropFormat()->cfFormat); #else return false; #endif } unsigned DragData::numberOfFiles() const { #if USE(CF) if (!m_platformDragData) return 0; STGMEDIUM medium; if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium))) return 0; HDROP hdrop = static_cast(GlobalLock(medium.hGlobal)); if (!hdrop) return 0; unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0); DragFinish(hdrop); GlobalUnlock(medium.hGlobal); return numFiles; #else return 0; #endif } Vector DragData::asFilenames() const { Vector result; #if USE(CF) if (m_platformDragData) { WCHAR filename[MAX_PATH]; STGMEDIUM medium; if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium))) return result; HDROP hdrop = reinterpret_cast(GlobalLock(medium.hGlobal)); if (!hdrop) return result; const unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0); for (unsigned i = 0; i < numFiles; i++) { if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename))) continue; result.append(filename); } // Free up memory from drag DragFinish(hdrop); GlobalUnlock(medium.hGlobal); return result; } result = m_dragDataMap.get(cfHDropFormat()->cfFormat); #endif return result; } bool DragData::containsPlainText() const { if (m_platformDragData) return SUCCEEDED(m_platformDragData->QueryGetData(plainTextWFormat())) || SUCCEEDED(m_platformDragData->QueryGetData(plainTextFormat())); return m_dragDataMap.contains(plainTextWFormat()->cfFormat) || m_dragDataMap.contains(plainTextFormat()->cfFormat); } String DragData::asPlainText() const { return (m_platformDragData) ? getPlainText(m_platformDragData) : getPlainText(&m_dragDataMap); } bool DragData::containsColor() const { return false; } bool DragData::canSmartReplace() const { if (m_platformDragData) return SUCCEEDED(m_platformDragData->QueryGetData(smartPasteFormat())); return m_dragDataMap.contains(smartPasteFormat()->cfFormat); } bool DragData::containsCompatibleContent(DraggingPurpose) const { return containsPlainText() || containsURL() || ((m_platformDragData) ? (containsHTML(m_platformDragData) || containsFilenames(m_platformDragData)) : (containsHTML(&m_dragDataMap) || containsFilenames(&m_dragDataMap))) || containsColor(); } Color DragData::asColor() const { return Color(); } }