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

📄 webframe.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* * 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 "WebFrame.h"#include "CFDictionaryPropertyBag.h"#include "COMPtr.h"#include "COMPropertyBag.h"#include "DefaultPolicyDelegate.h"#include "DOMCoreClasses.h"#include "HTMLFrameOwnerElement.h"#include "MarshallingHelpers.h"#include "WebActionPropertyBag.h"#include "WebChromeClient.h"#include "WebDocumentLoader.h"#include "WebDownload.h"#include "WebError.h"#include "WebMutableURLRequest.h"#include "WebEditorClient.h"#include "WebFramePolicyListener.h"#include "WebHistory.h"#include "WebIconFetcher.h"#include "WebKit.h"#include "WebKitStatisticsPrivate.h"#include "WebNotificationCenter.h"#include "WebView.h"#include "WebDataSource.h"#include "WebHistoryItem.h"#include "WebURLResponse.h"#pragma warning( push, 0 )#include <WebCore/BString.h>#include <WebCore/Cache.h>#include <WebCore/Document.h>#include <WebCore/DocumentLoader.h>#include <WebCore/DOMImplementation.h>#include <WebCore/DOMWindow.h>#include <WebCore/Event.h>#include <WebCore/EventHandler.h>#include <WebCore/FormState.h>#include <WebCore/FrameLoader.h>#include <WebCore/FrameLoadRequest.h>#include <WebCore/FrameTree.h>#include <WebCore/FrameView.h>#include <WebCore/FrameWin.h>#include <WebCore/GDIObjectCounter.h>#include <WebCore/GraphicsContext.h>#include <WebCore/HistoryItem.h>#include <WebCore/HTMLAppletElement.h>#include <WebCore/HTMLFormElement.h>#include <WebCore/HTMLFormControlElement.h>#include <WebCore/HTMLInputElement.h>#include <WebCore/HTMLNames.h>#include <WebCore/HTMLPlugInElement.h>#include <WebCore/JSDOMWindow.h>#include <WebCore/KeyboardEvent.h>#include <WebCore/MIMETypeRegistry.h>#include <WebCore/MouseRelatedEvent.h>#include <WebCore/NotImplemented.h>#include <WebCore/Page.h>#include <WebCore/PlatformKeyboardEvent.h>#include <WebCore/PluginInfoStore.h>#include <WebCore/PluginDatabase.h>#include <WebCore/PluginView.h>#include <WebCore/ResourceHandle.h>#include <WebCore/ResourceHandleWin.h>#include <WebCore/ResourceRequest.h>#include <WebCore/RenderView.h>#include <WebCore/RenderTreeAsText.h>#include <WebCore/Settings.h>#include <WebCore/TextIterator.h>#include <WebCore/JSDOMBinding.h>#include <WebCore/ScriptController.h>#include <JavaScriptCore/APICast.h>#include <wtf/MathExtras.h>#pragma warning(pop)#include <CoreGraphics/CoreGraphics.h>// CG SPI used for printingextern "C" {    CGAffineTransform CGContextGetBaseCTM(CGContextRef c);     void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m); }using namespace WebCore;using namespace HTMLNames;#define FLASH_REDRAW 0// By imaging to a width a little wider than the available pixels,// thin pages will be scaled down a little, matching the way they// print in IE and Camino. This lets them use fewer sheets than they// would otherwise, which is presumably why other browsers do this.// Wide pages will be scaled down more than this.const float PrintingMinimumShrinkFactor = 1.25f;// This number determines how small we are willing to reduce the page content// in order to accommodate the widest line. If the page would have to be// reduced smaller to make the widest line fit, we just clip instead (this// behavior matches MacIE and Mozilla, at least)const float PrintingMaximumShrinkFactor = 2.0f;//-----------------------------------------------------------------------------// Helpers to convert from WebCore to WebKit typeWebFrame* kit(Frame* frame){    if (!frame)        return 0;    FrameLoaderClient* frameLoaderClient = frame->loader()->client();    if (frameLoaderClient)        return static_cast<WebFrame*>(frameLoaderClient);  // eek, is there a better way than static cast?    return 0;}Frame* core(WebFrame* webFrame){    if (!webFrame)        return 0;    return webFrame->impl();}// This function is not in WebFrame.h because we don't want to advertise the ability to get a non-const Frame from a const WebFrameFrame* core(const WebFrame* webFrame){    if (!webFrame)        return 0;    return const_cast<WebFrame*>(webFrame)->impl();}//-----------------------------------------------------------------------------static Element *elementFromDOMElement(IDOMElement *element){    if (!element)        return 0;    COMPtr<IDOMElementPrivate> elePriv;    HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);    if (SUCCEEDED(hr)) {        Element* ele;        hr = elePriv->coreElement((void**)&ele);        if (SUCCEEDED(hr))            return ele;    }    return 0;}static HTMLFormElement *formElementFromDOMElement(IDOMElement *element){    if (!element)        return 0;    IDOMElementPrivate* elePriv;    HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);    if (SUCCEEDED(hr)) {        Element* ele;        hr = elePriv->coreElement((void**)&ele);        elePriv->Release();        if (SUCCEEDED(hr) && ele && ele->hasTagName(formTag))            return static_cast<HTMLFormElement*>(ele);    }    return 0;}static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element){    if (!element)        return 0;    IDOMElementPrivate* elePriv;    HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);    if (SUCCEEDED(hr)) {        Element* ele;        hr = elePriv->coreElement((void**)&ele);        elePriv->Release();        if (SUCCEEDED(hr) && ele && ele->hasTagName(inputTag))            return static_cast<HTMLInputElement*>(ele);    }    return 0;}// WebFramePrivate ------------------------------------------------------------class WebFrame::WebFramePrivate {public:    WebFramePrivate()         : frame(0)        , webView(0)        , m_policyFunction(0)    {     }    ~WebFramePrivate() { }    FrameView* frameView() { return frame ? frame->view() : 0; }    Frame* frame;    WebView* webView;    FramePolicyFunction m_policyFunction;    COMPtr<WebFramePolicyListener> m_policyListener;};// WebFrame ----------------------------------------------------------------WebFrame::WebFrame()    : WebFrameLoaderClient(this)    , m_refCount(0)    , d(new WebFrame::WebFramePrivate)    , m_quickRedirectComing(false)    , m_inPrintingMode(false)    , m_pageHeight(0){    WebFrameCount++;    gClassCount++;    gClassNameCount.add("WebFrame");}WebFrame::~WebFrame(){    delete d;    WebFrameCount--;    gClassCount--;    gClassNameCount.remove("WebFrame");}WebFrame* WebFrame::createInstance(){    WebFrame* instance = new WebFrame();    instance->AddRef();    return instance;}HRESULT STDMETHODCALLTYPE WebFrame::setAllowsScrolling(    /* [in] */ BOOL flag){    if (Frame* frame = core(this))        if (FrameView* view = frame->view())            view->setCanHaveScrollbars(!!flag);    return S_OK;}HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling(    /* [retval][out] */ BOOL *flag){    if (flag)        if (Frame* frame = core(this))            if (FrameView* view = frame->view())                *flag = view->canHaveScrollbars();    return S_OK;}HRESULT STDMETHODCALLTYPE WebFrame::setIsDisconnected(    /* [in] */ BOOL flag){    if (Frame* frame = core(this)) {        frame->setIsDisconnected(flag);        return S_OK;    }    return E_FAIL;}HRESULT STDMETHODCALLTYPE WebFrame::setExcludeFromTextSearch(    /* [in] */ BOOL flag){    if (Frame* frame = core(this)) {        frame->setExcludeFromTextSearch(flag);        return S_OK;    }    return E_FAIL;}HRESULT STDMETHODCALLTYPE WebFrame::paintDocumentRectToContext(    /* [in] */ RECT rect,    /* [in] */ OLE_HANDLE deviceContext){    Frame* coreFrame = core(this);    if (!coreFrame)        return E_FAIL;    FrameView* view = coreFrame->view();    if (!view)        return E_FAIL;    // We can't paint with a layout still pending.    view->layoutIfNeededRecursive();    HDC dc = (HDC)(ULONG64)deviceContext;    GraphicsContext gc(dc);    gc.setShouldIncludeChildWindows(true);    gc.save();    LONG width = rect.right - rect.left;    LONG height = rect.bottom - rect.top;    FloatRect dirtyRect;    dirtyRect.setWidth(width);    dirtyRect.setHeight(height);    gc.clip(dirtyRect);    gc.translate(-rect.left, -rect.top);    view->paintContents(&gc, rect);    gc.restore();    return S_OK;}// IUnknown -------------------------------------------------------------------HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject){    *ppvObject = 0;    if (IsEqualGUID(riid, __uuidof(WebFrame)))        *ppvObject = this;    else if (IsEqualGUID(riid, IID_IUnknown))        *ppvObject = static_cast<IWebFrame*>(this);    else if (IsEqualGUID(riid, IID_IWebFrame))        *ppvObject = static_cast<IWebFrame*>(this);    else if (IsEqualGUID(riid, IID_IWebFramePrivate))        *ppvObject = static_cast<IWebFramePrivate*>(this);    else if (IsEqualGUID(riid, IID_IWebDocumentText))        *ppvObject = static_cast<IWebDocumentText*>(this);    else        return E_NOINTERFACE;    AddRef();    return S_OK;}ULONG STDMETHODCALLTYPE WebFrame::AddRef(void){    return ++m_refCount;}ULONG STDMETHODCALLTYPE WebFrame::Release(void){    ULONG newRef = --m_refCount;    if (!newRef)        delete(this);    return newRef;}// IWebFrame -------------------------------------------------------------------HRESULT STDMETHODCALLTYPE WebFrame::name(     /* [retval][out] */ BSTR* frameName){    if (!frameName) {        ASSERT_NOT_REACHED();        return E_POINTER;    }    *frameName = 0;    Frame* coreFrame = core(this);    if (!coreFrame)        return E_FAIL;    *frameName = BString(coreFrame->tree()->name()).release();    return S_OK;}HRESULT STDMETHODCALLTYPE WebFrame::webView(     /* [retval][out] */ IWebView** view){    *view = 0;    if (!d->webView)        return E_FAIL;    *view = d->webView;    (*view)->AddRef();    return S_OK;}HRESULT STDMETHODCALLTYPE WebFrame::frameView(    /* [retval][out] */ IWebFrameView** /*view*/){    ASSERT_NOT_REACHED();    return E_NOTIMPL;}HRESULT STDMETHODCALLTYPE WebFrame::DOMDocument(     /* [retval][out] */ IDOMDocument** result){    if (!result) {        ASSERT_NOT_REACHED();        return E_POINTER;    }    *result = 0;    if (Frame* coreFrame = core(this))        if (Document* document = coreFrame->document())            *result = DOMDocument::createInstance(document);    return *result ? S_OK : E_FAIL;}HRESULT STDMETHODCALLTYPE WebFrame::frameElement(     /* [retval][out] */ IDOMHTMLElement** frameElement){    if (!frameElement)        return E_POINTER;    *frameElement = 0;    Frame* coreFrame = core(this);    if (!coreFrame)        return E_FAIL;    COMPtr<IDOMElement> domElement(AdoptCOM, DOMElement::createInstance(coreFrame->ownerElement()));    COMPtr<IDOMHTMLElement> htmlElement(Query, domElement);    if (!htmlElement)        return E_FAIL;    return htmlElement.copyRefTo(frameElement);}HRESULT STDMETHODCALLTYPE WebFrame::currentForm(         /* [retval][out] */ IDOMElement **currentForm){    if (!currentForm) {        ASSERT_NOT_REACHED();        return E_POINTER;    }    *currentForm = 0;    if (Frame* coreFrame = core(this))        if (HTMLFormElement* formElement = coreFrame->currentForm())            *currentForm = DOMElement::createInstance(formElement);    return *currentForm ? S_OK : E_FAIL;}JSGlobalContextRef STDMETHODCALLTYPE WebFrame::globalContext(){    Frame* coreFrame = core(this);    if (!coreFrame)        return 0;    return toGlobalRef(coreFrame->script()->globalObject()->globalExec());}HRESULT STDMETHODCALLTYPE WebFrame::loadRequest(     /* [in] */ IWebURLRequest* request){    COMPtr<WebMutableURLRequest> requestImpl;    HRESULT hr = request->QueryInterface(&requestImpl);    if (FAILED(hr))        return hr;     Frame* coreFrame = core(this);    if (!coreFrame)        return E_FAIL;    coreFrame->loader()->load(requestImpl->resourceRequest(), false);    return S_OK;}void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL){    String mimeTypeString(mimeType, SysStringLen(mimeType));    if (!mimeType)        mimeTypeString = "text/html";    String encodingString(textEncodingName, SysStringLen(textEncodingName));    // FIXME: We should really be using MarshallingHelpers::BSTRToKURL here,    // but that would turn a null BSTR into a null KURL, and we crash inside of    // WebCore if we use a null KURL in constructing the ResourceRequest.    KURL baseKURL = KURL(KURL(), String(baseURL ? baseURL : L"", SysStringLen(baseURL)));    KURL failingKURL = MarshallingHelpers::BSTRToKURL(failingURL);    ResourceRequest request(baseKURL);    SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL);    // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.    if (Frame* coreFrame = core(this))        coreFrame->loader()->load(request, substituteData, false);}HRESULT STDMETHODCALLTYPE WebFrame::loadData(     /* [in] */ IStream* data,    /* [in] */ BSTR mimeType,    /* [in] */ BSTR textEncodingName,    /* [in] */ BSTR url){    RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create();    STATSTG stat;    if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {        if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {            Vector<char> dataBuffer(stat.cbSize.LowPart);            ULONG read;            // FIXME: this does a needless copy, would be better to read right into the SharedBuffer            // or adopt the Vector or something.            if (SUCCEEDED(data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read)))                sharedBuffer->append(dataBuffer.data(), static_cast<int>(dataBuffer.size()));        }    }    loadData(sharedBuffer, mimeType, textEncodingName, url, 0);    return S_OK;

⌨️ 快捷键说明

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