diff options
Diffstat (limited to 'webkit/port/platform/win/ClipboardWin.cpp')
-rw-r--r-- | webkit/port/platform/win/ClipboardWin.cpp | 808 |
1 files changed, 0 insertions, 808 deletions
diff --git a/webkit/port/platform/win/ClipboardWin.cpp b/webkit/port/platform/win/ClipboardWin.cpp deleted file mode 100644 index 0383610..0000000 --- a/webkit/port/platform/win/ClipboardWin.cpp +++ /dev/null @@ -1,808 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple 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 COMPUTER, 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 COMPUTER, 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 <shlwapi.h> -#include <wininet.h> - -#pragma warning(push, 0) -#include "ClipboardWin.h" -#include "CachedImage.h" -#include "ClipboardUtilitiesWin.h" -#include "csshelper.h" -#include "CString.h" -#include "Document.h" -#include "DragData.h" -#include "Editor.h" -#include "Element.h" -#include "EventHandler.h" -#include "Frame.h" -#include "FrameLoader.h" -#include "FrameView.h" -#include "HTMLNames.h" -#include "Image.h" -#include "MIMETypeRegistry.h" -#include "markup.h" -#include "Page.h" -#include "Pasteboard.h" -#include "PlatformMouseEvent.h" -#include "PlatformString.h" -#include "Range.h" -#include "RenderImage.h" -#include "ResourceResponse.h" -#include "StringBuilder.h" -#include "StringHash.h" -#include "WCDataObject.h" -#include <wtf/RefPtr.h> -#pragma warning(pop) - -#undef LOG -#include "base/clipboard_util.h" -#include "base/string_util.h" -#include "googleurl/src/gurl.h" -#include "webkit/glue/glue_util.h" -#include "webkit/glue/webkit_glue.h" - -namespace WebCore { - -using namespace HTMLNames; - -// format string for -static const char szShellDotUrlTemplate[] = "[InternetShortcut]\r\nURL=%s\r\n"; - -// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft -// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3 - -enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardDataTypeText }; - -static ClipboardDataType clipboardTypeFromMIMEType(const String& type) -{ - String qType = type.stripWhiteSpace().lower(); - - // two special cases for IE compatibility - if (qType == "text" || qType == "text/plain" || qType.startsWith("text/plain;")) - return ClipboardDataTypeText; - if (qType == "url" || qType == "text/uri-list") - return ClipboardDataTypeURL; - - return ClipboardDataTypeNone; -} - -static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length) -{ - size_t writeTo = 0; - size_t readFrom = 0; - while (readFrom < length) { - UINT type = PathGetCharType(psz[readFrom]); - if (psz[readFrom] == 0 || type & (GCT_LFNCHAR | GCT_SHORTCHAR)) { - psz[writeTo++] = psz[readFrom]; - } - - readFrom++; - } - psz[writeTo] = 0; -} - -static String filesystemPathFromUrlOrTitle(const String& url, const String& title, TCHAR* extension, bool isLink) -{ - bool usedURL = false; - WCHAR fsPathBuffer[MAX_PATH]; - fsPathBuffer[0] = 0; - int extensionLen = extension ? min(MAX_PATH - 1, lstrlen(extension)) : 0; - String extensionString = extension ? String(extension, extensionLen) : String(L""); - - // We make the filename based on the title only if there's an extension. - if (!title.isEmpty() && extension) { - size_t len = min<size_t>(title.length(), MAX_PATH - extensionLen - 1); - CopyMemory(fsPathBuffer, title.characters(), len * sizeof(UChar)); - fsPathBuffer[len] = 0; - pathRemoveBadFSCharacters(fsPathBuffer, len); - } - - if (!lstrlen(fsPathBuffer)) { - DWORD len = MAX_PATH - 1; - String nullTermURL = url; - usedURL = true; - if (UrlIsFileUrl((LPCWSTR)nullTermURL.charactersWithNullTermination()) - && SUCCEEDED(PathCreateFromUrl((LPCWSTR)nullTermURL.charactersWithNullTermination(), fsPathBuffer, &len, 0))) { - // When linking to a file URL we can trivially find the file name - PWSTR fn = PathFindFileName(fsPathBuffer); - if (fn && fn != fsPathBuffer) - lstrcpyn(fsPathBuffer, fn, lstrlen(fn) + 1); - } else { - // The filename for any content based drag should be the last element of - // the path. If we can't find it, or we're coming up with the name for a link - // we just use the entire url. - KURL kurl(url); - String lastComponent; - if (!isLink && !(lastComponent = kurl.lastPathComponent()).isEmpty()) { - len = min<DWORD>(MAX_PATH - 1, lastComponent.length()); - CopyMemory(fsPathBuffer, lastComponent.characters(), len * sizeof(UChar)); - } else { - len = min<DWORD>(MAX_PATH - 1, nullTermURL.length()); - CopyMemory(fsPathBuffer, nullTermURL.characters(), len * sizeof(UChar)); - } - fsPathBuffer[len] = 0; - pathRemoveBadFSCharacters(fsPathBuffer, len); - } - } - - if (!extension) - return String((UChar*)fsPathBuffer); - - if (!isLink && usedURL) { - PathRenameExtension(fsPathBuffer, extensionString.charactersWithNullTermination()); - return String((UChar*)fsPathBuffer); - } - - String result((UChar*)fsPathBuffer); - result += extensionString; - return result.length() >= MAX_PATH ? result.substring(0, MAX_PATH - 1) : result; -} - -static HGLOBAL createGlobalURLContent(const String& url, int estimatedFileSize) -{ - HRESULT hr = S_OK; - HGLOBAL memObj = 0; - - char* fileContents; - char ansiUrl[INTERNET_MAX_URL_LENGTH + 1]; - // Used to generate the buffer. This is null terminated whereas the fileContents won't be. - char contentGenerationBuffer[INTERNET_MAX_URL_LENGTH + ARRAYSIZE(szShellDotUrlTemplate) + 1]; - - if (estimatedFileSize > 0 && estimatedFileSize > ARRAYSIZE(contentGenerationBuffer)) - return 0; - - int ansiUrlSize = ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)url.characters(), url.length(), ansiUrl, ARRAYSIZE(ansiUrl) - 1, 0, 0); - if (!ansiUrlSize) - return 0; - - ansiUrl[ansiUrlSize] = 0; - - int fileSize = (int) (ansiUrlSize+strlen(szShellDotUrlTemplate)-2); // -2 to remove the %s - ASSERT(estimatedFileSize < 0 || fileSize == estimatedFileSize); - - memObj = GlobalAlloc(GPTR, fileSize); - if (!memObj) - return 0; - - fileContents = (PSTR)GlobalLock(memObj); - - sprintf_s(contentGenerationBuffer, ARRAYSIZE(contentGenerationBuffer), szShellDotUrlTemplate, ansiUrl); - CopyMemory(fileContents, contentGenerationBuffer, fileSize); - - GlobalUnlock(memObj); - - return memObj; -} - -static HGLOBAL createGlobalImageFileContent(SharedBuffer* data) -{ - HGLOBAL memObj = GlobalAlloc(GPTR, data->size()); - if (!memObj) - return 0; - - char* fileContents = (PSTR)GlobalLock(memObj); - - CopyMemory(fileContents, data->data(), data->size()); - - GlobalUnlock(memObj); - - return memObj; -} - -static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, SharedBuffer* data) -{ - if (fileName.isEmpty() || !data ) - return 0; - - WCHAR filePath[MAX_PATH]; - - if (url.isLocalFile()) { - String localPath = url.path(); - // windows does not enjoy a leading slash on paths - if (localPath[0] == '/') - localPath = localPath.substring(1); - LPCTSTR localPathStr = localPath.charactersWithNullTermination(); - if (wcslen(localPathStr) + 1 < MAX_PATH) - wcscpy_s(filePath, MAX_PATH, localPathStr); - else - return 0; - } else { - WCHAR tempPath[MAX_PATH]; - WCHAR extension[MAX_PATH]; - if (!::GetTempPath(ARRAYSIZE(tempPath), tempPath)) - return 0; - if (!::PathAppend(tempPath, fileName.charactersWithNullTermination())) - return 0; - LPCWSTR foundExtension = ::PathFindExtension(tempPath); - if (foundExtension) { - if (wcscpy_s(extension, MAX_PATH, foundExtension)) - return 0; - } else - *extension = 0; - ::PathRemoveExtension(tempPath); - for (int i = 1; i < 10000; i++) { - if (swprintf_s(filePath, MAX_PATH, TEXT("%s-%d%s"), tempPath, i, extension) == -1) - return 0; - if (!::PathFileExists(filePath)) - break; - } - HANDLE tempFileHandle = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - if (tempFileHandle == INVALID_HANDLE_VALUE) - return 0; - - // Write the data to this temp file. - DWORD written; - BOOL tempWriteSucceeded = WriteFile(tempFileHandle, data->data(), data->size(), &written, 0); - CloseHandle(tempFileHandle); - if (!tempWriteSucceeded) - return 0; - } - - SIZE_T dropFilesSize = sizeof(DROPFILES) + (sizeof(WCHAR) * (wcslen(filePath) + 2)); - HGLOBAL memObj = GlobalAlloc(GHND | GMEM_SHARE, dropFilesSize); - if (!memObj) - return 0; - - DROPFILES* dropFiles = (DROPFILES*) GlobalLock(memObj); - dropFiles->pFiles = sizeof(DROPFILES); - dropFiles->fWide = TRUE; - wcscpy((LPWSTR)(dropFiles + 1), filePath); - GlobalUnlock(memObj); - - return memObj; -} - -static HGLOBAL createGlobalUrlFileDescriptor(const String& url, const String& title, int& /*out*/ estimatedSize) -{ - HRESULT hr = S_OK; - HGLOBAL memObj = 0; - String fsPath; - memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR)); - if (!memObj) - return 0; - - FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj); - memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR)); - fgd->cItems = 1; - fgd->fgd[0].dwFlags = FD_FILESIZE; - int fileSize = ::WideCharToMultiByte(CP_ACP, 0, url.characters(), url.length(), 0, 0, 0, 0); - fileSize += strlen(szShellDotUrlTemplate) - 2; // -2 is for getting rid of %s in the template string - fgd->fgd[0].nFileSizeLow = fileSize; - estimatedSize = fileSize; - fsPath = filesystemPathFromUrlOrTitle(url, title, L".URL", true); - - if (fsPath.length() <= 0) { - GlobalUnlock(memObj); - GlobalFree(memObj); - return 0; - } - - int maxSize = min(fsPath.length(), ARRAYSIZE(fgd->fgd[0].cFileName)); - CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar)); - GlobalUnlock(memObj); - - return memObj; -} - - -static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& title, CachedImage* image) -{ - ASSERT_ARG(image, image); - ASSERT(image->image()->data()); - - HRESULT hr = S_OK; - HGLOBAL memObj = 0; - String fsPath; - memObj = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR)); - if (!memObj) - return 0; - - FILEGROUPDESCRIPTOR* fgd = (FILEGROUPDESCRIPTOR*)GlobalLock(memObj); - memset(fgd, 0, sizeof(FILEGROUPDESCRIPTOR)); - fgd->cItems = 1; - fgd->fgd[0].dwFlags = FD_FILESIZE; - fgd->fgd[0].nFileSizeLow = image->image()->data()->size(); - - String extension("."); - extension += WebCore::MIMETypeRegistry::getPreferredExtensionForMIMEType(image->response().mimeType()); - const String& preferredTitle = title.isEmpty() ? image->response().suggestedFilename() : title; - fsPath = filesystemPathFromUrlOrTitle(url, preferredTitle, extension.isEmpty() ? 0 : (TCHAR*)extension.charactersWithNullTermination(), false); - - if (fsPath.length() <= 0) { - GlobalUnlock(memObj); - GlobalFree(memObj); - return 0; - } - - int maxSize = min(fsPath.length(), ARRAYSIZE(fgd->fgd[0].cFileName)); - CopyMemory(fgd->fgd[0].cFileName, (LPCWSTR)fsPath.characters(), maxSize * sizeof(UChar)); - GlobalUnlock(memObj); - - return memObj; -} - - -// writeFileToDataObject takes ownership of fileDescriptor and fileContent -static HRESULT writeFileToDataObject(IDataObject* dataObject, HGLOBAL fileDescriptor, HGLOBAL fileContent, HGLOBAL hDropContent) -{ - HRESULT hr = S_OK; - FORMATETC* fe; - STGMEDIUM medium = {0}; - medium.tymed = TYMED_HGLOBAL; - - if (!fileDescriptor || !fileContent) - goto exit; - - // Descriptor - fe = ClipboardUtil::GetFileDescriptorFormat(); - - medium.hGlobal = fileDescriptor; - - if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE))) - goto exit; - - // Contents - fe = ClipboardUtil::GetFileContentFormatZero(); - medium.hGlobal = fileContent; - if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE))) - goto exit; - - // HDROP - if (hDropContent) { - medium.hGlobal = hDropContent; - hr = dataObject->SetData(ClipboardUtil::GetCFHDropFormat(), &medium, TRUE); - } - -exit: - if (FAILED(hr)) { - if (fileDescriptor) - GlobalFree(fileDescriptor); - if (fileContent) - GlobalFree(fileContent); - if (hDropContent) - GlobalFree(hDropContent); - } - return hr; -} - -ClipboardWin::ClipboardWin(bool isForDragging, IDataObject* dataObject, ClipboardAccessPolicy policy) - : Clipboard(policy, isForDragging) - , m_dataObject(dataObject) - , m_writableDataObject(0) -{ -} - -ClipboardWin::ClipboardWin(bool isForDragging, WCDataObject* dataObject, ClipboardAccessPolicy policy) - : Clipboard(policy, isForDragging) - , m_dataObject(dataObject) - , m_writableDataObject(dataObject) -{ -} - -ClipboardWin::~ClipboardWin() -{ -} - -PassRefPtr<ClipboardWin> ClipboardWin::create(bool isForDragging, IDataObject* dataObject, ClipboardAccessPolicy policy) -{ - return adoptRef(new ClipboardWin(isForDragging, dataObject, policy)); -} - -PassRefPtr<ClipboardWin> ClipboardWin::create(bool isForDragging, WCDataObject* dataObject, ClipboardAccessPolicy policy) -{ - return adoptRef(new ClipboardWin(isForDragging, dataObject, policy)); -} - -static bool writeURL(WCDataObject *data, const KURL& url, String title, bool withPlainText, bool withHTML) -{ - ASSERT(data); - - if (url.isEmpty()) - return false; - - if (title.isEmpty()) { - title = url.lastPathComponent(); - if (title.isEmpty()) - title = url.host(); - } - - STGMEDIUM medium = {0}; - medium.tymed = TYMED_HGLOBAL; - - medium.hGlobal = createGlobalData(url, title); - bool success = false; - if (medium.hGlobal && FAILED(data->SetData(ClipboardUtil::GetUrlWFormat(), &medium, TRUE))) - ::GlobalFree(medium.hGlobal); - else - success = true; - - if (withHTML) { - Vector<char> cfhtmlData; - markupToCF_HTML(urlToMarkup(url, title), "", cfhtmlData); - medium.hGlobal = createGlobalData(cfhtmlData); - if (medium.hGlobal && FAILED(data->SetData(htmlFormat(), &medium, TRUE))) - ::GlobalFree(medium.hGlobal); - else - success = true; - } - - if (withPlainText) { - medium.hGlobal = createGlobalData(url.string()); - if (medium.hGlobal && FAILED(data->SetData(ClipboardUtil::GetPlainTextWFormat(), &medium, TRUE))) - ::GlobalFree(medium.hGlobal); - else - success = true; - } - - return success; -} - -void ClipboardWin::clearData(const String& type) -{ - //FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941> - ASSERT(isForDragging()); - if (policy() != ClipboardWritable || !m_writableDataObject) - return; - - ClipboardDataType dataType = clipboardTypeFromMIMEType(type); - - if (dataType == ClipboardDataTypeURL) { - m_writableDataObject->clearData(ClipboardUtil::GetUrlWFormat()->cfFormat); - m_writableDataObject->clearData(ClipboardUtil::GetUrlFormat()->cfFormat); - } - if (dataType == ClipboardDataTypeText) { - m_writableDataObject->clearData(ClipboardUtil::GetPlainTextFormat()->cfFormat); - m_writableDataObject->clearData(ClipboardUtil::GetPlainTextWFormat()->cfFormat); - } - -} - -void ClipboardWin::clearAllData() -{ - //FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941> - ASSERT(isForDragging()); - if (policy() != ClipboardWritable) - return; - - m_writableDataObject = 0; - WCDataObject::createInstance(&m_writableDataObject); - m_dataObject = m_writableDataObject; -} - -String ClipboardWin::getData(const String& type, bool& success) const -{ - success = false; - if (policy() != ClipboardReadable || !m_dataObject) { - return ""; - } - - ClipboardDataType dataType = clipboardTypeFromMIMEType(type); - if (dataType == ClipboardDataTypeText) { - std::wstring text; - if (!isForDragging()) { - // If this isn't for a drag, it's for a cut/paste event handler. - // In this case, we need to use our glue methods to access the - // clipboard contents. - webkit_glue::ClipboardReadText(&text); - if (text.empty()) { - std::string asciiText; - webkit_glue::ClipboardReadAsciiText(&asciiText); - text = ASCIIToWide(asciiText); - } - success = !text.empty(); - } else { - success = ClipboardUtil::GetPlainText(m_dataObject.get(), &text); - } - return webkit_glue::StdWStringToString(text); - } else if (dataType == ClipboardDataTypeURL) { - std::wstring url; - std::wstring title; - success = ClipboardUtil::GetUrl(m_dataObject.get(), &url, &title); - return webkit_glue::StdWStringToString(url); - } - - return ""; -} - -bool ClipboardWin::setData(const String& type, const String& data) -{ - // FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941> - ASSERT(isForDragging()); - if (policy() != ClipboardWritable || !m_writableDataObject) - return false; - - ClipboardDataType winType = clipboardTypeFromMIMEType(type); - - if (winType == ClipboardDataTypeURL) - return WebCore::writeURL(m_writableDataObject.get(), KURL(data), String(), false, true); - - if (winType == ClipboardDataTypeText) { - STGMEDIUM medium = {0}; - medium.tymed = TYMED_HGLOBAL; - medium.hGlobal = createGlobalData(data); - if (!medium.hGlobal) - return false; - - if (FAILED(m_writableDataObject->SetData(ClipboardUtil::GetPlainTextWFormat(), &medium, TRUE))) { - ::GlobalFree(medium.hGlobal); - return false; - } - return true; - } - return false; -} - -static void addMimeTypesForFormat(HashSet<String>& results, FORMATETC& format) -{ - // URL and Text are provided for compatibility with IE's model - if (format.cfFormat == ClipboardUtil::GetUrlFormat()->cfFormat || - format.cfFormat == ClipboardUtil::GetUrlWFormat()->cfFormat) { - results.add("URL"); - results.add("text/uri-list"); - } - - if (format.cfFormat == ClipboardUtil::GetPlainTextWFormat()->cfFormat || - format.cfFormat == ClipboardUtil::GetPlainTextFormat()->cfFormat) { - results.add("Text"); - results.add("text/plain"); - } -} - -// extensions beyond IE's API -HashSet<String> ClipboardWin::types() const -{ - HashSet<String> results; - if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable) - return results; - - if (!m_dataObject) - return results; - - COMPtr<IEnumFORMATETC> itr; - - if (FAILED(m_dataObject->EnumFormatEtc(0, &itr))) - return results; - - if (!itr) - return results; - - FORMATETC data; - - while (SUCCEEDED(itr->Next(1, &data, 0))) { - addMimeTypesForFormat(results, data); - } - - return results; -} - -void ClipboardWin::setDragImage(CachedImage* image, Node *node, const IntPoint &loc) -{ - if (policy() != ClipboardImageWritable && policy() != ClipboardWritable) - return; - - if (m_dragImage) - m_dragImage->removeClient(this); - m_dragImage = image; - if (m_dragImage) - m_dragImage->addClient(this); - - m_dragLoc = loc; - m_dragImageElement = node; -} - -void ClipboardWin::setDragImage(CachedImage* img, const IntPoint &loc) -{ - setDragImage(img, 0, loc); -} - -void ClipboardWin::setDragImageElement(Node *node, const IntPoint &loc) -{ - setDragImage(0, node, loc); -} - -DragImageRef ClipboardWin::createDragImage(IntPoint& loc) const -{ - HBITMAP result = 0; - //FIXME: Need to be able to draw element <rdar://problem/5015942> - if (m_dragImage) { - result = createDragImageFromImage(m_dragImage->image()); - loc = m_dragLoc; - } - return result; -} - -static String imageToMarkup(const String& url, Element* element) -{ - StringBuilder markup; - markup.append("<img src=\""); - markup.append(url); - markup.append("\""); - // Copy over attributes. If we are dragging an image, we expect things like - // the id to be copied as well. - NamedAttrMap* attrs = element->attributes(); - unsigned int length = attrs->length(); - for (unsigned int i = 0; i < length; ++i) { - Attribute* attr = attrs->attributeItem(i); - if (attr->localName() == "src") - continue; - markup.append(" "); - markup.append(attr->localName()); - markup.append("=\""); - String escapedAttr = attr->value(); - escapedAttr.replace("\"", """); - markup.append(escapedAttr); - markup.append("\""); - } - - markup.append("/>"); - return markup.toString(); -} - -static CachedImage* getCachedImage(Element* element) -{ - // Attempt to pull CachedImage from element - ASSERT(element); - RenderObject* renderer = element->renderer(); - if (!renderer || !renderer->isImage()) - return 0; - - RenderImage* image = static_cast<RenderImage*>(renderer); - if (image->cachedImage() && !image->cachedImage()->errorOccurred()) - return image->cachedImage(); - - return 0; -} - -static void writeImageToDataObject(IDataObject* dataObject, Element* element, const KURL& url) -{ - // Shove image data into a DataObject for use as a file - CachedImage* cachedImage = getCachedImage(element); - if (!cachedImage || !cachedImage->image() || !cachedImage->isLoaded()) - return; - - SharedBuffer* imageBuffer = cachedImage->image()->data(); - if (!imageBuffer || !imageBuffer->size()) - return; - - HGLOBAL imageFileDescriptor = createGlobalImageFileDescriptor(url.string(), element->getAttribute(altAttr), cachedImage); - if (!imageFileDescriptor) - return; - - HGLOBAL imageFileContent = createGlobalImageFileContent(imageBuffer); - if (!imageFileContent) { - GlobalFree(imageFileDescriptor); - return; - } - - // When running in the sandbox, it's possible that hDropContent is NULL. - // That's ok, we should keep going anyway. - String fileName = cachedImage->response().suggestedFilename(); - HGLOBAL hDropContent = createGlobalHDropContent(url, fileName, imageBuffer); - - writeFileToDataObject(dataObject, imageFileDescriptor, imageFileContent, hDropContent); -} - -void ClipboardWin::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame) -{ - // Order is important here for Explorer's sake - if (!m_writableDataObject) - return; - WebCore::writeURL(m_writableDataObject.get(), url, title, true, false); - - writeImageToDataObject(m_writableDataObject.get(), element, url); - - AtomicString imageURL = element->getAttribute(srcAttr); - if (imageURL.isEmpty()) - return; - - String fullURL = frame->document()->completeURL(parseURL(imageURL)); - if (fullURL.isEmpty()) - return; - STGMEDIUM medium = {0}; - medium.tymed = TYMED_HGLOBAL; - ExceptionCode ec = 0; - - // Put img tag on the clipboard referencing the image - Vector<char> data; - markupToCF_HTML(imageToMarkup(fullURL, element), "", data); - medium.hGlobal = createGlobalData(data); - if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE))) - ::GlobalFree(medium.hGlobal); -} - -void ClipboardWin::writeURL(const KURL& kurl, const String& titleStr, Frame*) -{ - if (!m_writableDataObject) - return; - WebCore::writeURL(m_writableDataObject.get(), kurl, titleStr, true, true); - - int estimatedSize = 0; - String url = kurl.string(); - - HGLOBAL urlFileDescriptor = createGlobalUrlFileDescriptor(url, titleStr, estimatedSize); - if (!urlFileDescriptor) - return; - HGLOBAL urlFileContent = createGlobalURLContent(url, estimatedSize); - if (!urlFileContent) { - GlobalFree(urlFileDescriptor); - return; - } - writeFileToDataObject(m_writableDataObject.get(), urlFileDescriptor, urlFileContent, 0); -} - -void ClipboardWin::writeRange(Range* selectedRange, Frame* frame) -{ - ASSERT(selectedRange); - if (!m_writableDataObject) - return; - - STGMEDIUM medium = {0}; - medium.tymed = TYMED_HGLOBAL; - ExceptionCode ec = 0; - - Vector<char> data; - markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), - selectedRange->startContainer(ec)->document()->url().string(), data); - medium.hGlobal = createGlobalData(data); - if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE))) - ::GlobalFree(medium.hGlobal); - - String str = frame->selectedText(); - replaceNewlinesWithWindowsStyleNewlines(str); - replaceNBSPWithSpace(str); - medium.hGlobal = createGlobalData(str); - if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE))) - ::GlobalFree(medium.hGlobal); - - medium.hGlobal = 0; - if (frame->editor()->canSmartCopyOrDelete()) - m_writableDataObject->SetData(smartPasteFormat(), &medium, TRUE); -} - -bool ClipboardWin::hasData() -{ - if (!m_dataObject) - return false; - - COMPtr<IEnumFORMATETC> itr; - if (FAILED(m_dataObject->EnumFormatEtc(0, &itr))) - return false; - - if (!itr) - return false; - - FORMATETC data; - - if (SUCCEEDED(itr->Next(1, &data, 0))) { - // There is at least one item in the IDataObject - return true; - } - - return false; -} - -} // namespace WebCore |