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

📄 webhistoryitem.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2006, 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 "WebKitDLL.h"#include "WebHistoryItem.h"#include "COMEnumVariant.h"#include "COMPtr.h"#include "MarshallingHelpers.h"#include "WebKit.h"#pragma warning(push, 0)#include <WebCore/BString.h>#include <WebCore/CString.h>#include <WebCore/HistoryItem.h>#include <WebCore/KURL.h>#pragma warning(pop)#include <wtf/RetainPtr.h>using namespace WebCore;// WebHistoryItem ----------------------------------------------------------------static HashMap<HistoryItem*, WebHistoryItem*>& historyItemWrappers(){    static HashMap<HistoryItem*, WebHistoryItem*> staticHistoryItemWrappers;    return staticHistoryItemWrappers;}WebHistoryItem::WebHistoryItem(PassRefPtr<HistoryItem> historyItem): m_refCount(0), m_historyItem(historyItem){    ASSERT(!historyItemWrappers().contains(m_historyItem.get()));    historyItemWrappers().set(m_historyItem.get(), this);    gClassCount++;    gClassNameCount.add("WebHistoryItem");}WebHistoryItem::~WebHistoryItem(){    ASSERT(historyItemWrappers().contains(m_historyItem.get()));    historyItemWrappers().remove(m_historyItem.get());    gClassCount--;    gClassNameCount.remove("WebHistoryItem");}WebHistoryItem* WebHistoryItem::createInstance(){    WebHistoryItem* instance = new WebHistoryItem(HistoryItem::create());    instance->AddRef();    return instance;}WebHistoryItem* WebHistoryItem::createInstance(PassRefPtr<HistoryItem> historyItem){    WebHistoryItem* instance;    instance = historyItemWrappers().get(historyItem.get());    if (!instance)        instance = new WebHistoryItem(historyItem);    instance->AddRef();    return instance;}// IWebHistoryItemPrivate -----------------------------------------------------static CFStringRef urlKey = CFSTR("");static CFStringRef lastVisitedDateKey = CFSTR("lastVisitedDate");static CFStringRef titleKey = CFSTR("title");static CFStringRef visitCountKey = CFSTR("visitCount");static CFStringRef lastVisitWasFailureKey = CFSTR("lastVisitWasFailure");static CFStringRef lastVisitWasHTTPNonGetKey = CFSTR("lastVisitWasHTTPNonGet");static CFStringRef redirectURLsKey = CFSTR("redirectURLs");static CFStringRef dailyVisitCountKey = CFSTR("D"); // short key to save spacestatic CFStringRef weeklyVisitCountKey = CFSTR("W"); // short key to save spaceHRESULT STDMETHODCALLTYPE WebHistoryItem::initFromDictionaryRepresentation(void* dictionary){    CFDictionaryRef dictionaryRef = (CFDictionaryRef) dictionary;    CFStringRef urlStringRef = (CFStringRef) CFDictionaryGetValue(dictionaryRef, urlKey);    if (urlStringRef && CFGetTypeID(urlStringRef) != CFStringGetTypeID())        return E_FAIL;    CFStringRef lastVisitedRef = (CFStringRef) CFDictionaryGetValue(dictionaryRef, lastVisitedDateKey);    if (!lastVisitedRef || CFGetTypeID(lastVisitedRef) != CFStringGetTypeID())        return E_FAIL;    CFAbsoluteTime lastVisitedTime = CFStringGetDoubleValue(lastVisitedRef);    CFStringRef titleRef = (CFStringRef) CFDictionaryGetValue(dictionaryRef, titleKey);    if (titleRef && CFGetTypeID(titleRef) != CFStringGetTypeID())        return E_FAIL;    CFNumberRef visitCountRef = (CFNumberRef) CFDictionaryGetValue(dictionaryRef, visitCountKey);    if (!visitCountRef || CFGetTypeID(visitCountRef) != CFNumberGetTypeID())        return E_FAIL;    int visitedCount = 0;    if (!CFNumberGetValue(visitCountRef, kCFNumberIntType, &visitedCount))        return E_FAIL;    // Can't trust data on disk, and we've had at least one report of this (<rdar://6572300>).    if (visitedCount < 0) {        LOG_ERROR("visit count for history item \"%s\" is negative (%d), will be reset to 1", String(urlStringRef).utf8().data(), visitedCount);        visitedCount = 1;    }    CFBooleanRef lastVisitWasFailureRef = static_cast<CFBooleanRef>(CFDictionaryGetValue(dictionaryRef, lastVisitWasFailureKey));    if (lastVisitWasFailureRef && CFGetTypeID(lastVisitWasFailureRef) != CFBooleanGetTypeID())        return E_FAIL;    bool lastVisitWasFailure = lastVisitWasFailureRef && CFBooleanGetValue(lastVisitWasFailureRef);    CFBooleanRef lastVisitWasHTTPNonGetRef = static_cast<CFBooleanRef>(CFDictionaryGetValue(dictionaryRef, lastVisitWasHTTPNonGetKey));    if (lastVisitWasHTTPNonGetRef && CFGetTypeID(lastVisitWasHTTPNonGetRef) != CFBooleanGetTypeID())        return E_FAIL;    bool lastVisitWasHTTPNonGet = lastVisitWasHTTPNonGetRef && CFBooleanGetValue(lastVisitWasHTTPNonGetRef);    std::auto_ptr<Vector<String> > redirectURLsVector;    if (CFArrayRef redirectURLsRef = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionaryRef, redirectURLsKey))) {        CFIndex size = CFArrayGetCount(redirectURLsRef);        redirectURLsVector.reset(new Vector<String>(size));        for (CFIndex i = 0; i < size; ++i)            (*redirectURLsVector)[i] = String(static_cast<CFStringRef>(CFArrayGetValueAtIndex(redirectURLsRef, i)));    }    CFArrayRef dailyCounts = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionaryRef, dailyVisitCountKey));    if (dailyCounts && CFGetTypeID(dailyCounts) != CFArrayGetTypeID())        dailyCounts = 0;    CFArrayRef weeklyCounts = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionaryRef, weeklyVisitCountKey));    if (weeklyCounts && CFGetTypeID(weeklyCounts) != CFArrayGetTypeID())        weeklyCounts = 0;    std::auto_ptr<Vector<int> > dailyVector, weeklyVector;    if (dailyCounts || weeklyCounts) {        CFIndex dailySize = dailyCounts ? CFArrayGetCount(dailyCounts) : 0;        CFIndex weeklySize = weeklyCounts ? CFArrayGetCount(weeklyCounts) : 0;        dailyVector.reset(new Vector<int>(dailySize));        weeklyVector.reset(new Vector<int>(weeklySize));        // Daily and weekly counts < 0 are errors in the data read from disk, so reset to 0.        for (CFIndex i = 0; i < dailySize; ++i) {            CFNumberRef dailyCount = static_cast<CFNumberRef>(CFArrayGetValueAtIndex(dailyCounts, i));                    if (CFGetTypeID(dailyCount) == CFNumberGetTypeID())                CFNumberGetValue(dailyCount, kCFNumberIntType, &(*dailyVector)[i]);            if ((*dailyVector)[i] < 0)                (*dailyVector)[i] = 0;        }        for (CFIndex i = 0; i < weeklySize; ++i) {            CFNumberRef weeklyCount = static_cast<CFNumberRef>(CFArrayGetValueAtIndex(weeklyCounts, i));                    if (CFGetTypeID(weeklyCount) == CFNumberGetTypeID())                CFNumberGetValue(weeklyCount, kCFNumberIntType, &(*weeklyVector)[i]);            if ((*weeklyVector)[i] < 0)                (*weeklyVector)[i] = 0;        }    }    historyItemWrappers().remove(m_historyItem.get());    m_historyItem = HistoryItem::create(urlStringRef, titleRef, lastVisitedTime);    historyItemWrappers().set(m_historyItem.get(), this);    m_historyItem->setVisitCount(visitedCount);    if (lastVisitWasFailure)        m_historyItem->setLastVisitWasFailure(true);    if (lastVisitWasHTTPNonGet && (protocolIs(m_historyItem->urlString(), "http") || protocolIs(m_historyItem->urlString(), "https")))        m_historyItem->setLastVisitWasHTTPNonGet(true);    if (redirectURLsVector.get())        m_historyItem->setRedirectURLs(redirectURLsVector);    if (dailyVector.get())        m_historyItem->adoptVisitCounts(*dailyVector, *weeklyVector);    return S_OK;}HRESULT STDMETHODCALLTYPE WebHistoryItem::dictionaryRepresentation(void** dictionary){    CFDictionaryRef* dictionaryRef = (CFDictionaryRef*) dictionary;    static CFStringRef lastVisitedFormat = CFSTR("%.1lf");    CFStringRef lastVisitedStringRef =        CFStringCreateWithFormat(0, 0, lastVisitedFormat, m_historyItem->lastVisitedTime());    if (!lastVisitedStringRef)        return E_FAIL;    int keyCount = 0;    CFTypeRef keys[9];    CFTypeRef values[9];    if (!m_historyItem->urlString().isEmpty()) {        keys[keyCount] = urlKey;        values[keyCount++] = m_historyItem->urlString().createCFString();    }    keys[keyCount] = lastVisitedDateKey;    values[keyCount++] = lastVisitedStringRef;    if (!m_historyItem->title().isEmpty()) {        keys[keyCount] = titleKey;        values[keyCount++] = m_historyItem->title().createCFString();    }    keys[keyCount] = visitCountKey;    int visitCount = m_historyItem->visitCount();    values[keyCount++] = CFNumberCreate(0, kCFNumberIntType, &visitCount);    if (m_historyItem->lastVisitWasFailure()) {        keys[keyCount] = lastVisitWasFailureKey;        values[keyCount++] = CFRetain(kCFBooleanTrue);    }    if (m_historyItem->lastVisitWasHTTPNonGet()) {        ASSERT(m_historyItem->urlString().startsWith("http:", false) || m_historyItem->urlString().startsWith("https:", false));        keys[keyCount] = lastVisitWasHTTPNonGetKey;        values[keyCount++] = CFRetain(kCFBooleanTrue);    }    if (Vector<String>* redirectURLs = m_historyItem->redirectURLs()) {        size_t size = redirectURLs->size();        ASSERT(size);        CFStringRef* items = new CFStringRef[size];        for (size_t i = 0; i < size; ++i)            items[i] = redirectURLs->at(i).createCFString();        CFArrayRef result = CFArrayCreate(0, (const void**)items, size, &kCFTypeArrayCallBacks);        for (size_t i = 0; i < size; ++i)            CFRelease(items[i]);        delete[] items;        keys[keyCount] = redirectURLsKey;        values[keyCount++] = result;    }    const Vector<int>& dailyVisitCount(m_historyItem->dailyVisitCounts());    if (size_t size = dailyVisitCount.size()) {        Vector<CFNumberRef, 13> numbers(size);        for (size_t i = 0; i < size; ++i)            numbers[i] = CFNumberCreate(0, kCFNumberIntType, &dailyVisitCount[i]);        CFArrayRef result = CFArrayCreate(0, (const void**)numbers.data(), size, &kCFTypeArrayCallBacks);        for (size_t i = 0; i < size; ++i)            CFRelease(numbers[i]);        keys[keyCount] = dailyVisitCountKey;        values[keyCount++] = result;    }    const Vector<int>& weeklyVisitCount(m_historyItem->weeklyVisitCounts());    if (size_t size = weeklyVisitCount.size()) {        Vector<CFNumberRef, 5> numbers(size);        for (size_t i = 0; i < size; ++i)            numbers[i] = CFNumberCreate(0, kCFNumberIntType, &weeklyVisitCount[i]);        CFArrayRef result = CFArrayCreate(0, (const void**)numbers.data(), size, &kCFTypeArrayCallBacks);        for (size_t i = 0; i < size; ++i)            CFRelease(numbers[i]);        keys[keyCount] = weeklyVisitCountKey;        values[keyCount++] = result;    }    *dictionaryRef = CFDictionaryCreate(0, keys, values, keyCount, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);        for (int i = 0; i < keyCount; ++i)        CFRelease(values[i]);    return S_OK;}HRESULT STDMETHODCALLTYPE WebHistoryItem::hasURLString(BOOL *hasURL){    *hasURL = m_historyItem->urlString().isEmpty() ? FALSE : TRUE;    return S_OK;}HRESULT STDMETHODCALLTYPE WebHistoryItem::visitCount(int *count){    *count = m_historyItem->visitCount();    return S_OK;}HRESULT STDMETHODCALLTYPE WebHistoryItem::setVisitCount(int count){    m_historyItem->setVisitCount(count);    return S_OK;}HRESULT STDMETHODCALLTYPE WebHistoryItem::mergeAutoCompleteHints(IWebHistoryItem* otherItem){    if (!otherItem)        return E_FAIL;    COMPtr<WebHistoryItem> otherWebHistoryItem(Query, otherItem);    if (!otherWebHistoryItem)        return E_FAIL;    m_historyItem->mergeAutoCompleteHints(otherWebHistoryItem->historyItem());

⌨️ 快捷键说明

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