⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clipboardutilitieswin.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * Copyright (C) 2007, 2008 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 "ClipboardUtilitiesWin.h"#include "CString.h"#include "DocumentFragment.h"#include "KURL.h"#include "PlatformString.h"#include "TextEncoding.h"#include "markup.h"#include <CoreFoundation/CoreFoundation.h>#include <wtf/RetainPtr.h>#include <shlwapi.h>#include <wininet.h>    // for INTERNET_MAX_URL_LENGTHnamespace WebCore {FORMATETC* cfHDropFormat(){    static FORMATETC urlFormat = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &urlFormat;}static bool getWebLocData(IDataObject* dataObject, String& url, String* title) {    bool succeeded = false;    WCHAR filename[MAX_PATH];    WCHAR urlBuffer[INTERNET_MAX_URL_LENGTH];    STGMEDIUM medium;    if (FAILED(dataObject->GetData(cfHDropFormat(), &medium)))        return false;    HDROP hdrop = (HDROP)GlobalLock(medium.hGlobal);       if (!hdrop)        return false;    if (!DragQueryFileW(hdrop, 0, filename, ARRAYSIZE(filename)))        goto exit;    if (_wcsicmp(PathFindExtensionW(filename), L".url"))        goto exit;            if (!GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, urlBuffer, ARRAYSIZE(urlBuffer), filename))        goto exit;        if (title) {        PathRemoveExtension(filename);        *title = String((UChar*)filename);    }        url = String((UChar*)urlBuffer);    succeeded = true;exit:    // Free up memory.    DragFinish(hdrop);    GlobalUnlock(medium.hGlobal);    return succeeded;}static String extractURL(const String &inURL, String* title){    String url = inURL;    int splitLoc = url.find('\n');    if (splitLoc > 0) {        if (title)            *title = url.substring(splitLoc+1);        url.truncate(splitLoc);    } else if (title)        *title = url;    return url;}//Firefox text/htmlstatic FORMATETC* texthtmlFormat() {    static UINT cf = RegisterClipboardFormat(L"text/html");    static FORMATETC texthtmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &texthtmlFormat;}HGLOBAL createGlobalData(const KURL& url, const String& title){    String mutableURL(url.string());    String mutableTitle(title);    SIZE_T size = mutableURL.length() + mutableTitle.length() + 2;  // +1 for "\n" and +1 for null terminator    HGLOBAL cbData = ::GlobalAlloc(GPTR, size * sizeof(UChar));    if (cbData) {        PWSTR buffer = (PWSTR)::GlobalLock(cbData);        swprintf_s(buffer, size, L"%s\n%s", mutableURL.charactersWithNullTermination(), mutableTitle.charactersWithNullTermination());        ::GlobalUnlock(cbData);    }    return cbData;}HGLOBAL createGlobalData(const String& str){    HGLOBAL globalData = ::GlobalAlloc(GPTR, (str.length() + 1) * sizeof(UChar));    if (!globalData)        return 0;    UChar* buffer = static_cast<UChar*>(::GlobalLock(globalData));    memcpy(buffer, str.characters(), str.length() * sizeof(UChar));    buffer[str.length()] = 0;    ::GlobalUnlock(globalData);    return globalData;}HGLOBAL createGlobalData(const Vector<char>& vector){    HGLOBAL globalData = ::GlobalAlloc(GPTR, vector.size() + 1);    if (!globalData)        return 0;    char* buffer = static_cast<char*>(::GlobalLock(globalData));    memcpy(buffer, vector.data(), vector.size());    buffer[vector.size()] = 0;    ::GlobalUnlock(globalData);    return globalData;}static void append(Vector<char>& vector, const char* string){    vector.append(string, strlen(string));}static void append(Vector<char>& vector, const CString& string){    vector.append(string.data(), string.length());}// Documentation for the CF_HTML format is available at http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.aspvoid markupToCF_HTML(const String& markup, const String& srcURL, Vector<char>& result){    if (markup.isEmpty())        return;    #define MAX_DIGITS 10    #define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits)    #define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u"    #define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS)    const char* header = "Version:0.9\n"        "StartHTML:" NUMBER_FORMAT "\n"        "EndHTML:" NUMBER_FORMAT "\n"        "StartFragment:" NUMBER_FORMAT "\n"        "EndFragment:" NUMBER_FORMAT "\n";    const char* sourceURLPrefix = "SourceURL:";    const char* startMarkup = "<HTML>\n<BODY>\n<!--StartFragment-->\n";    const char* endMarkup = "\n<!--EndFragment-->\n</BODY>\n</HTML>";    CString sourceURLUTF8 = srcURL == blankURL() ? "" : srcURL.utf8();    CString markupUTF8 = markup.utf8();    // calculate offsets    unsigned startHTMLOffset = strlen(header) - strlen(NUMBER_FORMAT) * 4 + MAX_DIGITS * 4;    if (sourceURLUTF8.length())        startHTMLOffset += strlen(sourceURLPrefix) + sourceURLUTF8.length() + 1;    unsigned startFragmentOffset = startHTMLOffset + strlen(startMarkup);    unsigned endFragmentOffset = startFragmentOffset + markupUTF8.length();    unsigned endHTMLOffset = endFragmentOffset + strlen(endMarkup);    append(result, String::format(header, startHTMLOffset, endHTMLOffset, startFragmentOffset, endFragmentOffset).utf8());    if (sourceURLUTF8.length()) {        append(result, sourceURLPrefix);        append(result, sourceURLUTF8);        result.append('\n');    }    append(result, startMarkup);    append(result, markupUTF8);    append(result, endMarkup);    #undef MAX_DIGITS    #undef MAKE_NUMBER_FORMAT_1    #undef MAKE_NUMBER_FORMAT_2    #undef NUMBER_FORMAT}String urlToMarkup(const KURL& url, const String& title){    Vector<UChar> markup;    append(markup, "<a href=\"");    append(markup, url.string());    append(markup, "\">");    append(markup, title);    append(markup, "</a>");    return String::adopt(markup);}void replaceNewlinesWithWindowsStyleNewlines(String& str){    static const UChar Newline = '\n';    static const char* const WindowsNewline("\r\n");    str.replace(Newline, WindowsNewline);}void replaceNBSPWithSpace(String& str){    static const UChar NonBreakingSpaceCharacter = 0xA0;    static const UChar SpaceCharacter = ' ';    str.replace(NonBreakingSpaceCharacter, SpaceCharacter);}FORMATETC* urlWFormat(){    static UINT cf = RegisterClipboardFormat(L"UniformResourceLocatorW");    static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &urlFormat;}FORMATETC* urlFormat(){    static UINT cf = RegisterClipboardFormat(L"UniformResourceLocator");    static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &urlFormat;}FORMATETC* plainTextFormat(){    static FORMATETC textFormat = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &textFormat;}FORMATETC* plainTextWFormat(){    static FORMATETC textFormat = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &textFormat;}FORMATETC* filenameWFormat(){    static UINT cf = RegisterClipboardFormat(L"FileNameW");    static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &urlFormat;}FORMATETC* filenameFormat(){    static UINT cf = RegisterClipboardFormat(L"FileName");    static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &urlFormat;}//MSIE HTML FormatFORMATETC* htmlFormat() {    static UINT cf = RegisterClipboardFormat(L"HTML Format");    static FORMATETC htmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &htmlFormat;}FORMATETC* smartPasteFormat(){    static UINT cf = RegisterClipboardFormat(L"WebKit Smart Paste Format");    static FORMATETC htmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};    return &htmlFormat;}static bool urlFromPath(CFStringRef path, String& url){    if (!path)        return false;    RetainPtr<CFURLRef> cfURL(AdoptCF, CFURLCreateWithFileSystemPath(0, path, kCFURLWindowsPathStyle, false));    if (!cfURL)        return false;    url = String(CFURLGetString(cfURL.get()));    return true;}String getURL(IDataObject* dataObject, bool& success, String* title){    STGMEDIUM store;    String url;    success = false;    if (getWebLocData(dataObject, url, title)) {        success = true;        return url;    } else if (SUCCEEDED(dataObject->GetData(urlWFormat(), &store))) {        //URL using unicode        UChar* data = (UChar*)GlobalLock(store.hGlobal);        url = extractURL(String(data), title);        GlobalUnlock(store.hGlobal);              ReleaseStgMedium(&store);        success = true;    } else if (SUCCEEDED(dataObject->GetData(urlFormat(), &store))) {        //URL using ascii        char* data = (char*)GlobalLock(store.hGlobal);        url = extractURL(String(data), title);        GlobalUnlock(store.hGlobal);              ReleaseStgMedium(&store);        success = true;    } else if (SUCCEEDED(dataObject->GetData(filenameWFormat(), &store))) {        //file using unicode        wchar_t* data = (wchar_t*)GlobalLock(store.hGlobal);        if (data && data[0] && (PathFileExists(data) || PathIsUNC(data))) {            RetainPtr<CFStringRef> pathAsCFString(AdoptCF, CFStringCreateWithCharacters(kCFAllocatorDefault, (const UniChar*)data, wcslen(data)));            if (urlFromPath(pathAsCFString.get(), url)) {                if (title)                    *title = url;                success = true;            }        }        GlobalUnlock(store.hGlobal);              ReleaseStgMedium(&store);    } else if (SUCCEEDED(dataObject->GetData(filenameFormat(), &store))) {        //filename using ascii        char* data = (char*)GlobalLock(store.hGlobal);               if (data && data[0] && (PathFileExistsA(data) || PathIsUNCA(data))) {            RetainPtr<CFStringRef> pathAsCFString(AdoptCF, CFStringCreateWithCString(kCFAllocatorDefault, data, kCFStringEncodingASCII));            if (urlFromPath(pathAsCFString.get(), url)) {                if (title)                    *title = url;                success = true;            }        }        GlobalUnlock(store.hGlobal);              ReleaseStgMedium(&store);    }    return url;}String getPlainText(IDataObject* dataObject, bool& success){    STGMEDIUM store;    String text;    success = false;    if (SUCCEEDED(dataObject->GetData(plainTextWFormat(), &store))) {        //unicode text        UChar* data = (UChar*)GlobalLock(store.hGlobal);        text = String(data);        GlobalUnlock(store.hGlobal);              ReleaseStgMedium(&store);        success = true;    } else if (SUCCEEDED(dataObject->GetData(plainTextFormat(), &store))) {        //ascii text        char* data = (char*)GlobalLock(store.hGlobal);        text = String(data);        GlobalUnlock(store.hGlobal);              ReleaseStgMedium(&store);        success = true;    } else {        //If a file is dropped on the window, it does not provide either of the         //plain text formats, so here we try to forcibly get a url.        text = getURL(dataObject, success);        success = true;    }    return text;}PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*){    //FIXME: We should be able to create fragments from files    return 0;}bool containsFilenames(const IDataObject*){    //FIXME: We'll want to update this once we can produce fragments from files    return false;}//Convert a String containing CF_HTML formatted text to a DocumentFragmentPassRefPtr<DocumentFragment> fragmentFromCF_HTML(Document* doc, const String& cf_html){            // obtain baseURL if present    String srcURLStr("sourceURL:");    String srcURL;    unsigned lineStart = cf_html.find(srcURLStr, 0, false);    if (lineStart != -1) {        unsigned srcEnd = cf_html.find("\n", lineStart, false);        unsigned srcStart = lineStart+srcURLStr.length();        String rawSrcURL = cf_html.substring(srcStart, srcEnd-srcStart);        replaceNBSPWithSpace(rawSrcURL);        srcURL = rawSrcURL.stripWhiteSpace();    }    // find the markup between "<!--StartFragment -->" and "<!--EndFragment -->", accounting for browser quirks    unsigned markupStart = cf_html.find("<html", 0, false);    unsigned tagStart = cf_html.find("startfragment", markupStart, false);    unsigned fragmentStart = cf_html.find('>', tagStart) + 1;    unsigned tagEnd = cf_html.find("endfragment", fragmentStart, false);    unsigned fragmentEnd = cf_html.reverseFind('<', tagEnd);    String markup = cf_html.substring(fragmentStart, fragmentEnd - fragmentStart).stripWhiteSpace();    return createFragmentFromMarkup(doc, markup, srcURL);}PassRefPtr<DocumentFragment> fragmentFromHTML(Document* doc, IDataObject* data) {    if (!doc || !data)        return 0;    STGMEDIUM store;    String html;    String srcURL;    if (SUCCEEDED(data->GetData(htmlFormat(), &store))) {        //MS HTML Format parsing        char* data = (char*)GlobalLock(store.hGlobal);        SIZE_T dataSize = ::GlobalSize(store.hGlobal);        String cf_html(UTF8Encoding().decode(data, dataSize));                 GlobalUnlock(store.hGlobal);        ReleaseStgMedium(&store);         if (PassRefPtr<DocumentFragment> fragment = fragmentFromCF_HTML(doc, cf_html))            return fragment;    }     if (SUCCEEDED(data->GetData(texthtmlFormat(), &store))) {        //raw html        UChar* data = (UChar*)GlobalLock(store.hGlobal);        html = String(data);        GlobalUnlock(store.hGlobal);              ReleaseStgMedium(&store);        return createFragmentFromMarkup(doc, html, srcURL);    }     return 0;}bool containsHTML(IDataObject* data){    return SUCCEEDED(data->QueryGetData(texthtmlFormat())) || SUCCEEDED(data->QueryGetData(htmlFormat()));}} // namespace WebCore

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -