webengine/osswebengine/WebKit/win/WebFrame.cpp
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  * 1. Redistributions of source code must retain the above copyright
       
     8  *    notice, this list of conditions and the following disclaimer.
       
     9  * 2. Redistributions in binary form must reproduce the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer in the
       
    11  *    documentation and/or other materials provided with the distribution.
       
    12  *
       
    13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
       
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
       
    17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
       
    21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
       
    24  */
       
    25 
       
    26 #include "config.h"
       
    27 #include "WebKitDLL.h"
       
    28 #include "WebFrame.h"
       
    29 
       
    30 #include "CFDictionaryPropertyBag.h"
       
    31 #include "COMPtr.h"
       
    32 #include "DOMCoreClasses.h"
       
    33 #include "IWebError.h"
       
    34 #include "IWebErrorPrivate.h"
       
    35 #include "IWebHistory.h"
       
    36 #include "IWebHistoryItemPrivate.h"
       
    37 #include "IWebFrameLoadDelegatePrivate.h"
       
    38 #include "IWebFormDelegate.h"
       
    39 #include "IWebUIDelegatePrivate.h"
       
    40 #include "MarshallingHelpers.h"
       
    41 #include "WebActionPropertyBag.h"
       
    42 #include "WebDocumentLoader.h"
       
    43 #include "WebDownload.h"
       
    44 #include "WebError.h"
       
    45 #include "WebMutableURLRequest.h"
       
    46 #include "WebEditorClient.h"
       
    47 #include "WebFramePolicyListener.h"
       
    48 #include "WebHistory.h"
       
    49 #include "WebKit.h"
       
    50 #include "WebKitStatisticsPrivate.h"
       
    51 #include "WebNotificationCenter.h"
       
    52 #include "WebView.h"
       
    53 #include "WebDataSource.h"
       
    54 #include "WebHistoryItem.h"
       
    55 #include "WebURLAuthenticationChallenge.h"
       
    56 #include "WebURLResponse.h"
       
    57 #pragma warning( push, 0 )
       
    58 #include <WebCore/AuthenticationChallenge.h>
       
    59 #include <WebCore/BString.h>
       
    60 #include <WebCore/Cache.h>
       
    61 #include <WebCore/Document.h>
       
    62 #include <WebCore/DocumentLoader.h>
       
    63 #include <WebCore/DOMImplementation.h>
       
    64 #include <WebCore/DOMWindow.h>
       
    65 #include <WebCore/Event.h>
       
    66 #include <WebCore/FormState.h>
       
    67 #include <WebCore/FrameLoader.h>
       
    68 #include <WebCore/FrameLoadRequest.h>
       
    69 #include <WebCore/FrameTree.h>
       
    70 #include <WebCore/FrameView.h>
       
    71 #include <WebCore/FrameWin.h>
       
    72 #include <WebCore/GDIObjectCounter.h>
       
    73 #include <WebCore/GraphicsContext.h>
       
    74 #include <WebCore/HistoryItem.h>
       
    75 #include <WebCore/HTMLFormElement.h>
       
    76 #include <WebCore/HTMLGenericFormElement.h>
       
    77 #include <WebCore/HTMLInputElement.h>
       
    78 #include <WebCore/HTMLNames.h>
       
    79 #include <WebCore/KeyboardEvent.h>
       
    80 #include <WebCore/MIMETypeRegistry.h>
       
    81 #include <WebCore/MouseRelatedEvent.h>
       
    82 #include <WebCore/NotImplemented.h>
       
    83 #include <WebCore/Page.h>
       
    84 #include <WebCore/PlatformKeyboardEvent.h>
       
    85 #include <WebCore/PlugInInfoStore.h>
       
    86 #include <WebCore/PluginDatabaseWin.h>
       
    87 #include <WebCore/PluginViewWin.h>
       
    88 #include <WebCore/ResourceHandle.h>
       
    89 #include <WebCore/ResourceHandleWin.h>
       
    90 #include <WebCore/ResourceRequest.h>
       
    91 #include <WebCore/RenderFrame.h>
       
    92 #include <WebCore/RenderTreeAsText.h>
       
    93 #include <WebCore/Settings.h>
       
    94 #include <WebCore/TextIterator.h>
       
    95 #include <WebCore/kjs_binding.h>
       
    96 #include <WebCore/kjs_proxy.h>
       
    97 #include <WebCore/kjs_window.h>
       
    98 #include <JavaScriptCore/APICast.h>
       
    99 #include <wtf/MathExtras.h>
       
   100 #pragma warning(pop)
       
   101 
       
   102 #include <CoreGraphics/CoreGraphics.h>
       
   103 
       
   104 // CG SPI used for printing
       
   105 extern "C" {
       
   106     CGAffineTransform CGContextGetBaseCTM(CGContextRef c); 
       
   107     void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m); 
       
   108 }
       
   109 
       
   110 using namespace WebCore;
       
   111 using namespace HTMLNames;
       
   112 
       
   113 #define FLASH_REDRAW 0
       
   114 
       
   115 
       
   116 // By imaging to a width a little wider than the available pixels,
       
   117 // thin pages will be scaled down a little, matching the way they
       
   118 // print in IE and Camino. This lets them use fewer sheets than they
       
   119 // would otherwise, which is presumably why other browsers do this.
       
   120 // Wide pages will be scaled down more than this.
       
   121 const float PrintingMinimumShrinkFactor = 1.25f;
       
   122 
       
   123 // This number determines how small we are willing to reduce the page content
       
   124 // in order to accommodate the widest line. If the page would have to be
       
   125 // reduced smaller to make the widest line fit, we just clip instead (this
       
   126 // behavior matches MacIE and Mozilla, at least)
       
   127 const float PrintingMaximumShrinkFactor = 2.0f;
       
   128 
       
   129 
       
   130 // {A3676398-4485-4a9d-87DC-CB5A40E6351D}
       
   131 const GUID IID_WebFrame = 
       
   132 { 0xa3676398, 0x4485, 0x4a9d, { 0x87, 0xdc, 0xcb, 0x5a, 0x40, 0xe6, 0x35, 0x1d } };
       
   133 
       
   134 
       
   135 //-----------------------------------------------------------------------------
       
   136 // Helpers to convert from WebCore to WebKit type
       
   137 WebFrame* kit(Frame* frame)
       
   138 {
       
   139     if (!frame)
       
   140         return 0;
       
   141 
       
   142     FrameLoaderClient* frameLoaderClient = frame->loader()->client();
       
   143     if (frameLoaderClient)
       
   144         return static_cast<WebFrame*>(frameLoaderClient);  // eek, is there a better way than static cast?
       
   145     return 0;
       
   146 }
       
   147 
       
   148 Frame* core(WebFrame* webFrame)
       
   149 {
       
   150     if (!webFrame)
       
   151         return 0;
       
   152     return webFrame->impl();
       
   153 }
       
   154 
       
   155 // 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 WebFrame
       
   156 Frame* core(const WebFrame* webFrame)
       
   157 {
       
   158     if (!webFrame)
       
   159         return 0;
       
   160     return const_cast<WebFrame*>(webFrame)->impl();
       
   161 }
       
   162 
       
   163 //-----------------------------------------------------------------------------
       
   164 
       
   165 class FormValuesPropertyBag : public IPropertyBag, public IPropertyBag2
       
   166 {
       
   167 public:
       
   168     FormValuesPropertyBag(HashMap<String, String>* formValues) : m_formValues(formValues) {}
       
   169 
       
   170     // IUnknown
       
   171     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
       
   172     virtual ULONG STDMETHODCALLTYPE AddRef(void);
       
   173     virtual ULONG STDMETHODCALLTYPE Release(void);
       
   174 
       
   175     // IPropertyBag
       
   176     virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read( 
       
   177         /* [in] */ LPCOLESTR pszPropName,
       
   178         /* [out][in] */ VARIANT* pVar,
       
   179         /* [in] */ IErrorLog* pErrorLog);
       
   180 
       
   181     virtual HRESULT STDMETHODCALLTYPE Write( 
       
   182         /* [in] */ LPCOLESTR pszPropName,
       
   183         /* [in] */ VARIANT* pVar);
       
   184 
       
   185     // IPropertyBag2
       
   186     virtual HRESULT STDMETHODCALLTYPE Read( 
       
   187         /* [in] */ ULONG cProperties,
       
   188         /* [in] */ PROPBAG2 *pPropBag,
       
   189         /* [in] */ IErrorLog *pErrLog,
       
   190         /* [out] */ VARIANT *pvarValue,
       
   191         /* [out] */ HRESULT *phrError);
       
   192     
       
   193     virtual HRESULT STDMETHODCALLTYPE Write( 
       
   194         /* [in] */ ULONG cProperties,
       
   195         /* [in] */ PROPBAG2 *pPropBag,
       
   196         /* [in] */ VARIANT *pvarValue);
       
   197     
       
   198     virtual HRESULT STDMETHODCALLTYPE CountProperties( 
       
   199         /* [out] */ ULONG *pcProperties);
       
   200     
       
   201     virtual HRESULT STDMETHODCALLTYPE GetPropertyInfo( 
       
   202         /* [in] */ ULONG iProperty,
       
   203         /* [in] */ ULONG cProperties,
       
   204         /* [out] */ PROPBAG2 *pPropBag,
       
   205         /* [out] */ ULONG *pcProperties);
       
   206     
       
   207     virtual HRESULT STDMETHODCALLTYPE LoadObject( 
       
   208         /* [in] */ LPCOLESTR pstrName,
       
   209         /* [in] */ DWORD dwHint,
       
   210         /* [in] */ IUnknown *pUnkObject,
       
   211         /* [in] */ IErrorLog *pErrLog);
       
   212     
       
   213 protected:
       
   214     HashMap<String, String>* m_formValues;
       
   215 };
       
   216 
       
   217 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
       
   218 {
       
   219     *ppvObject = 0;
       
   220     if (IsEqualGUID(riid, IID_IUnknown))
       
   221         *ppvObject = this;
       
   222     else if (IsEqualGUID(riid, IID_IPropertyBag))
       
   223         *ppvObject = static_cast<IPropertyBag*>(this);
       
   224     else if (IsEqualGUID(riid, IID_IPropertyBag2))
       
   225         *ppvObject = static_cast<IPropertyBag2*>(this);
       
   226     else
       
   227         return E_NOINTERFACE;
       
   228 
       
   229     AddRef();
       
   230     return S_OK;
       
   231 }
       
   232 
       
   233 ULONG STDMETHODCALLTYPE FormValuesPropertyBag::AddRef(void)
       
   234 {
       
   235     return 1;
       
   236 }
       
   237 
       
   238 ULONG STDMETHODCALLTYPE FormValuesPropertyBag::Release(void)
       
   239 {
       
   240     return 0;
       
   241 }
       
   242 
       
   243 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* /*pErrorLog*/)
       
   244 {
       
   245     HRESULT hr = S_OK;
       
   246 
       
   247     if (!pszPropName || !pVar)
       
   248         return E_POINTER;
       
   249 
       
   250     String key(pszPropName);
       
   251     if (!m_formValues->contains(key))
       
   252         return E_INVALIDARG;
       
   253     
       
   254     String value = m_formValues->get(key);
       
   255 
       
   256     VARTYPE requestedType = V_VT(pVar);
       
   257     VariantClear(pVar);
       
   258     V_VT(pVar) = VT_BSTR;
       
   259     V_BSTR(pVar) = SysAllocStringLen(value.characters(), value.length());
       
   260     if (value.length() && !V_BSTR(pVar))
       
   261         return E_OUTOFMEMORY;
       
   262 
       
   263     if (requestedType != VT_BSTR && requestedType != VT_EMPTY)
       
   264         hr = VariantChangeType(pVar, pVar, VARIANT_NOUSEROVERRIDE | VARIANT_ALPHABOOL, requestedType);
       
   265     
       
   266     return hr;
       
   267 }
       
   268 
       
   269 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
       
   270 {
       
   271     if (!pszPropName || !pVar)
       
   272         return E_POINTER;
       
   273     VariantClear(pVar);
       
   274     return E_FAIL;
       
   275 }
       
   276 
       
   277 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Read( 
       
   278     /* [in] */ ULONG cProperties,
       
   279     /* [in] */ PROPBAG2* pPropBag,
       
   280     /* [in] */ IErrorLog* pErrLog,
       
   281     /* [out] */ VARIANT* pvarValue,
       
   282     /* [out] */ HRESULT* phrError)
       
   283 {
       
   284     if (cProperties > (size_t)m_formValues->size())
       
   285         return E_INVALIDARG;
       
   286     if (!pPropBag || !pvarValue || !phrError)
       
   287         return E_POINTER;
       
   288 
       
   289     for (ULONG i=0; i<cProperties; i++) {
       
   290         VariantInit(&pvarValue[i]);
       
   291         phrError[i] = Read(pPropBag->pstrName, &pvarValue[i], pErrLog);
       
   292     }
       
   293 
       
   294     return S_OK;
       
   295 }
       
   296 
       
   297 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Write( 
       
   298     /* [in] */ ULONG /*cProperties*/,
       
   299     /* [in] */ PROPBAG2* pPropBag,
       
   300     /* [in] */ VARIANT* pvarValue)
       
   301 {
       
   302     if (!pPropBag || !pvarValue)
       
   303         return E_POINTER;
       
   304     return E_FAIL;
       
   305 }
       
   306 
       
   307 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::CountProperties( 
       
   308     /* [out] */ ULONG* pcProperties)
       
   309 {
       
   310     *pcProperties = m_formValues->size();
       
   311     return S_OK;
       
   312 }
       
   313 
       
   314 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::GetPropertyInfo( 
       
   315     /* [in] */ ULONG iProperty,
       
   316     /* [in] */ ULONG cProperties,
       
   317     /* [out] */ PROPBAG2* pPropBag,
       
   318     /* [out] */ ULONG* pcProperties)
       
   319 {
       
   320     if (iProperty > (size_t)m_formValues->size() || iProperty+cProperties > (size_t)m_formValues->size())
       
   321         return E_INVALIDARG;
       
   322     if (!pPropBag || !pcProperties)
       
   323         return E_POINTER;
       
   324 
       
   325     *pcProperties = 0;
       
   326     ULONG i = 0;
       
   327     ULONG endProperty = iProperty + cProperties;
       
   328     for (HashMap<String, String>::iterator it = m_formValues->begin(); i<endProperty; i++) {
       
   329         if (i >= iProperty) {
       
   330             int storeIndex = (*pcProperties)++;
       
   331             pPropBag[storeIndex].dwType = PROPBAG2_TYPE_DATA;
       
   332             pPropBag[storeIndex].vt = VT_BSTR;
       
   333             pPropBag[storeIndex].cfType = CF_TEXT;
       
   334             pPropBag[storeIndex].dwHint = 0;
       
   335             pPropBag[storeIndex].pstrName = const_cast<LPOLESTR>(it->first.charactersWithNullTermination());
       
   336         }
       
   337         ++it;
       
   338     }
       
   339 
       
   340     return S_OK;
       
   341 }
       
   342 
       
   343 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::LoadObject( 
       
   344     /* [in] */ LPCOLESTR pstrName,
       
   345     /* [in] */ DWORD /*dwHint*/,
       
   346     /* [in] */ IUnknown* pUnkObject,
       
   347     /* [in] */ IErrorLog* /*pErrLog*/)
       
   348 {
       
   349     if (!pstrName || !pUnkObject)
       
   350         return E_POINTER;
       
   351     return E_FAIL;
       
   352 }
       
   353 
       
   354 //-----------------------------------------------------------------------------
       
   355 
       
   356 static Element *elementFromDOMElement(IDOMElement *element)
       
   357 {
       
   358     if (!element)
       
   359         return 0;
       
   360 
       
   361     COMPtr<IDOMElementPrivate> elePriv;
       
   362     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
       
   363     if (SUCCEEDED(hr)) {
       
   364         Element* ele;
       
   365         hr = elePriv->coreElement((void**)&ele);
       
   366         if (SUCCEEDED(hr))
       
   367             return ele;
       
   368     }
       
   369     return 0;
       
   370 }
       
   371 
       
   372 static HTMLFormElement *formElementFromDOMElement(IDOMElement *element)
       
   373 {
       
   374     if (!element)
       
   375         return 0;
       
   376 
       
   377     IDOMElementPrivate* elePriv;
       
   378     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
       
   379     if (SUCCEEDED(hr)) {
       
   380         Element* ele;
       
   381         hr = elePriv->coreElement((void**)&ele);
       
   382         elePriv->Release();
       
   383         if (SUCCEEDED(hr) && ele && ele->hasTagName(formTag))
       
   384             return static_cast<HTMLFormElement*>(ele);
       
   385     }
       
   386     return 0;
       
   387 }
       
   388 
       
   389 static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element)
       
   390 {
       
   391     if (!element)
       
   392         return 0;
       
   393 
       
   394     IDOMElementPrivate* elePriv;
       
   395     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
       
   396     if (SUCCEEDED(hr)) {
       
   397         Element* ele;
       
   398         hr = elePriv->coreElement((void**)&ele);
       
   399         elePriv->Release();
       
   400         if (SUCCEEDED(hr) && ele && ele->hasTagName(inputTag))
       
   401             return static_cast<HTMLInputElement*>(ele);
       
   402     }
       
   403     return 0;
       
   404 }
       
   405 
       
   406 // WebFramePrivate ------------------------------------------------------------
       
   407 
       
   408 class WebFrame::WebFramePrivate {
       
   409 public:
       
   410     WebFramePrivate() 
       
   411         : frame(0)
       
   412         , webView(0)
       
   413         , m_policyFunction(0)
       
   414         , m_pluginView(0) 
       
   415         , m_hasSentResponseToPlugin(false) 
       
   416     { 
       
   417     }
       
   418 
       
   419     ~WebFramePrivate() { }
       
   420     FrameView* frameView() { return frame ? frame->view() : 0; }
       
   421 
       
   422     Frame* frame;
       
   423     WebView* webView;
       
   424     FramePolicyFunction m_policyFunction;
       
   425     COMPtr<WebFramePolicyListener> m_policyListener;
       
   426     
       
   427     // Points to the plugin view that data should be redirected to.
       
   428     PluginViewWin* m_pluginView;
       
   429     bool m_hasSentResponseToPlugin;
       
   430 };
       
   431 
       
   432 // WebFrame ----------------------------------------------------------------
       
   433 
       
   434 WebFrame::WebFrame()
       
   435 : m_refCount(0)
       
   436 , d(new WebFrame::WebFramePrivate)
       
   437 , m_quickRedirectComing(false)
       
   438 , m_inPrintingMode(false)
       
   439 , m_pageHeight(0)
       
   440 {
       
   441     WebFrameCount++;
       
   442     gClassCount++;
       
   443 }
       
   444 
       
   445 WebFrame::~WebFrame()
       
   446 {
       
   447     delete d;
       
   448     WebFrameCount--;
       
   449     gClassCount--;
       
   450 }
       
   451 
       
   452 WebFrame* WebFrame::createInstance()
       
   453 {
       
   454     WebFrame* instance = new WebFrame();
       
   455     instance->AddRef();
       
   456     return instance;
       
   457 }
       
   458 
       
   459 HRESULT STDMETHODCALLTYPE WebFrame::setAllowsScrolling(
       
   460     /* [in] */ BOOL flag)
       
   461 {
       
   462     if (Frame* frame = core(this))
       
   463         if (FrameView* view = frame->view())
       
   464             view->setAllowsScrolling(!!flag);
       
   465 
       
   466     return S_OK;
       
   467 }
       
   468 
       
   469 HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling(
       
   470     /* [retval][out] */ BOOL *flag)
       
   471 {
       
   472     if (flag)
       
   473         if (Frame* frame = core(this))
       
   474             if (FrameView* view = frame->view())
       
   475                 *flag = view->allowsScrolling();
       
   476 
       
   477     return S_OK;
       
   478 }
       
   479 
       
   480 
       
   481 // IUnknown -------------------------------------------------------------------
       
   482 
       
   483 HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject)
       
   484 {
       
   485     *ppvObject = 0;
       
   486     if (IsEqualGUID(riid, IID_WebFrame))
       
   487         *ppvObject = this;
       
   488     else if (IsEqualGUID(riid, IID_IUnknown))
       
   489         *ppvObject = static_cast<IWebFrame*>(this);
       
   490     else if (IsEqualGUID(riid, IID_IWebFrame))
       
   491         *ppvObject = static_cast<IWebFrame*>(this);
       
   492     else if (IsEqualGUID(riid, IID_IWebFramePrivate))
       
   493         *ppvObject = static_cast<IWebFramePrivate*>(this);
       
   494     else
       
   495         return E_NOINTERFACE;
       
   496 
       
   497     AddRef();
       
   498     return S_OK;
       
   499 }
       
   500 
       
   501 ULONG STDMETHODCALLTYPE WebFrame::AddRef(void)
       
   502 {
       
   503     return ++m_refCount;
       
   504 }
       
   505 
       
   506 ULONG STDMETHODCALLTYPE WebFrame::Release(void)
       
   507 {
       
   508     ULONG newRef = --m_refCount;
       
   509     if (!newRef)
       
   510         delete(this);
       
   511 
       
   512     return newRef;
       
   513 }
       
   514 
       
   515 // IWebFrame -------------------------------------------------------------------
       
   516 
       
   517 HRESULT STDMETHODCALLTYPE WebFrame::name( 
       
   518     /* [retval][out] */ BSTR* frameName)
       
   519 {
       
   520     if (!frameName) {
       
   521         ASSERT_NOT_REACHED();
       
   522         return E_POINTER;
       
   523     }
       
   524 
       
   525     *frameName = 0;
       
   526 
       
   527     Frame* coreFrame = core(this);
       
   528     if (!coreFrame)
       
   529         return E_FAIL;
       
   530 
       
   531     *frameName = BString(coreFrame->tree()->name()).release();
       
   532     return S_OK;
       
   533 }
       
   534 
       
   535 HRESULT STDMETHODCALLTYPE WebFrame::webView( 
       
   536     /* [retval][out] */ IWebView** view)
       
   537 {
       
   538     *view = 0;
       
   539     if (!d->webView)
       
   540         return E_FAIL;
       
   541     *view = d->webView;
       
   542     (*view)->AddRef();
       
   543     return S_OK;
       
   544 }
       
   545 
       
   546 HRESULT STDMETHODCALLTYPE WebFrame::frameView(
       
   547     /* [retval][out] */ IWebFrameView** /*view*/)
       
   548 {
       
   549     ASSERT_NOT_REACHED();
       
   550     return E_NOTIMPL;
       
   551 }
       
   552 
       
   553 HRESULT STDMETHODCALLTYPE WebFrame::DOMDocument( 
       
   554     /* [retval][out] */ IDOMDocument** result)
       
   555 {
       
   556     if (!result) {
       
   557         ASSERT_NOT_REACHED();
       
   558         return E_POINTER;
       
   559     }
       
   560 
       
   561     *result = 0;
       
   562 
       
   563     if (Frame* coreFrame = core(this))
       
   564         if (Document* document = coreFrame->document())
       
   565             *result = DOMDocument::createInstance(document);
       
   566 
       
   567     return *result ? S_OK : E_FAIL;
       
   568 }
       
   569 
       
   570 HRESULT STDMETHODCALLTYPE WebFrame::frameElement( 
       
   571     /* [retval][out] */ IDOMHTMLElement** /*frameElement*/)
       
   572 {
       
   573     ASSERT_NOT_REACHED();
       
   574     return E_NOTIMPL;
       
   575 }
       
   576 
       
   577 HRESULT STDMETHODCALLTYPE WebFrame::currentForm( 
       
   578         /* [retval][out] */ IDOMElement **currentForm)
       
   579 {
       
   580     if (!currentForm) {
       
   581         ASSERT_NOT_REACHED();
       
   582         return E_POINTER;
       
   583     }
       
   584 
       
   585     *currentForm = 0;
       
   586 
       
   587     if (Frame* coreFrame = core(this))
       
   588         if (HTMLFormElement* formElement = coreFrame->currentForm())
       
   589             *currentForm = DOMElement::createInstance(formElement);
       
   590 
       
   591     return *currentForm ? S_OK : E_FAIL;
       
   592 }
       
   593 
       
   594 HRESULT STDMETHODCALLTYPE WebFrame::loadRequest( 
       
   595     /* [in] */ IWebURLRequest* request)
       
   596 {
       
   597     COMPtr<WebMutableURLRequest> requestImpl;
       
   598 
       
   599     HRESULT hr = request->QueryInterface(CLSID_WebMutableURLRequest, (void**)&requestImpl);
       
   600     if (FAILED(hr))
       
   601         return hr;
       
   602  
       
   603     Frame* coreFrame = core(this);
       
   604     if (!coreFrame)
       
   605         return E_FAIL;
       
   606 
       
   607     coreFrame->loader()->load(requestImpl->resourceRequest());
       
   608     return S_OK;
       
   609 }
       
   610 
       
   611 void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL)
       
   612 {
       
   613     String mimeTypeString(mimeType, SysStringLen(mimeType));
       
   614     if (!mimeType)
       
   615         mimeTypeString = "text/html";
       
   616 
       
   617     String encodingString(textEncodingName, SysStringLen(textEncodingName));
       
   618     KURL baseKURL = DeprecatedString((DeprecatedChar*)baseURL, SysStringLen(baseURL));
       
   619     KURL failingKURL = DeprecatedString((DeprecatedChar*)failingURL, SysStringLen(failingURL));
       
   620 
       
   621     ResourceRequest request(baseKURL);
       
   622     SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL);
       
   623 
       
   624     // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.
       
   625     if (Frame* coreFrame = core(this))
       
   626         coreFrame->loader()->load(request, substituteData);
       
   627 }
       
   628 
       
   629 
       
   630 HRESULT STDMETHODCALLTYPE WebFrame::loadData( 
       
   631     /* [in] */ IStream* data,
       
   632     /* [in] */ BSTR mimeType,
       
   633     /* [in] */ BSTR textEncodingName,
       
   634     /* [in] */ BSTR url)
       
   635 {
       
   636     RefPtr<SharedBuffer> sharedBuffer = new SharedBuffer();
       
   637 
       
   638     STATSTG stat;
       
   639     if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {
       
   640         if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {
       
   641             Vector<char> dataBuffer(stat.cbSize.LowPart);
       
   642             ULONG read;
       
   643             // FIXME: this does a needless copy, would be better to read right into the SharedBuffer
       
   644             // or adopt the Vector or something.
       
   645             if (SUCCEEDED(data->Read(dataBuffer.data(), (ULONG)dataBuffer.size(), &read)))
       
   646                 sharedBuffer->append(dataBuffer.data(), (int)dataBuffer.size());
       
   647         }
       
   648     }
       
   649 
       
   650     loadData(sharedBuffer, mimeType, textEncodingName, url, 0);
       
   651     return S_OK;
       
   652 }
       
   653 
       
   654 void WebFrame::loadHTMLString(BSTR string, BSTR baseURL, BSTR unreachableURL)
       
   655 {
       
   656     RefPtr<SharedBuffer> sharedBuffer = new SharedBuffer(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string));
       
   657     BString utf16Encoding(TEXT("utf-16"), 6);
       
   658     loadData(sharedBuffer.release(), 0, utf16Encoding, baseURL, unreachableURL);
       
   659 }
       
   660 
       
   661 HRESULT STDMETHODCALLTYPE WebFrame::loadHTMLString( 
       
   662     /* [in] */ BSTR string,
       
   663     /* [in] */ BSTR baseURL)
       
   664 {
       
   665     loadHTMLString(string, baseURL, 0);
       
   666     return S_OK;
       
   667 }
       
   668 
       
   669 HRESULT STDMETHODCALLTYPE WebFrame::loadAlternateHTMLString( 
       
   670     /* [in] */ BSTR str,
       
   671     /* [in] */ BSTR baseURL,
       
   672     /* [in] */ BSTR unreachableURL)
       
   673 {
       
   674     loadHTMLString(str, baseURL, unreachableURL);
       
   675     return S_OK;
       
   676 }
       
   677 
       
   678 HRESULT STDMETHODCALLTYPE WebFrame::loadArchive( 
       
   679     /* [in] */ IWebArchive* /*archive*/)
       
   680 {
       
   681     ASSERT_NOT_REACHED();
       
   682     return E_NOTIMPL;
       
   683 }
       
   684 
       
   685 static inline WebDataSource *getWebDataSource(DocumentLoader* loader)
       
   686 {
       
   687     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
       
   688 }
       
   689 
       
   690 HRESULT STDMETHODCALLTYPE WebFrame::dataSource( 
       
   691     /* [retval][out] */ IWebDataSource** source)
       
   692 {
       
   693     if (!source) {
       
   694         ASSERT_NOT_REACHED();
       
   695         return E_POINTER;
       
   696     }
       
   697 
       
   698     *source = 0;
       
   699 
       
   700     Frame* coreFrame = core(this);
       
   701     if (!coreFrame)
       
   702         return E_FAIL;
       
   703 
       
   704     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->documentLoader());
       
   705 
       
   706     *source = webDataSource;
       
   707 
       
   708     if (webDataSource)
       
   709         webDataSource->AddRef(); 
       
   710 
       
   711     return *source ? S_OK : E_FAIL;
       
   712 }
       
   713 
       
   714 HRESULT STDMETHODCALLTYPE WebFrame::provisionalDataSource( 
       
   715     /* [retval][out] */ IWebDataSource** source)
       
   716 {
       
   717     if (!source) {
       
   718         ASSERT_NOT_REACHED();
       
   719         return E_POINTER;
       
   720     }
       
   721 
       
   722     *source = 0;
       
   723 
       
   724     Frame* coreFrame = core(this);
       
   725     if (!coreFrame)
       
   726         return E_FAIL;
       
   727 
       
   728     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->provisionalDocumentLoader());
       
   729 
       
   730     *source = webDataSource;
       
   731 
       
   732     if (webDataSource)
       
   733         webDataSource->AddRef(); 
       
   734 
       
   735     return *source ? S_OK : E_FAIL;
       
   736 }
       
   737 
       
   738 KURL WebFrame::url() const
       
   739 {
       
   740     Frame* coreFrame = core(this);
       
   741     if (!coreFrame)
       
   742         return KURL();
       
   743 
       
   744     return coreFrame->loader()->URL();
       
   745 }
       
   746 
       
   747 HRESULT STDMETHODCALLTYPE WebFrame::stopLoading( void)
       
   748 {
       
   749     if (Frame* coreFrame = core(this))
       
   750         coreFrame->loader()->stopAllLoaders();
       
   751     return S_OK;
       
   752 }
       
   753 
       
   754 HRESULT STDMETHODCALLTYPE WebFrame::reload( void)
       
   755 {
       
   756     Frame* coreFrame = core(this);
       
   757     if (!coreFrame)
       
   758         return E_FAIL;
       
   759 
       
   760     coreFrame->loader()->reload();
       
   761     return S_OK;
       
   762 }
       
   763 
       
   764 HRESULT STDMETHODCALLTYPE WebFrame::findFrameNamed( 
       
   765     /* [in] */ BSTR name,
       
   766     /* [retval][out] */ IWebFrame** frame)
       
   767 {
       
   768     if (!frame) {
       
   769         ASSERT_NOT_REACHED();
       
   770         return E_POINTER;
       
   771     }
       
   772 
       
   773     *frame = 0;
       
   774 
       
   775     Frame* coreFrame = core(this);
       
   776     if (!coreFrame)
       
   777         return E_FAIL;
       
   778 
       
   779     Frame* foundFrame = coreFrame->tree()->find(AtomicString(name, SysStringLen(name)));
       
   780     if (!foundFrame)
       
   781         return S_OK;
       
   782 
       
   783     WebFrame* foundWebFrame = kit(foundFrame);
       
   784     if (!foundWebFrame)
       
   785         return E_FAIL;
       
   786 
       
   787     return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame);
       
   788 }
       
   789 
       
   790 HRESULT STDMETHODCALLTYPE WebFrame::parentFrame( 
       
   791     /* [retval][out] */ IWebFrame** frame)
       
   792 {
       
   793     HRESULT hr = S_OK;
       
   794     *frame = 0;
       
   795     if (Frame* coreFrame = core(this))
       
   796         if (WebFrame* webFrame = kit(coreFrame->tree()->parent()))
       
   797             hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame);
       
   798 
       
   799     return hr;
       
   800 }
       
   801 
       
   802 class EnumChildFrames : public IEnumVARIANT
       
   803 {
       
   804 public:
       
   805     EnumChildFrames(Frame* f) : m_refCount(1), m_frame(f), m_curChild(f ? f->tree()->firstChild() : 0) { }
       
   806 
       
   807     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
       
   808     {
       
   809         *ppvObject = 0;
       
   810         if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT))
       
   811             *ppvObject = this;
       
   812         else
       
   813             return E_NOINTERFACE;
       
   814 
       
   815         AddRef();
       
   816         return S_OK;
       
   817     }
       
   818 
       
   819     virtual ULONG STDMETHODCALLTYPE AddRef(void)
       
   820     {
       
   821         return ++m_refCount;
       
   822     }
       
   823 
       
   824     virtual ULONG STDMETHODCALLTYPE Release(void)
       
   825     {
       
   826         ULONG newRef = --m_refCount;
       
   827         if (!newRef)
       
   828             delete(this);
       
   829         return newRef;
       
   830     }
       
   831 
       
   832     virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
       
   833     {
       
   834         if (pCeltFetched)
       
   835             *pCeltFetched = 0;
       
   836         if (!rgVar)
       
   837             return E_POINTER;
       
   838         VariantInit(rgVar);
       
   839         if (!celt || celt > 1)
       
   840             return S_FALSE;
       
   841         if (!m_frame || !m_curChild)
       
   842             return S_FALSE;
       
   843 
       
   844         WebFrame* webFrame = kit(m_curChild);
       
   845         IUnknown* unknown;
       
   846         HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown);
       
   847         if (FAILED(hr))
       
   848             return hr;
       
   849 
       
   850         V_VT(rgVar) = VT_UNKNOWN;
       
   851         V_UNKNOWN(rgVar) = unknown;
       
   852 
       
   853         m_curChild = m_curChild->tree()->nextSibling();
       
   854         if (pCeltFetched)
       
   855             *pCeltFetched = 1;
       
   856         return S_OK;
       
   857     }
       
   858 
       
   859     virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
       
   860     {
       
   861         if (!m_frame)
       
   862             return S_FALSE;
       
   863         for (unsigned i = 0; i < celt && m_curChild; i++)
       
   864             m_curChild = m_curChild->tree()->nextSibling();
       
   865         return m_curChild ? S_OK : S_FALSE;
       
   866     }
       
   867 
       
   868     virtual HRESULT STDMETHODCALLTYPE Reset(void)
       
   869     {
       
   870         if (!m_frame)
       
   871             return S_FALSE;
       
   872         m_curChild = m_frame->tree()->firstChild();
       
   873         return S_OK;
       
   874     }
       
   875 
       
   876     virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**)
       
   877     {
       
   878         return E_NOTIMPL;
       
   879     }
       
   880 
       
   881 private:
       
   882     ULONG m_refCount;
       
   883     Frame* m_frame;
       
   884     Frame* m_curChild;
       
   885 };
       
   886 
       
   887 HRESULT STDMETHODCALLTYPE WebFrame::childFrames( 
       
   888     /* [retval][out] */ IEnumVARIANT **enumFrames)
       
   889 {
       
   890     if (!enumFrames)
       
   891         return E_POINTER;
       
   892 
       
   893     *enumFrames = new EnumChildFrames(core(this));
       
   894     return S_OK;
       
   895 }
       
   896 
       
   897 // IWebFramePrivaete ------------------------------------------------------
       
   898 
       
   899 HRESULT STDMETHODCALLTYPE WebFrame::renderTreeAsExternalRepresentation(
       
   900     /* [retval][out] */ BSTR *result)
       
   901 {
       
   902     if (!result) {
       
   903         ASSERT_NOT_REACHED();
       
   904         return E_POINTER;
       
   905     }
       
   906 
       
   907     *result = 0;
       
   908 
       
   909     Frame* coreFrame = core(this);
       
   910     if (!coreFrame)
       
   911         return E_FAIL;
       
   912 
       
   913     DeprecatedString representation = externalRepresentation(coreFrame->renderer());
       
   914 
       
   915     *result = SysAllocStringLen((LPCOLESTR)representation.unicode(), representation.length());
       
   916 
       
   917     return S_OK;
       
   918 }
       
   919 
       
   920 HRESULT STDMETHODCALLTYPE WebFrame::scrollOffset(
       
   921         /* [retval][out] */ SIZE* offset)
       
   922 {
       
   923     if (!offset) {
       
   924         ASSERT_NOT_REACHED();
       
   925         return E_POINTER;
       
   926     }
       
   927 
       
   928     Frame* coreFrame = core(this);
       
   929     if (!coreFrame)
       
   930         return E_FAIL;
       
   931 
       
   932     FrameView* view = coreFrame->view();
       
   933     if (!view)
       
   934         return E_FAIL;
       
   935 
       
   936     *offset = view->scrollOffset();
       
   937     return S_OK;
       
   938 }
       
   939 
       
   940 HRESULT STDMETHODCALLTYPE WebFrame::layout()
       
   941 {
       
   942     Frame* coreFrame = core(this);
       
   943     if (!coreFrame)
       
   944         return E_FAIL;
       
   945 
       
   946     FrameView* view = coreFrame->view();
       
   947     if (!view)
       
   948         return E_FAIL;
       
   949 
       
   950     view->layout();
       
   951     return S_OK;
       
   952 }
       
   953 
       
   954 HRESULT STDMETHODCALLTYPE WebFrame::firstLayoutDone(
       
   955     /* [retval][out] */ BOOL* result)
       
   956 {
       
   957     if (!result) {
       
   958         ASSERT_NOT_REACHED();
       
   959         return E_POINTER;
       
   960     }
       
   961 
       
   962     *result = 0;
       
   963 
       
   964     Frame* coreFrame = core(this);
       
   965     if (!coreFrame)
       
   966         return E_FAIL;
       
   967 
       
   968     *result = coreFrame->loader()->firstLayoutDone();
       
   969     return S_OK;
       
   970 }
       
   971 
       
   972 HRESULT STDMETHODCALLTYPE WebFrame::loadType( 
       
   973     /* [retval][out] */ WebFrameLoadType* type)
       
   974 {
       
   975     if (!type) {
       
   976         ASSERT_NOT_REACHED();
       
   977         return E_POINTER;
       
   978     }
       
   979 
       
   980     *type = (WebFrameLoadType)0;
       
   981 
       
   982     Frame* coreFrame = core(this);
       
   983     if (!coreFrame)
       
   984         return E_FAIL;
       
   985 
       
   986     *type = (WebFrameLoadType)coreFrame->loader()->loadType();
       
   987     return S_OK;
       
   988 }
       
   989 
       
   990 
       
   991 // WebFrame ---------------------------------------------------------------
       
   992 
       
   993 void WebFrame::initWithWebFrameView(IWebFrameView* /*view*/, IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement)
       
   994 {
       
   995     if (FAILED(webView->QueryInterface(CLSID_WebView, (void**)&d->webView)))
       
   996         return;
       
   997     d->webView->Release(); // don't hold the extra ref
       
   998 
       
   999     HWND viewWindow;
       
  1000     d->webView->viewWindow((OLE_HANDLE*)&viewWindow);
       
  1001 
       
  1002     this->AddRef(); // We release this ref in frameLoaderDestroyed()
       
  1003     Frame* frame = new Frame(page, ownerElement, this);
       
  1004     d->frame = frame;
       
  1005 
       
  1006     FrameView* frameView = new FrameView(frame);
       
  1007 
       
  1008     frame->setView(frameView);
       
  1009     frameView->deref(); // FrameViews are created with a ref count of 1. Release this ref since we've assigned it to frame.
       
  1010 
       
  1011     frameView->setContainingWindow(viewWindow);
       
  1012 }
       
  1013 
       
  1014 Frame* WebFrame::impl()
       
  1015 {
       
  1016     return d->frame;
       
  1017 }
       
  1018 
       
  1019 void WebFrame::invalidate()
       
  1020 {
       
  1021     Frame* coreFrame = core(this);
       
  1022     ASSERT(coreFrame);
       
  1023 
       
  1024     if (Document* document = coreFrame->document())
       
  1025         document->recalcStyle(Node::Force);
       
  1026 }
       
  1027 
       
  1028 void WebFrame::setTextSizeMultiplier(float multiplier)
       
  1029 {
       
  1030     int newZoomFactor = (int)round(multiplier * 100);
       
  1031     Frame* coreFrame = core(this);
       
  1032     ASSERT(coreFrame);
       
  1033 
       
  1034     if (coreFrame->zoomFactor() == newZoomFactor)
       
  1035         return;
       
  1036 
       
  1037     coreFrame->setZoomFactor(newZoomFactor);
       
  1038 }
       
  1039 
       
  1040 HRESULT WebFrame::inViewSourceMode(BOOL* flag)
       
  1041 {
       
  1042     if (!flag) {
       
  1043         ASSERT_NOT_REACHED();
       
  1044         return E_POINTER;
       
  1045     }
       
  1046 
       
  1047     *flag = FALSE;
       
  1048 
       
  1049     Frame* coreFrame = core(this);
       
  1050     if (!coreFrame)
       
  1051         return E_FAIL;
       
  1052 
       
  1053     *flag = coreFrame->inViewSourceMode() ? TRUE : FALSE;
       
  1054     return S_OK;
       
  1055 }
       
  1056 
       
  1057 HRESULT WebFrame::setInViewSourceMode(BOOL flag)
       
  1058 {
       
  1059     Frame* coreFrame = core(this);
       
  1060     if (!coreFrame)
       
  1061         return E_FAIL;
       
  1062 
       
  1063     coreFrame->setInViewSourceMode(!!flag);
       
  1064     return S_OK;
       
  1065 }
       
  1066 
       
  1067 HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element)
       
  1068 {
       
  1069     if (!form)
       
  1070         return E_INVALIDARG;
       
  1071 
       
  1072     HTMLFormElement *formElement = formElementFromDOMElement(form);
       
  1073     if (formElement) {
       
  1074         Vector<HTMLGenericFormElement*>& elements = formElement->formElements;
       
  1075         AtomicString targetName((UChar*)name, SysStringLen(name));
       
  1076         for (unsigned int i = 0; i < elements.size(); i++) {
       
  1077             HTMLGenericFormElement *elt = elements[i];
       
  1078             // Skip option elements, other duds
       
  1079             if (elt->name() == targetName) {
       
  1080                 *element = DOMElement::createInstance(elt);
       
  1081                 return S_OK;
       
  1082             }
       
  1083         }
       
  1084     }
       
  1085     return E_FAIL;
       
  1086 }
       
  1087 
       
  1088 HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form)
       
  1089 {
       
  1090     if (!element)
       
  1091         return E_INVALIDARG;
       
  1092 
       
  1093     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
       
  1094     if (!inputElement)
       
  1095         return E_FAIL;
       
  1096 
       
  1097     HTMLFormElement *formElement = inputElement->form();
       
  1098     if (!formElement)
       
  1099         return E_FAIL;
       
  1100 
       
  1101     *form = DOMElement::createInstance(formElement);
       
  1102     return S_OK;
       
  1103 }
       
  1104 
       
  1105 HRESULT WebFrame::elementDoesAutoComplete(IDOMElement *element, bool *result)
       
  1106 {
       
  1107     *result = false;
       
  1108     if (!element)
       
  1109         return E_INVALIDARG;
       
  1110 
       
  1111     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
       
  1112     if (!inputElement)
       
  1113         *result = false;
       
  1114     else
       
  1115         *result = (inputElement->inputType() == HTMLInputElement::TEXT && inputElement->autoComplete());
       
  1116 
       
  1117     return S_OK;
       
  1118 }
       
  1119 
       
  1120 HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls)
       
  1121 {
       
  1122     if (!form)
       
  1123         return E_INVALIDARG;
       
  1124 
       
  1125     HTMLFormElement *formElement = formElementFromDOMElement(form);
       
  1126     if (!formElement)
       
  1127         return E_FAIL;
       
  1128 
       
  1129     int inCount = *cControls;
       
  1130     int count = (int) formElement->formElements.size();
       
  1131     *cControls = count;
       
  1132     if (!controls)
       
  1133         return S_OK;
       
  1134     if (inCount < count)
       
  1135         return E_FAIL;
       
  1136 
       
  1137     *cControls = 0;
       
  1138     Vector<HTMLGenericFormElement*>& elements = formElement->formElements;
       
  1139     for (int i = 0; i < count; i++) {
       
  1140         if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds
       
  1141             controls[*cControls] = DOMElement::createInstance(elements.at(i));
       
  1142             (*cControls)++;
       
  1143         }
       
  1144     }
       
  1145     return S_OK;
       
  1146 }
       
  1147 
       
  1148 HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result)
       
  1149 {
       
  1150     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
       
  1151     *result = inputElement != 0
       
  1152         && inputElement->inputType() == HTMLInputElement::PASSWORD;
       
  1153     return S_OK;
       
  1154 }
       
  1155 
       
  1156 HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, int cLabels, IDOMElement* beforeElement, BSTR* result)
       
  1157 {
       
  1158     if (!result) {
       
  1159         ASSERT_NOT_REACHED();
       
  1160         return E_POINTER;
       
  1161     }
       
  1162 
       
  1163     *result = 0;
       
  1164 
       
  1165     if (!cLabels)
       
  1166         return S_OK;
       
  1167     if (cLabels < 1)
       
  1168         return E_INVALIDARG;
       
  1169 
       
  1170     Frame* coreFrame = core(this);
       
  1171     if (!coreFrame)
       
  1172         return E_FAIL;
       
  1173 
       
  1174     Vector<String> labelStrings(cLabels);
       
  1175     for (int i=0; i<cLabels; i++)
       
  1176         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
       
  1177     Element *coreElement = elementFromDOMElement(beforeElement);
       
  1178     if (!coreElement)
       
  1179         return E_FAIL;
       
  1180 
       
  1181     String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement);
       
  1182     
       
  1183     *result = SysAllocStringLen(label.characters(), label.length());
       
  1184     if (label.length() && !*result)
       
  1185         return E_OUTOFMEMORY;
       
  1186     return S_OK;
       
  1187 }
       
  1188 
       
  1189 HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result)
       
  1190 {
       
  1191     if (!result) {
       
  1192         ASSERT_NOT_REACHED();
       
  1193         return E_POINTER;
       
  1194     }
       
  1195 
       
  1196     *result = 0;
       
  1197 
       
  1198     if (!cLabels)
       
  1199         return S_OK;
       
  1200     if (cLabels < 1)
       
  1201         return E_INVALIDARG;
       
  1202 
       
  1203     Frame* coreFrame = core(this);
       
  1204     if (!coreFrame)
       
  1205         return E_FAIL;
       
  1206 
       
  1207     Vector<String> labelStrings(cLabels);
       
  1208     for (int i=0; i<cLabels; i++)
       
  1209         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
       
  1210     Element *coreElement = elementFromDOMElement(againstElement);
       
  1211     if (!coreElement)
       
  1212         return E_FAIL;
       
  1213 
       
  1214     String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement);
       
  1215     
       
  1216     *result = SysAllocStringLen(label.characters(), label.length());
       
  1217     if (label.length() && !*result)
       
  1218         return E_OUTOFMEMORY;
       
  1219     return S_OK;
       
  1220 }
       
  1221 
       
  1222 HRESULT WebFrame::canProvideDocumentSource(bool* result)
       
  1223 {
       
  1224     HRESULT hr = S_OK;
       
  1225     *result = false;
       
  1226 
       
  1227     COMPtr<IWebDataSource> dataSource;
       
  1228     hr = WebFrame::dataSource(&dataSource);
       
  1229     if (FAILED(hr))
       
  1230         return hr;
       
  1231 
       
  1232     COMPtr<IWebURLResponse> urlResponse;
       
  1233     hr = dataSource->response(&urlResponse);
       
  1234     if (SUCCEEDED(hr) && urlResponse) {
       
  1235         BSTR mimeTypeBStr;
       
  1236         if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) {
       
  1237             String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr));
       
  1238             *result = mimeType == "text/html" || WebCore::DOMImplementation::isXMLMIMEType(mimeType);
       
  1239             SysFreeString(mimeTypeBStr);
       
  1240         }
       
  1241     }
       
  1242     return hr;
       
  1243 }
       
  1244 
       
  1245 // FrameWinClient
       
  1246 
       
  1247 void WebFrame::ref()
       
  1248 {
       
  1249     this->AddRef();
       
  1250 }
       
  1251 
       
  1252 void WebFrame::deref()
       
  1253 {
       
  1254     this->Release();
       
  1255 }
       
  1256 
       
  1257 void WebFrame::frameLoaderDestroyed()
       
  1258 {
       
  1259     // The FrameLoader going away is equivalent to the Frame going away,
       
  1260     // so we now need to clear our frame pointer.
       
  1261     d->frame = 0;
       
  1262 
       
  1263     this->Release();
       
  1264 }
       
  1265 
       
  1266 PassRefPtr<Frame> WebFrame::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
       
  1267 {
       
  1268     Frame* coreFrame = core(this);
       
  1269     ASSERT(coreFrame);
       
  1270 
       
  1271     COMPtr<WebFrame> webFrame;
       
  1272     webFrame.adoptRef(WebFrame::createInstance());
       
  1273 
       
  1274     webFrame->initWithWebFrameView(0, d->webView, coreFrame->page(), ownerElement);
       
  1275 
       
  1276     RefPtr<Frame> childFrame(adoptRef(core(webFrame.get()))); // We have to adopt, because Frames start out with a refcount of 1.
       
  1277     ASSERT(childFrame);
       
  1278 
       
  1279     coreFrame->tree()->appendChild(childFrame);
       
  1280     childFrame->tree()->setName(name);
       
  1281     childFrame->init();
       
  1282 
       
  1283     loadURLIntoChild(URL, referrer, webFrame.get());
       
  1284 
       
  1285     // The frame's onload handler may have removed it from the document.
       
  1286     if (!childFrame->tree()->parent())
       
  1287         return 0;
       
  1288 
       
  1289     return childFrame.release();
       
  1290 }
       
  1291 
       
  1292 void WebFrame::loadURLIntoChild(const KURL& originalURL, const String& referrer, WebFrame* childFrame)
       
  1293 {
       
  1294     ASSERT(childFrame);
       
  1295     ASSERT(core(childFrame));
       
  1296 
       
  1297     Frame* coreFrame = core(this);
       
  1298     ASSERT(coreFrame);
       
  1299 
       
  1300     HistoryItem* parentItem = coreFrame->loader()->currentHistoryItem();
       
  1301     FrameLoadType loadType = coreFrame->loader()->loadType();
       
  1302     FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
       
  1303 
       
  1304     KURL url = originalURL;
       
  1305 
       
  1306     // If we're moving in the backforward list, we might want to replace the content
       
  1307     // of this child frame with whatever was there at that point.
       
  1308     // Reload will maintain the frame contents, LoadSame will not.
       
  1309     if (parentItem && parentItem->children().size() &&
       
  1310         (isBackForwardLoadType(loadType)
       
  1311          || loadType == FrameLoadTypeReload
       
  1312          || loadType == FrameLoadTypeReloadAllowingStaleData))
       
  1313     {
       
  1314         if (HistoryItem* childItem = parentItem->childItemWithName(core(childFrame)->tree()->name())) {
       
  1315             // Use the original URL to ensure we get all the side-effects, such as
       
  1316             // onLoad handlers, of any redirects that happened. An example of where
       
  1317             // this is needed is Radar 3213556.
       
  1318             url = childItem->originalURLString().deprecatedString();
       
  1319             // These behaviors implied by these loadTypes should apply to the child frames
       
  1320             childLoadType = loadType;
       
  1321 
       
  1322             if (isBackForwardLoadType(loadType))
       
  1323                 // For back/forward, remember this item so we can traverse any child items as child frames load
       
  1324                 core(childFrame)->loader()->setProvisionalHistoryItem(childItem);
       
  1325             else
       
  1326                 // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
       
  1327                 core(childFrame)->loader()->setCurrentHistoryItem(childItem);
       
  1328         }
       
  1329     }
       
  1330 
       
  1331     // FIXME: Handle loading WebArchives here
       
  1332 
       
  1333     core(childFrame)->loader()->load(url, referrer, childLoadType, String(), 0, 0);
       
  1334 }
       
  1335 
       
  1336 void WebFrame::openURL(const String& URL, const Event* triggeringEvent, bool newWindow, bool lockHistory)
       
  1337 {
       
  1338     bool ctrlPressed = false;
       
  1339     bool shiftPressed = false;
       
  1340     if (triggeringEvent) {
       
  1341         if (triggeringEvent->isMouseEvent()) {
       
  1342             const MouseRelatedEvent* mouseEvent = static_cast<const MouseRelatedEvent*>(triggeringEvent);
       
  1343             ctrlPressed = mouseEvent->ctrlKey();
       
  1344             shiftPressed = mouseEvent->shiftKey();
       
  1345         } else if (triggeringEvent->isKeyboardEvent()) {
       
  1346             const KeyboardEvent* keyEvent = static_cast<const KeyboardEvent*>(triggeringEvent);
       
  1347             ctrlPressed = keyEvent->ctrlKey();
       
  1348             shiftPressed = keyEvent->shiftKey();
       
  1349         }
       
  1350     }
       
  1351 
       
  1352     if (ctrlPressed)
       
  1353         newWindow = true;
       
  1354 
       
  1355     BString urlBStr = URL;
       
  1356 
       
  1357     IWebMutableURLRequest* request = WebMutableURLRequest::createInstance();
       
  1358     if (FAILED(request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 0)))
       
  1359         goto exit;
       
  1360 
       
  1361     if (newWindow) {
       
  1362         // new tab/window
       
  1363         IWebUIDelegate* ui;
       
  1364         IWebView* newWebView;
       
  1365         if (SUCCEEDED(d->webView->uiDelegate(&ui)) && ui) {
       
  1366             if (SUCCEEDED(ui->createWebViewWithRequest(d->webView, request, &newWebView))) {
       
  1367                 if (shiftPressed) {
       
  1368                     // Ctrl-Option-Shift-click:  Opens a link in a new window and selects it.
       
  1369                     // Ctrl-Shift-click:  Opens a link in a new tab and selects it.
       
  1370                     ui->webViewShow(d->webView);
       
  1371                 }
       
  1372                 newWebView->Release();
       
  1373                 newWebView = 0;
       
  1374             }
       
  1375             ui->Release();
       
  1376         }
       
  1377     } else {
       
  1378         m_quickRedirectComing = lockHistory;
       
  1379         loadRequest(request);
       
  1380     }
       
  1381 
       
  1382 exit:
       
  1383     request->Release();
       
  1384 }
       
  1385 
       
  1386 void WebFrame::dispatchDidHandleOnloadEvents()
       
  1387 {
       
  1388     IWebFrameLoadDelegatePrivate* frameLoadDelegatePriv;
       
  1389     if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv))  && frameLoadDelegatePriv) {
       
  1390         frameLoadDelegatePriv->didHandleOnloadEventsForFrame(d->webView, this);
       
  1391         frameLoadDelegatePriv->Release();
       
  1392     }
       
  1393 }
       
  1394 
       
  1395 void WebFrame::windowScriptObjectAvailable(JSContextRef context, JSObjectRef windowObject)
       
  1396 {
       
  1397     IWebFrameLoadDelegate* frameLoadDelegate;
       
  1398     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)) && frameLoadDelegate) {
       
  1399         frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
       
  1400         frameLoadDelegate->Release();
       
  1401     }
       
  1402 }
       
  1403 
       
  1404 WebHistory* WebFrame::webHistory()
       
  1405 {
       
  1406     if (this != d->webView->topLevelFrame())
       
  1407         return 0;
       
  1408 
       
  1409     IWebHistoryPrivate* historyInternal = WebHistory::optionalSharedHistoryInternal(); // does not add a ref
       
  1410     if (!historyInternal)
       
  1411         return 0;
       
  1412 
       
  1413     WebHistory* webHistory;
       
  1414     if (FAILED(historyInternal->QueryInterface(CLSID_WebHistory, (void**)&webHistory)))
       
  1415         return 0;
       
  1416 
       
  1417     return webHistory;
       
  1418 }
       
  1419 
       
  1420 bool WebFrame::hasWebView() const
       
  1421 {
       
  1422     return !!d->webView;
       
  1423 }
       
  1424 
       
  1425 bool WebFrame::hasFrameView() const
       
  1426 {
       
  1427     return !!d->frameView();
       
  1428 }
       
  1429 
       
  1430 bool WebFrame::privateBrowsingEnabled() const
       
  1431 {
       
  1432     BOOL privateBrowsingEnabled = FALSE;
       
  1433     COMPtr<IWebPreferences> preferences;
       
  1434     if (SUCCEEDED(d->webView->preferences(&preferences)))
       
  1435         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
       
  1436     return !!privateBrowsingEnabled;
       
  1437 }
       
  1438 
       
  1439 void WebFrame::makeDocumentView()
       
  1440 {
       
  1441     ASSERT(core(this));
       
  1442     
       
  1443     // On the mac, this is done in Frame::setView, but since we don't have separate 
       
  1444     // frame views, we'll just do it here instead.
       
  1445     core(this)->loader()->resetMultipleFormSubmissionProtection();
       
  1446 }
       
  1447 
       
  1448 void WebFrame::makeRepresentation(DocumentLoader*)
       
  1449 {
       
  1450     notImplemented();
       
  1451 }
       
  1452 
       
  1453 void WebFrame::forceLayout()
       
  1454 {
       
  1455     notImplemented();
       
  1456 }
       
  1457 
       
  1458 void WebFrame::forceLayoutForNonHTML()
       
  1459 {
       
  1460     notImplemented();
       
  1461 }
       
  1462 
       
  1463 void WebFrame::setCopiesOnScroll()
       
  1464 {
       
  1465     notImplemented();
       
  1466 }
       
  1467 
       
  1468 void WebFrame::detachedFromParent1()
       
  1469 {
       
  1470     notImplemented();
       
  1471 }
       
  1472 
       
  1473 void WebFrame::detachedFromParent2()
       
  1474 {
       
  1475     notImplemented();
       
  1476 }
       
  1477 
       
  1478 void WebFrame::detachedFromParent3()
       
  1479 {
       
  1480     notImplemented();
       
  1481 }
       
  1482 
       
  1483 void WebFrame::detachedFromParent4()
       
  1484 {
       
  1485     notImplemented();
       
  1486 }
       
  1487 
       
  1488 void WebFrame::loadedFromCachedPage()
       
  1489 {
       
  1490     notImplemented();
       
  1491 }
       
  1492 
       
  1493 void WebFrame::dispatchDidReceiveServerRedirectForProvisionalLoad()
       
  1494 {
       
  1495     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1496     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
       
  1497         frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(d->webView, this);
       
  1498 }
       
  1499 
       
  1500 void WebFrame::dispatchDidCancelClientRedirect()
       
  1501 {
       
  1502     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1503     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
       
  1504         frameLoadDelegate->didCancelClientRedirectForFrame(d->webView, this);
       
  1505 }
       
  1506 
       
  1507 void WebFrame::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
       
  1508 {
       
  1509     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1510     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
       
  1511         frameLoadDelegate->willPerformClientRedirectToURL(d->webView, BString(url.url()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), this);
       
  1512 }
       
  1513 
       
  1514 void WebFrame::dispatchDidChangeLocationWithinPage()
       
  1515 {
       
  1516     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1517     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
       
  1518         frameLoadDelegate->didChangeLocationWithinPageForFrame(d->webView, this);
       
  1519 }
       
  1520 
       
  1521 void WebFrame::dispatchWillClose()
       
  1522 {
       
  1523     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1524     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
       
  1525         frameLoadDelegate->willCloseFrame(d->webView, this);
       
  1526 }
       
  1527 
       
  1528 void WebFrame::dispatchDidReceiveIcon()
       
  1529 {
       
  1530     d->webView->dispatchDidReceiveIconFromWebFrame(this);
       
  1531 }
       
  1532 
       
  1533 void WebFrame::dispatchDidStartProvisionalLoad()
       
  1534 {
       
  1535     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1536     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
       
  1537         frameLoadDelegate->didStartProvisionalLoadForFrame(d->webView, this);
       
  1538 }
       
  1539 
       
  1540 void WebFrame::dispatchDidReceiveTitle(const String& title)
       
  1541 {
       
  1542     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1543     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
       
  1544         frameLoadDelegate->didReceiveTitle(d->webView, BString(title), this);
       
  1545 }
       
  1546 
       
  1547 void WebFrame::dispatchDidCommitLoad()
       
  1548 {
       
  1549     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1550     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) 
       
  1551         frameLoadDelegate->didCommitLoadForFrame(d->webView, this);
       
  1552 }
       
  1553 
       
  1554 void WebFrame::dispatchDidFinishDocumentLoad()
       
  1555 {
       
  1556     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
       
  1557     if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
       
  1558         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(d->webView, this);
       
  1559 }
       
  1560 
       
  1561 void WebFrame::dispatchDidFinishLoad()
       
  1562 {
       
  1563     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  1564     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) 
       
  1565         frameLoadDelegate->didFinishLoadForFrame(d->webView, this);
       
  1566 }
       
  1567 
       
  1568 void WebFrame::dispatchDidFirstLayout()
       
  1569 {
       
  1570     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
       
  1571     if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
       
  1572         frameLoadDelegatePriv->didFirstLayoutInFrame(d->webView, this);
       
  1573 }
       
  1574 
       
  1575 void WebFrame::dispatchShow()
       
  1576 {
       
  1577     COMPtr<IWebUIDelegate> ui;
       
  1578 
       
  1579     if (SUCCEEDED(d->webView->uiDelegate(&ui)))
       
  1580         ui->webViewShow(d->webView);
       
  1581 }
       
  1582 
       
  1583 void WebFrame::cancelPolicyCheck()
       
  1584 {
       
  1585     if (d->m_policyListener) {
       
  1586         d->m_policyListener->invalidate();
       
  1587         d->m_policyListener = 0;
       
  1588     }
       
  1589 
       
  1590     d->m_policyFunction = 0;
       
  1591 }
       
  1592 
       
  1593 void WebFrame::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
       
  1594 {
       
  1595     Frame* coreFrame = core(this);
       
  1596     ASSERT(coreFrame);
       
  1597 
       
  1598     COMPtr<IWebFormDelegate> formDelegate;
       
  1599 
       
  1600     if (FAILED(d->webView->formDelegate(&formDelegate))) {
       
  1601         (coreFrame->loader()->*function)(PolicyUse);
       
  1602         return;
       
  1603     }
       
  1604 
       
  1605     COMPtr<IDOMElement> formElement;
       
  1606     formElement.adoptRef(DOMElement::createInstance(formState->form()));
       
  1607 
       
  1608     // FIXME: The FormValuesPropertyBag constructor should take a const pointer
       
  1609     FormValuesPropertyBag formValuesPropBag(const_cast<HashMap<String, String>*>(&formState->values()));
       
  1610 
       
  1611     COMPtr<WebFrame> sourceFrame(kit(formState->sourceFrame()));
       
  1612     if (SUCCEEDED(formDelegate->willSubmitForm(this, sourceFrame.get(), formElement.get(), &formValuesPropBag, setUpPolicyListener(function).get())))
       
  1613         return;
       
  1614 
       
  1615     // FIXME: Add a sane default implementation
       
  1616     (coreFrame->loader()->*function)(PolicyUse);
       
  1617 }
       
  1618 
       
  1619 void WebFrame::dispatchDidLoadMainResource(DocumentLoader*)
       
  1620 {
       
  1621     notImplemented();
       
  1622 }
       
  1623 
       
  1624 void WebFrame::revertToProvisionalState(DocumentLoader*)
       
  1625 {
       
  1626     notImplemented();
       
  1627 }
       
  1628 
       
  1629 void WebFrame::clearUnarchivingState(DocumentLoader*)
       
  1630 {
       
  1631     notImplemented();
       
  1632 }
       
  1633 
       
  1634 void WebFrame::setMainFrameDocumentReady(bool)
       
  1635 {
       
  1636     notImplemented();
       
  1637 }
       
  1638 
       
  1639 void WebFrame::willChangeTitle(DocumentLoader*)
       
  1640 {
       
  1641     notImplemented();
       
  1642 }
       
  1643 
       
  1644 void WebFrame::didChangeTitle(DocumentLoader*)
       
  1645 {
       
  1646     notImplemented();
       
  1647 }
       
  1648 
       
  1649 void WebFrame::finishedLoading(DocumentLoader* loader)
       
  1650 {
       
  1651     // Telling the frame we received some data and passing 0 as the data is our
       
  1652     // way to get work done that is normally done when the first bit of data is
       
  1653     // received, even for the case of a document with no data (like about:blank)
       
  1654     if (!d->m_pluginView)
       
  1655         committedLoad(loader, 0, 0);
       
  1656     else {
       
  1657         d->m_pluginView->didFinishLoading();
       
  1658         d->m_pluginView = 0;
       
  1659         d->m_hasSentResponseToPlugin = false;
       
  1660     }
       
  1661 }
       
  1662 
       
  1663 void WebFrame::finalSetupForReplace(DocumentLoader*)
       
  1664 {
       
  1665     notImplemented();
       
  1666 }
       
  1667 
       
  1668 void WebFrame::setDefersLoading(bool)
       
  1669 {
       
  1670     notImplemented();
       
  1671 }
       
  1672 
       
  1673 bool WebFrame::isArchiveLoadPending(ResourceLoader*) const
       
  1674 {
       
  1675     notImplemented();
       
  1676     return false;
       
  1677 }
       
  1678 
       
  1679 void WebFrame::cancelPendingArchiveLoad(ResourceLoader*)
       
  1680 {
       
  1681     notImplemented();
       
  1682 }
       
  1683 
       
  1684 void WebFrame::clearArchivedResources()
       
  1685 {
       
  1686     notImplemented();
       
  1687 }
       
  1688 
       
  1689 bool WebFrame::canHandleRequest(const ResourceRequest& request) const
       
  1690 {
       
  1691     return WebView::canHandleRequest(request);
       
  1692 }
       
  1693 
       
  1694 bool WebFrame::canShowMIMEType(const String& /*MIMEType*/) const
       
  1695 {
       
  1696     notImplemented();
       
  1697     return true;
       
  1698 }
       
  1699 
       
  1700 bool WebFrame::representationExistsForURLScheme(const String& /*URLScheme*/) const
       
  1701 {
       
  1702     notImplemented();
       
  1703     return false;
       
  1704 }
       
  1705 
       
  1706 String WebFrame::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
       
  1707 {
       
  1708     notImplemented();
       
  1709     ASSERT_NOT_REACHED();
       
  1710     return String();
       
  1711 }
       
  1712 
       
  1713 void WebFrame::frameLoadCompleted()
       
  1714 {
       
  1715     if (Frame* coreFrame = core(this))
       
  1716         coreFrame->loader()->setPreviousHistoryItem(0);
       
  1717 }
       
  1718 
       
  1719 void WebFrame::restoreViewState()
       
  1720 {
       
  1721     // FIXME: Need to restore view state for page caching
       
  1722     notImplemented();
       
  1723 }
       
  1724 
       
  1725 void WebFrame::provisionalLoadStarted()
       
  1726 {
       
  1727     notImplemented();
       
  1728 }
       
  1729 
       
  1730 bool WebFrame::shouldTreatURLAsSameAsCurrent(const KURL&) const
       
  1731 {
       
  1732     notImplemented();
       
  1733     return false;
       
  1734 }
       
  1735 
       
  1736 void WebFrame::addHistoryItemForFragmentScroll()
       
  1737 {
       
  1738     notImplemented();
       
  1739 }
       
  1740 
       
  1741 void WebFrame::didFinishLoad()
       
  1742 {
       
  1743     notImplemented();
       
  1744 }
       
  1745 
       
  1746 void WebFrame::prepareForDataSourceReplacement()
       
  1747 {
       
  1748     notImplemented();
       
  1749 }
       
  1750 
       
  1751 void WebFrame::setTitle(const String& title, const KURL& url)
       
  1752 {
       
  1753     BOOL privateBrowsingEnabled = FALSE;
       
  1754     COMPtr<IWebPreferences> preferences;
       
  1755     if (SUCCEEDED(d->webView->preferences(&preferences)))
       
  1756         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
       
  1757     if (!privateBrowsingEnabled) {
       
  1758         // update title in global history
       
  1759         COMPtr<WebHistory> history;
       
  1760         history.adoptRef(webHistory());
       
  1761         if (history) {
       
  1762             COMPtr<IWebHistoryItem> item;
       
  1763             if (SUCCEEDED(history->itemForURL(BString(url.url()), &item))) {
       
  1764                 COMPtr<IWebHistoryItemPrivate> itemPrivate;
       
  1765                 if (SUCCEEDED(item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&itemPrivate)))
       
  1766                     itemPrivate->setTitle(BString(title));
       
  1767             }
       
  1768         }
       
  1769     }
       
  1770 }
       
  1771 
       
  1772 String WebFrame::userAgent(const KURL& url)
       
  1773 {
       
  1774     return d->webView->userAgentForKURL(url);
       
  1775 }
       
  1776 
       
  1777 void WebFrame::setDocumentViewFromCachedPage(CachedPage*)
       
  1778 {
       
  1779     notImplemented();
       
  1780 }
       
  1781 
       
  1782 void WebFrame::updateGlobalHistoryForStandardLoad(const KURL& url)
       
  1783 {
       
  1784     COMPtr<WebHistory> history;
       
  1785     history.adoptRef(webHistory());
       
  1786 
       
  1787     if (!history)
       
  1788         return;
       
  1789 
       
  1790     history->addItemForURL(BString(url.url()), 0);                 
       
  1791 }
       
  1792 
       
  1793 void WebFrame::updateGlobalHistoryForReload(const KURL& url)
       
  1794 {
       
  1795     BString urlBStr(url.url());
       
  1796 
       
  1797     COMPtr<WebHistory> history;
       
  1798     history.adoptRef(webHistory());
       
  1799 
       
  1800     if (!history)
       
  1801         return;
       
  1802 
       
  1803     COMPtr<IWebHistoryItem> item;
       
  1804     if (SUCCEEDED(history->itemForURL(urlBStr, &item))) {
       
  1805         COMPtr<IWebHistoryItemPrivate> itemPrivate;
       
  1806         if (SUCCEEDED(item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&itemPrivate))) {
       
  1807             SYSTEMTIME currentTime;
       
  1808             GetSystemTime(&currentTime);
       
  1809             DATE visitedTime = 0;
       
  1810             SystemTimeToVariantTime(&currentTime, &visitedTime);
       
  1811 
       
  1812             // FIXME - bumping the last visited time doesn't mark the history as changed
       
  1813             itemPrivate->setLastVisitedTimeInterval(visitedTime);
       
  1814         }
       
  1815     }
       
  1816 }
       
  1817 
       
  1818 bool WebFrame::shouldGoToHistoryItem(HistoryItem*) const
       
  1819 {
       
  1820     notImplemented();
       
  1821     return true;
       
  1822 }
       
  1823 
       
  1824 void WebFrame::saveViewStateToItem(HistoryItem*)
       
  1825 {
       
  1826     // FIXME: Need to save view state for page caching
       
  1827     notImplemented();
       
  1828 }
       
  1829 
       
  1830 void WebFrame::saveDocumentViewToCachedPage(CachedPage*)
       
  1831 {
       
  1832     notImplemented();
       
  1833 }
       
  1834 
       
  1835 bool WebFrame::canCachePage() const
       
  1836 {
       
  1837     notImplemented();
       
  1838     return false;
       
  1839 }
       
  1840 
       
  1841 PassRefPtr<DocumentLoader> WebFrame::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
       
  1842 {
       
  1843     RefPtr<WebDocumentLoader> loader = new WebDocumentLoader(request, substituteData);
       
  1844  
       
  1845     COMPtr<WebDataSource> dataSource;
       
  1846     dataSource.adoptRef(WebDataSource::createInstance(loader.get()));
       
  1847 
       
  1848     loader->setDataSource(dataSource.get());
       
  1849     return loader.release();
       
  1850 }
       
  1851 
       
  1852 void WebFrame::setMainDocumentError(DocumentLoader*, const ResourceError& error)
       
  1853 {
       
  1854     if (d->m_pluginView) {
       
  1855         d->m_pluginView->didFail(error);
       
  1856         d->m_pluginView = 0;
       
  1857         d->m_hasSentResponseToPlugin = false;
       
  1858     }
       
  1859 }
       
  1860 
       
  1861 ResourceError WebFrame::cancelledError(const ResourceRequest& request)
       
  1862 {
       
  1863     // FIXME: Need ChickenCat to include CFNetwork/CFURLError.h to get these values
       
  1864     // Alternatively, we could create our own error domain/codes.
       
  1865     return ResourceError(String(WebURLErrorDomain), -999, request.url().url(), String());
       
  1866 }
       
  1867 
       
  1868 ResourceError WebFrame::blockedError(const ResourceRequest& request)
       
  1869 {
       
  1870     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
       
  1871     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotUseRestrictedPort, request.url().url(), String());
       
  1872 }
       
  1873 
       
  1874 ResourceError WebFrame::cannotShowURLError(const ResourceRequest&)
       
  1875 {
       
  1876     notImplemented();
       
  1877     return ResourceError();
       
  1878 }
       
  1879 
       
  1880 ResourceError WebFrame::interruptForPolicyChangeError(const ResourceRequest& request)
       
  1881 {
       
  1882     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
       
  1883     return ResourceError(String(WebKitErrorDomain), WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().url(), String());
       
  1884 }
       
  1885 
       
  1886 ResourceError WebFrame::cannotShowMIMETypeError(const ResourceResponse&)
       
  1887 {
       
  1888     notImplemented();
       
  1889     return ResourceError();
       
  1890 }
       
  1891 
       
  1892 ResourceError WebFrame::fileDoesNotExistError(const ResourceResponse&)
       
  1893 {
       
  1894     notImplemented();
       
  1895     return ResourceError();
       
  1896 }
       
  1897 
       
  1898 bool WebFrame::shouldFallBack(const ResourceError& error)
       
  1899 {
       
  1900     return error.errorCode() != WebURLErrorCancelled;
       
  1901 }
       
  1902 
       
  1903 void WebFrame::receivedData(const char* data, int length, const String& textEncoding)
       
  1904 {
       
  1905     Frame* coreFrame = core(this);
       
  1906     if (!coreFrame)
       
  1907         return;
       
  1908 
       
  1909     // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
       
  1910     String encoding = coreFrame->loader()->documentLoader()->overrideEncoding();
       
  1911     bool userChosen = !encoding.isNull();
       
  1912     if (encoding.isNull())
       
  1913         encoding = textEncoding;
       
  1914     coreFrame->loader()->setEncoding(encoding, userChosen);
       
  1915 
       
  1916     coreFrame->loader()->addData(data, length);
       
  1917 }
       
  1918 
       
  1919 COMPtr<WebFramePolicyListener> WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction function)
       
  1920 {
       
  1921     ASSERT(!d->m_policyListener);
       
  1922     ASSERT(!d->m_policyFunction);
       
  1923 
       
  1924     Frame* coreFrame = core(this);
       
  1925     ASSERT(coreFrame);
       
  1926 
       
  1927     d->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
       
  1928     d->m_policyFunction = function;
       
  1929 
       
  1930     return d->m_policyListener;
       
  1931 }
       
  1932 
       
  1933 void WebFrame::receivedPolicyDecision(PolicyAction action)
       
  1934 {
       
  1935     ASSERT(d->m_policyListener);
       
  1936     ASSERT(d->m_policyFunction);
       
  1937 
       
  1938     FramePolicyFunction function = d->m_policyFunction;
       
  1939 
       
  1940     d->m_policyListener = 0;
       
  1941     d->m_policyFunction = 0;
       
  1942 
       
  1943     Frame* coreFrame = core(this);
       
  1944     ASSERT(coreFrame);
       
  1945 
       
  1946     (coreFrame->loader()->*function)(action);
       
  1947 }
       
  1948 
       
  1949 void WebFrame::committedLoad(DocumentLoader* loader, const char* data, int length)
       
  1950 {
       
  1951     // FIXME: This should probably go through the data source.
       
  1952     const String& textEncoding = loader->response().textEncodingName();
       
  1953 
       
  1954     if (!d->m_pluginView)
       
  1955         receivedData(data, length, textEncoding);
       
  1956 
       
  1957     if (d->m_pluginView) {
       
  1958         if (!d->m_hasSentResponseToPlugin) {
       
  1959             d->m_pluginView->didReceiveResponse(d->frame->loader()->documentLoader()->response());
       
  1960             // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
       
  1961             // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
       
  1962             // to null
       
  1963             if (!d->m_pluginView)
       
  1964                 return;
       
  1965             d->m_hasSentResponseToPlugin = true;
       
  1966         }
       
  1967         d->m_pluginView->didReceiveData(data, length);
       
  1968     }
       
  1969 }
       
  1970 
       
  1971 void WebFrame::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const String& mimeType, const ResourceRequest& request)
       
  1972 {
       
  1973     COMPtr<IWebPolicyDelegate> policyDelegate;
       
  1974     if (SUCCEEDED(d->webView->policyDelegate(&policyDelegate))) {
       
  1975         COMPtr<IWebURLRequest> urlRequest;
       
  1976         urlRequest.adoptRef(WebMutableURLRequest::createInstance(request));
       
  1977         if (SUCCEEDED(policyDelegate->decidePolicyForMIMEType(d->webView, BString(mimeType), urlRequest.get(), this, setUpPolicyListener(function).get())))
       
  1978             return;
       
  1979     }
       
  1980 
       
  1981     Frame* coreFrame = core(this);
       
  1982     ASSERT(coreFrame);
       
  1983 
       
  1984     // FIXME: This is a stopgap default implementation to tide us over until
       
  1985     // <rdar://4911042/> is taken care of
       
  1986     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType) || MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
       
  1987         (coreFrame->loader()->*function)(PolicyUse);
       
  1988     else
       
  1989         (coreFrame->loader()->*function)(PolicyDownload);
       
  1990 }
       
  1991 
       
  1992 void WebFrame::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, const String& frameName)
       
  1993 {
       
  1994     Frame* coreFrame = core(this);
       
  1995     ASSERT(coreFrame);
       
  1996 
       
  1997     COMPtr<IWebPolicyDelegate> policyDelegate;
       
  1998     if (SUCCEEDED(d->webView->policyDelegate(&policyDelegate))) {
       
  1999         COMPtr<IWebURLRequest> urlRequest;
       
  2000         urlRequest.adoptRef(WebMutableURLRequest::createInstance(request));
       
  2001         COMPtr<WebActionPropertyBag> actionInformation;
       
  2002         actionInformation.adoptRef(WebActionPropertyBag::createInstance(action, coreFrame));
       
  2003 
       
  2004         if (SUCCEEDED(policyDelegate->decidePolicyForNewWindowAction(d->webView, actionInformation.get(), urlRequest.get(), BString(frameName), setUpPolicyListener(function).get())))
       
  2005             return;
       
  2006     }
       
  2007 
       
  2008     // FIXME: Add a sane default implementation
       
  2009     (coreFrame->loader()->*function)(PolicyUse);
       
  2010 }
       
  2011 
       
  2012 void WebFrame::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request)
       
  2013 {
       
  2014     Frame* coreFrame = core(this);
       
  2015     ASSERT(coreFrame);
       
  2016 
       
  2017     COMPtr<IWebPolicyDelegate> policyDelegate;
       
  2018     if (SUCCEEDED(d->webView->policyDelegate(&policyDelegate))) {
       
  2019         COMPtr<IWebURLRequest> urlRequest;
       
  2020         urlRequest.adoptRef(WebMutableURLRequest::createInstance(request));
       
  2021         COMPtr<WebActionPropertyBag> actionInformation;
       
  2022         actionInformation.adoptRef(WebActionPropertyBag::createInstance(action, coreFrame));
       
  2023 
       
  2024         if (SUCCEEDED(policyDelegate->decidePolicyForNavigationAction(d->webView, actionInformation.get(), urlRequest.get(), this, setUpPolicyListener(function).get())))
       
  2025             return;
       
  2026     }
       
  2027 
       
  2028     // FIXME: Add a sane default implementation
       
  2029     (coreFrame->loader()->*function)(PolicyUse);
       
  2030 }
       
  2031 
       
  2032 void WebFrame::dispatchUnableToImplementPolicy(const ResourceError& error)
       
  2033 {
       
  2034     COMPtr<IWebPolicyDelegate> policyDelegate;
       
  2035     if (SUCCEEDED(d->webView->policyDelegate(&policyDelegate))) {
       
  2036         COMPtr<IWebError> webError;
       
  2037         webError.adoptRef(WebError::createInstance(error));
       
  2038         policyDelegate->unableToImplementPolicyWithError(d->webView, webError.get(), this);
       
  2039     }
       
  2040 }
       
  2041 
       
  2042 void WebFrame::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest&, const ResourceResponse& response)
       
  2043 {
       
  2044     COMPtr<IWebDownloadDelegate> downloadDelegate;
       
  2045     COMPtr<IWebView> webView;
       
  2046     if (SUCCEEDED(this->webView(&webView))) {
       
  2047         if (FAILED(webView->downloadDelegate(&downloadDelegate))) {
       
  2048             // If the WebView doesn't successfully provide a download delegate we'll pass a null one
       
  2049             // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
       
  2050             LOG_ERROR("Failed to get downloadDelegate from WebView");
       
  2051             downloadDelegate = 0;
       
  2052         }
       
  2053     }
       
  2054 
       
  2055     // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
       
  2056     // when this method returns
       
  2057     COMPtr<WebDownload> download;
       
  2058     download.adoptRef(WebDownload::createInstance(handle, request, response, downloadDelegate.get()));
       
  2059 }
       
  2060 
       
  2061 bool WebFrame::willUseArchive(ResourceLoader*, const ResourceRequest&, const KURL&) const
       
  2062 {
       
  2063     notImplemented();
       
  2064     return false;
       
  2065 }
       
  2066 
       
  2067 void WebFrame::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
       
  2068 {
       
  2069     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2070     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
       
  2071         COMPtr<IWebURLRequest> webURLRequest;
       
  2072         webURLRequest.adoptRef(WebMutableURLRequest::createInstance(request));
       
  2073 
       
  2074         resourceLoadDelegate->identifierForInitialRequest(d->webView, webURLRequest.get(), getWebDataSource(loader), identifier);
       
  2075     }
       
  2076 }
       
  2077 
       
  2078 void WebFrame::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
       
  2079 {
       
  2080     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2081     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
       
  2082         COMPtr<IWebURLRequest> webURLRequest;
       
  2083         webURLRequest.adoptRef(WebMutableURLRequest::createInstance(request));
       
  2084         COMPtr<IWebURLResponse> webURLRedirectResponse;
       
  2085         webURLRedirectResponse.adoptRef(WebURLResponse::createInstance(redirectResponse));
       
  2086         COMPtr<IWebURLRequest> newWebURLRequest;
       
  2087 
       
  2088         if (FAILED(resourceLoadDelegate->willSendRequest(d->webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
       
  2089             return;
       
  2090 
       
  2091         if (webURLRequest == newWebURLRequest)
       
  2092             return;
       
  2093 
       
  2094         COMPtr<WebMutableURLRequest> newWebURLRequestImpl;
       
  2095         if (FAILED(newWebURLRequest->QueryInterface(CLSID_WebMutableURLRequest, (void**)&newWebURLRequestImpl)))
       
  2096             return;
       
  2097 
       
  2098         request = newWebURLRequestImpl->resourceRequest();
       
  2099     }
       
  2100 }
       
  2101 
       
  2102 void WebFrame::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
       
  2103 {
       
  2104     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2105     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
       
  2106         COMPtr<IWebURLResponse> webURLResponse;
       
  2107         webURLResponse.adoptRef(WebURLResponse::createInstance(response));
       
  2108 
       
  2109         resourceLoadDelegate->didReceiveResponse(d->webView, identifier, webURLResponse.get(), getWebDataSource(loader));
       
  2110     }
       
  2111 }
       
  2112 
       
  2113 void WebFrame::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
       
  2114 {
       
  2115     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2116     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
       
  2117         resourceLoadDelegate->didReceiveContentLength(d->webView, identifier, length, getWebDataSource(loader));
       
  2118 }
       
  2119 
       
  2120 void WebFrame::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
       
  2121 {
       
  2122     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2123     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
       
  2124         resourceLoadDelegate->didFinishLoadingFromDataSource(d->webView, identifier, getWebDataSource(loader));
       
  2125 }
       
  2126 
       
  2127 void WebFrame::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
       
  2128 {
       
  2129     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2130     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
       
  2131         COMPtr<IWebError> webError;
       
  2132         webError.adoptRef(WebError::createInstance(error));
       
  2133         resourceLoadDelegate->didFailLoadingWithError(d->webView, identifier, webError.get(), getWebDataSource(loader));
       
  2134     }
       
  2135 }
       
  2136 
       
  2137 bool WebFrame::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
       
  2138 {
       
  2139     notImplemented();
       
  2140     return false;
       
  2141 }
       
  2142 
       
  2143 void WebFrame::dispatchDidFailProvisionalLoad(const ResourceError& error)
       
  2144 {
       
  2145     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  2146     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
       
  2147         COMPtr<IWebError> webError;
       
  2148         webError.adoptRef(WebError::createInstance(error));
       
  2149         frameLoadDelegate->didFailProvisionalLoadWithError(d->webView, webError.get(), this);
       
  2150     }
       
  2151 }
       
  2152 
       
  2153 void WebFrame::dispatchDidFailLoad(const ResourceError& error)
       
  2154 {
       
  2155     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  2156     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
       
  2157         COMPtr<IWebError> webError;
       
  2158         webError.adoptRef(WebError::createInstance(error));
       
  2159         frameLoadDelegate->didFailLoadWithError(d->webView, webError.get(), this);
       
  2160     }
       
  2161 }
       
  2162 
       
  2163 Frame* WebFrame::dispatchCreatePage()
       
  2164 {
       
  2165     COMPtr<IWebUIDelegate> ui;
       
  2166 
       
  2167     if (SUCCEEDED(d->webView->uiDelegate(&ui))) {
       
  2168         COMPtr<IWebView> newWebView;
       
  2169 
       
  2170         if (SUCCEEDED(ui->createWebViewWithRequest(d->webView, 0, &newWebView))) {
       
  2171             COMPtr<IWebFrame> mainFrame;
       
  2172 
       
  2173             if (SUCCEEDED(newWebView->mainFrame(&mainFrame))) {
       
  2174                 COMPtr<WebFrame> mainFrameImpl;
       
  2175 
       
  2176                 if (SUCCEEDED(mainFrame->QueryInterface(IID_WebFrame, (void**)&mainFrameImpl)))
       
  2177                     return core(mainFrameImpl.get());
       
  2178             }
       
  2179         }
       
  2180     }
       
  2181     return 0;
       
  2182 }
       
  2183 
       
  2184 void WebFrame::postProgressStartedNotification()
       
  2185 {
       
  2186     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
       
  2187     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
       
  2188     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(d->webView), 0);
       
  2189 }
       
  2190 
       
  2191 void WebFrame::postProgressEstimateChangedNotification()
       
  2192 {
       
  2193     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
       
  2194     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
       
  2195     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(d->webView), 0);
       
  2196 }
       
  2197 
       
  2198 void WebFrame::postProgressFinishedNotification()
       
  2199 {
       
  2200     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
       
  2201     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
       
  2202     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(d->webView), 0);
       
  2203 }
       
  2204 
       
  2205 void WebFrame::startDownload(const ResourceRequest&)
       
  2206 {
       
  2207     notImplemented();
       
  2208 }
       
  2209 
       
  2210 void WebFrame::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
       
  2211 {
       
  2212     ASSERT(challenge.sourceHandle());
       
  2213 
       
  2214     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2215     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
       
  2216         COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
       
  2217 
       
  2218         if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(d->webView, identifier, webChallenge.get(), getWebDataSource(loader))))
       
  2219             return;
       
  2220     }
       
  2221 
       
  2222     // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
       
  2223     // to continue without credential - this is the best approximation of Mac behavior
       
  2224     challenge.sourceHandle()->receivedRequestToContinueWithoutCredential(challenge);
       
  2225 }
       
  2226 
       
  2227 void WebFrame::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
       
  2228 {
       
  2229     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2230     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
       
  2231         COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
       
  2232 
       
  2233         if (SUCCEEDED(resourceLoadDelegate->didCancelAuthenticationChallenge(d->webView, identifier, webChallenge.get(), getWebDataSource(loader))))
       
  2234             return;
       
  2235     }
       
  2236 }
       
  2237 
       
  2238 PassRefPtr<Frame> WebFrame::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
       
  2239                             const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
       
  2240 {
       
  2241     RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
       
  2242     if (!result)
       
  2243         return 0;
       
  2244 
       
  2245     // Propagate the marginwidth/height and scrolling modes to the view.
       
  2246     if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag)) {
       
  2247         HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
       
  2248         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
       
  2249             result->view()->setScrollbarsMode(ScrollbarAlwaysOff);
       
  2250         int marginWidth = frameElt->getMarginWidth();
       
  2251         int marginHeight = frameElt->getMarginHeight();
       
  2252         if (marginWidth != -1)
       
  2253             result->view()->setMarginWidth(marginWidth);
       
  2254         if (marginHeight != -1)
       
  2255             result->view()->setMarginHeight(marginHeight);
       
  2256     }
       
  2257 
       
  2258     return result.release();
       
  2259 }
       
  2260 
       
  2261 Widget* WebFrame::createPlugin(const IntSize& pluginSize, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
       
  2262 {
       
  2263     PluginViewWin* pluginView = PluginDatabaseWin::installedPlugins()->createPluginView(core(this), pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
       
  2264 
       
  2265     if (pluginView->status() == PluginStatusLoadedSuccessfully)
       
  2266         return pluginView;
       
  2267 
       
  2268     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2269 
       
  2270     if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
       
  2271         return pluginView;
       
  2272 
       
  2273     RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
       
  2274 
       
  2275     unsigned count = (unsigned)paramNames.size();
       
  2276     for (unsigned i = 0; i < count; i++) {
       
  2277         if (paramNames[i] == "pluginspage") {
       
  2278             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
       
  2279             RetainPtr<CFStringRef> str(AdoptCF, paramValues[i].createCFString());
       
  2280             CFDictionarySetValue(userInfo.get(), key, str.get());
       
  2281             break;
       
  2282         }
       
  2283     }
       
  2284 
       
  2285     if (!mimeType.isNull()) {
       
  2286         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
       
  2287 
       
  2288         RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString());
       
  2289         CFDictionarySetValue(userInfo.get(), key, str.get());
       
  2290     }
       
  2291 
       
  2292     String pluginName;
       
  2293     if (pluginView->plugin())
       
  2294         pluginName = pluginView->plugin()->name();
       
  2295     if (!pluginName.isNull()) {
       
  2296         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
       
  2297         RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString());
       
  2298         CFDictionarySetValue(userInfo.get(), key, str.get());
       
  2299     }
       
  2300 
       
  2301     COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
       
  2302     userInfoBag->setDictionary(userInfo.get());
       
  2303  
       
  2304     int errorCode = 0;
       
  2305     switch (pluginView->status()) {
       
  2306         case PluginStatusCanNotFindPlugin:
       
  2307             errorCode = WebKitErrorCannotFindPlugIn;
       
  2308             break;
       
  2309         case PluginStatusCanNotLoadPlugin:
       
  2310             errorCode = WebKitErrorCannotLoadPlugIn;
       
  2311             break;
       
  2312         default:
       
  2313             ASSERT_NOT_REACHED();
       
  2314     }
       
  2315 
       
  2316     ResourceError resourceError(String(WebKitErrorDomain), errorCode, url.url(), String());
       
  2317     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
       
  2318      
       
  2319     resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
       
  2320 
       
  2321     return pluginView;
       
  2322 }
       
  2323 
       
  2324 void WebFrame::redirectDataToPlugin(Widget* pluginWidget)
       
  2325 {
       
  2326     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
       
  2327 
       
  2328     d->m_pluginView = static_cast<PluginViewWin*>(pluginWidget);
       
  2329 }
       
  2330 
       
  2331 Widget* WebFrame::createJavaAppletWidget(const IntSize& pluginSize, Element* element, const KURL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
       
  2332 {
       
  2333     PluginViewWin* pluginView = PluginDatabaseWin::installedPlugins()->
       
  2334         createPluginView(core(this), pluginSize, element, KURL(), paramNames, paramValues, "application/x-java-applet", false);
       
  2335 
       
  2336     // Check if the plugin can be loaded successfully
       
  2337     if (pluginView->plugin()->load())
       
  2338         return pluginView;
       
  2339 
       
  2340     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
       
  2341     if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
       
  2342         return pluginView;
       
  2343 
       
  2344     COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
       
  2345 
       
  2346     ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, String(), String());
       
  2347     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
       
  2348      
       
  2349     resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
       
  2350 
       
  2351     return pluginView;
       
  2352 }
       
  2353 
       
  2354 ObjectContentType WebFrame::objectContentType(const KURL& url, const String& mimeTypeIn)
       
  2355 {
       
  2356     String mimeType = mimeTypeIn;
       
  2357     if (mimeType.isEmpty())
       
  2358         mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().mid(url.path().findRev('.')+1));
       
  2359 
       
  2360     if (mimeType.isEmpty())
       
  2361         return ObjectContentFrame; // Go ahead and hope that we can display the content.
       
  2362 
       
  2363     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
       
  2364         return WebCore::ObjectContentImage;
       
  2365 
       
  2366     if (PluginDatabaseWin::installedPlugins()->isMIMETypeRegistered(mimeType))
       
  2367         return WebCore::ObjectContentNetscapePlugin;
       
  2368 
       
  2369     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
       
  2370         return WebCore::ObjectContentFrame;
       
  2371 
       
  2372     return WebCore::ObjectContentNone;
       
  2373 }
       
  2374 
       
  2375 String WebFrame::overrideMediaType() const
       
  2376 {
       
  2377     notImplemented();
       
  2378     return String();
       
  2379 }
       
  2380 
       
  2381 void WebFrame::windowObjectCleared() const
       
  2382 {
       
  2383     Frame* coreFrame = core(this);
       
  2384     ASSERT(coreFrame);
       
  2385 
       
  2386     Settings* settings = coreFrame->settings();
       
  2387     if (!settings || !settings->isJavaScriptEnabled())
       
  2388         return;
       
  2389 
       
  2390     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
       
  2391     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
       
  2392         JSContextRef context = toRef(coreFrame->scriptProxy()->interpreter()->globalExec());
       
  2393         JSObjectRef windowObject = toRef(KJS::Window::retrieve(coreFrame)->getObject());
       
  2394         ASSERT(windowObject);
       
  2395 
       
  2396         frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
       
  2397     }
       
  2398 }
       
  2399 
       
  2400 void WebFrame::didPerformFirstNavigation() const
       
  2401 {
       
  2402 }
       
  2403 
       
  2404 void WebFrame::registerForIconNotification(bool listen)
       
  2405 {
       
  2406     d->webView->registerForIconNotification(listen);
       
  2407 }
       
  2408 
       
  2409 static IntRect printerRect(HDC printDC)
       
  2410 {
       
  2411     return IntRect(0, 0, 
       
  2412                    GetDeviceCaps(printDC, PHYSICALWIDTH)  - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX),
       
  2413                    GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
       
  2414 }
       
  2415 
       
  2416 void WebFrame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
       
  2417 {
       
  2418     Frame* coreFrame = core(this);
       
  2419     ASSERT(coreFrame);
       
  2420     coreFrame->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize);
       
  2421 }
       
  2422 
       
  2423 HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode( 
       
  2424     /* [in] */ BOOL value,
       
  2425     /* [in] */ HDC printDC)
       
  2426 {
       
  2427     if (m_inPrintingMode == !!value)
       
  2428         return S_OK;
       
  2429 
       
  2430     Frame* coreFrame = core(this);
       
  2431     if (!coreFrame)
       
  2432         return E_FAIL;
       
  2433 
       
  2434     m_inPrintingMode = !!value;
       
  2435 
       
  2436     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
       
  2437     // according to the paper size
       
  2438     float minLayoutWidth = 0.0f;
       
  2439     float maxLayoutWidth = 0.0f;
       
  2440     if (m_inPrintingMode && !coreFrame->isFrameSet()) {
       
  2441         if (!printDC) {
       
  2442             ASSERT_NOT_REACHED();
       
  2443             return E_POINTER;
       
  2444         }
       
  2445 
       
  2446         const int desiredHorizontalPixelsPerInch = 72;
       
  2447         int paperHorizontalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSX);
       
  2448         int paperWidth = printerRect(printDC).width() * desiredHorizontalPixelsPerInch / paperHorizontalPixelsPerInch;
       
  2449         minLayoutWidth = paperWidth * PrintingMinimumShrinkFactor;
       
  2450         maxLayoutWidth = paperWidth * PrintingMaximumShrinkFactor;
       
  2451     }
       
  2452 
       
  2453     setPrinting(m_inPrintingMode, minLayoutWidth, maxLayoutWidth, true);
       
  2454 
       
  2455     if (!m_inPrintingMode)
       
  2456         m_pageRects.clear();
       
  2457 
       
  2458     return S_OK;
       
  2459 }
       
  2460 
       
  2461 void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
       
  2462 {
       
  2463     if (headerHeight)
       
  2464         *headerHeight = 0;
       
  2465     if (footerHeight)
       
  2466         *footerHeight = 0;
       
  2467     float height = 0;
       
  2468     COMPtr<IWebUIDelegate> ui;
       
  2469     if (FAILED(d->webView->uiDelegate(&ui)))
       
  2470         return;
       
  2471     COMPtr<IWebUIDelegate2> ui2;
       
  2472     if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
       
  2473         return;
       
  2474     if (headerHeight && SUCCEEDED(ui2->webViewHeaderHeight(d->webView, &height)))
       
  2475         *headerHeight = height;
       
  2476     if (footerHeight && SUCCEEDED(ui2->webViewFooterHeight(d->webView, &height)))
       
  2477         *footerHeight = height;
       
  2478 }
       
  2479 
       
  2480 IntRect WebFrame::printerMarginRect(HDC printDC)
       
  2481 {
       
  2482     IntRect emptyRect(0, 0, 0, 0);
       
  2483 
       
  2484     COMPtr<IWebUIDelegate> ui;
       
  2485     if (FAILED(d->webView->uiDelegate(&ui)))
       
  2486         return emptyRect;
       
  2487     COMPtr<IWebUIDelegate2> ui2;
       
  2488     if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
       
  2489         return emptyRect;
       
  2490 
       
  2491     RECT rect;
       
  2492     if (FAILED(ui2->webViewPrintingMarginRect(d->webView, &rect)))
       
  2493         return emptyRect;
       
  2494 
       
  2495     rect.left = MulDiv(rect.left, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
       
  2496     rect.top = MulDiv(rect.top, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
       
  2497     rect.right = MulDiv(rect.right, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
       
  2498     rect.bottom = MulDiv(rect.bottom, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
       
  2499 
       
  2500     return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top);
       
  2501 }
       
  2502 
       
  2503 const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
       
  2504 {
       
  2505     ASSERT(m_inPrintingMode);
       
  2506     
       
  2507     Frame* coreFrame = core(this);
       
  2508     ASSERT(coreFrame);
       
  2509     ASSERT(coreFrame->document());
       
  2510 
       
  2511     if (!printDC)
       
  2512         return m_pageRects;
       
  2513 
       
  2514     // adjust the page rect by the header and footer
       
  2515     float headerHeight = 0, footerHeight = 0;
       
  2516     headerAndFooterHeights(&headerHeight, &footerHeight);
       
  2517     IntRect pageRect = printerRect(printDC);
       
  2518     IntRect marginRect = printerMarginRect(printDC);
       
  2519     IntRect adjustedRect = IntRect(
       
  2520         pageRect.x() + marginRect.x(),
       
  2521         pageRect.y() + marginRect.y(),
       
  2522         pageRect.width() - marginRect.x() - marginRect.right(),
       
  2523         pageRect.height() - marginRect.y() - marginRect.bottom());
       
  2524 
       
  2525     computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight);
       
  2526     
       
  2527     return m_pageRects;
       
  2528 }
       
  2529 
       
  2530 HRESULT STDMETHODCALLTYPE WebFrame::getPrintedPageCount( 
       
  2531     /* [in] */ HDC printDC,
       
  2532     /* [retval][out] */ UINT *pageCount)
       
  2533 {
       
  2534     if (!pageCount || !printDC) {
       
  2535         ASSERT_NOT_REACHED();
       
  2536         return E_POINTER;
       
  2537     }
       
  2538 
       
  2539     *pageCount = 0;
       
  2540 
       
  2541     if (!m_inPrintingMode) {
       
  2542         ASSERT_NOT_REACHED();
       
  2543         return E_FAIL;
       
  2544     }
       
  2545 
       
  2546     Frame* coreFrame = core(this);
       
  2547     if (!coreFrame || !coreFrame->document())
       
  2548         return E_FAIL;
       
  2549 
       
  2550     const Vector<IntRect>& pages = computePageRects(printDC);
       
  2551     *pageCount = (UINT) pages.size();
       
  2552     
       
  2553     return S_OK;
       
  2554 }
       
  2555 
       
  2556 HRESULT STDMETHODCALLTYPE WebFrame::spoolPages( 
       
  2557     /* [in] */ HDC printDC,
       
  2558     /* [in] */ UINT startPage,
       
  2559     /* [in] */ UINT endPage,
       
  2560     /* [retval][out] */ void* ctx)
       
  2561 {
       
  2562     if (!printDC || !ctx) {
       
  2563         ASSERT_NOT_REACHED();
       
  2564         return E_POINTER;
       
  2565     }
       
  2566 
       
  2567     if (!m_inPrintingMode) {
       
  2568         ASSERT_NOT_REACHED();
       
  2569         return E_FAIL;
       
  2570     }
       
  2571 
       
  2572     Frame* coreFrame = core(this);
       
  2573     if (!coreFrame || !coreFrame->document())
       
  2574         return E_FAIL;
       
  2575 
       
  2576     UINT pageCount = (UINT) m_pageRects.size();
       
  2577     PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
       
  2578 
       
  2579     if (!pageCount || startPage > pageCount) {
       
  2580         ASSERT_NOT_REACHED();
       
  2581         return E_FAIL;
       
  2582     }
       
  2583 
       
  2584     if (startPage > 0)
       
  2585         startPage--;
       
  2586 
       
  2587     if (endPage == 0)
       
  2588         endPage = pageCount;
       
  2589 
       
  2590     COMPtr<IWebUIDelegate> ui;
       
  2591     if (FAILED(d->webView->uiDelegate(&ui)))
       
  2592         return E_FAIL;
       
  2593     // FIXME: we can return early after the updated app is released
       
  2594     COMPtr<IWebUIDelegate2> ui2;
       
  2595     if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
       
  2596         ui2 = 0;
       
  2597 
       
  2598     float headerHeight = 0, footerHeight = 0;
       
  2599     headerAndFooterHeights(&headerHeight, &footerHeight);
       
  2600     GraphicsContext spoolCtx(pctx);
       
  2601 
       
  2602     for (UINT ii = startPage; ii < endPage; ii++) {
       
  2603         IntRect pageRect = m_pageRects[ii];
       
  2604 
       
  2605         CGContextSaveGState(pctx);
       
  2606 
       
  2607         IntRect printRect = printerRect(printDC);
       
  2608         CGRect mediaBox = CGRectMake(CGFloat(0),
       
  2609                                      CGFloat(0),
       
  2610                                      CGFloat(printRect.width()),
       
  2611                                      CGFloat(printRect.height()));
       
  2612 
       
  2613         CGContextBeginPage(pctx, &mediaBox);
       
  2614 
       
  2615         CGFloat scale = (float)mediaBox.size.width/ (float)pageRect.width();
       
  2616         CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
       
  2617         ctm = CGAffineTransformScale(ctm, -scale, -scale);
       
  2618         ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
       
  2619         CGContextScaleCTM(pctx, scale, scale);
       
  2620         CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight));   // reserves space for header
       
  2621         CGContextSetBaseCTM(pctx, ctm);
       
  2622 
       
  2623         coreFrame->paint(&spoolCtx, pageRect);
       
  2624 
       
  2625         if (ui2) {
       
  2626             CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);
       
  2627 
       
  2628             int x = pageRect.x();
       
  2629             int y = 0;
       
  2630             if (headerHeight) {
       
  2631                 RECT headerRect = {x, y, x+pageRect.width(), y+(int)headerHeight};
       
  2632                 ui2->drawHeaderInRect(d->webView, &headerRect, (OLE_HANDLE)(LONG64)pctx);
       
  2633             }
       
  2634 
       
  2635             if (footerHeight) {
       
  2636                 y = max((int)headerHeight+pageRect.height(), m_pageHeight-(int)footerHeight);
       
  2637                 RECT footerRect = {x, y, x+pageRect.width(), y+(int)footerHeight};
       
  2638                 ui2->drawFooterInRect(d->webView, &footerRect, (OLE_HANDLE)(LONG64)pctx, ii+1, pageCount);
       
  2639             }
       
  2640         }
       
  2641 
       
  2642         CGContextEndPage(pctx);
       
  2643         CGContextRestoreGState(pctx);
       
  2644     }
       
  2645  
       
  2646     return S_OK;
       
  2647 }
       
  2648 
       
  2649 HRESULT STDMETHODCALLTYPE WebFrame::isFrameSet( 
       
  2650     /* [retval][out] */ BOOL* result)
       
  2651 {
       
  2652     *result = FALSE;
       
  2653 
       
  2654     Frame* coreFrame = core(this);
       
  2655     if (!coreFrame)
       
  2656         return E_FAIL;
       
  2657 
       
  2658     *result = coreFrame->isFrameSet() ? TRUE : FALSE;
       
  2659     return S_OK;
       
  2660 }
       
  2661 
       
  2662 HRESULT STDMETHODCALLTYPE WebFrame::string( 
       
  2663     /* [retval][out] */ BSTR *result)
       
  2664 {
       
  2665     *result = 0;
       
  2666 
       
  2667     Frame* coreFrame = core(this);
       
  2668     if (!coreFrame)
       
  2669         return E_FAIL;
       
  2670 
       
  2671     RefPtr<Range> allRange(rangeOfContents(coreFrame->document()));
       
  2672     DeprecatedString allString = plainText(allRange.get());
       
  2673     *result = BString(allString).release();
       
  2674     return S_OK;
       
  2675 }
       
  2676 
       
  2677 HRESULT STDMETHODCALLTYPE WebFrame::size( 
       
  2678     /* [retval][out] */ SIZE *size)
       
  2679 {
       
  2680     if (!size)
       
  2681         return E_POINTER;
       
  2682     size->cx = size->cy = 0;
       
  2683 
       
  2684     Frame* coreFrame = core(this);
       
  2685     if (!coreFrame)
       
  2686         return E_FAIL;
       
  2687     FrameView* view = coreFrame->view();
       
  2688     if (!view)
       
  2689         return E_FAIL;
       
  2690     size->cx = view->width();
       
  2691     size->cy = view->height();
       
  2692     return S_OK;
       
  2693 }
       
  2694 
       
  2695 HRESULT STDMETHODCALLTYPE WebFrame::hasScrollBars( 
       
  2696     /* [retval][out] */ BOOL *result)
       
  2697 {
       
  2698     if (!result)
       
  2699         return E_POINTER;
       
  2700     *result = FALSE;
       
  2701 
       
  2702     Frame* coreFrame = core(this);
       
  2703     if (!coreFrame)
       
  2704         return E_FAIL;
       
  2705 
       
  2706     FrameView* view = coreFrame->view();
       
  2707     if (!view)
       
  2708         return E_FAIL;
       
  2709 
       
  2710     if (view->vScrollbarMode() == ScrollbarAlwaysOn || view->visibleHeight() < view->contentsHeight() ||
       
  2711             view->hScrollbarMode() == ScrollbarAlwaysOn || view->visibleWidth() < view->contentsWidth())
       
  2712         *result = TRUE;
       
  2713 
       
  2714     return S_OK;
       
  2715 }
       
  2716 
       
  2717 HRESULT STDMETHODCALLTYPE WebFrame::contentBounds( 
       
  2718     /* [retval][out] */ RECT *result)
       
  2719 {
       
  2720     if (!result)
       
  2721         return E_POINTER;
       
  2722     ::SetRectEmpty(result);
       
  2723 
       
  2724     Frame* coreFrame = core(this);
       
  2725     if (!coreFrame)
       
  2726         return E_FAIL;
       
  2727 
       
  2728     FrameView* view = coreFrame->view();
       
  2729     if (!view)
       
  2730         return E_FAIL;
       
  2731 
       
  2732     result->bottom = view->contentsHeight();
       
  2733     result->right = view->contentsWidth();
       
  2734     return S_OK;
       
  2735 }
       
  2736 
       
  2737 HRESULT STDMETHODCALLTYPE WebFrame::frameBounds( 
       
  2738     /* [retval][out] */ RECT *result)
       
  2739 {
       
  2740     if (!result)
       
  2741         return E_POINTER;
       
  2742     ::SetRectEmpty(result);
       
  2743 
       
  2744     Frame* coreFrame = core(this);
       
  2745     if (!coreFrame)
       
  2746         return E_FAIL;
       
  2747 
       
  2748     FrameView* view = coreFrame->view();
       
  2749     if (!view)
       
  2750         return E_FAIL;
       
  2751 
       
  2752     FloatRect bounds = view->visibleContentRectConsideringExternalScrollers();
       
  2753     result->bottom = (LONG) bounds.height();
       
  2754     result->right = (LONG) bounds.width();
       
  2755     return S_OK;
       
  2756 }
       
  2757 
       
  2758 HRESULT STDMETHODCALLTYPE WebFrame::isDescendantOfFrame( 
       
  2759     /* [in] */ IWebFrame *ancestor,
       
  2760     /* [retval][out] */ BOOL *result)
       
  2761 {
       
  2762     if (!result)
       
  2763         return E_POINTER;
       
  2764     *result = FALSE;
       
  2765 
       
  2766     Frame* coreFrame = core(this);
       
  2767     COMPtr<WebFrame> ancestorWebFrame;
       
  2768     if (!ancestor || FAILED(ancestor->QueryInterface(IID_WebFrame, (void**)&ancestorWebFrame)))
       
  2769         return S_OK;
       
  2770 
       
  2771     *result = (coreFrame && coreFrame->tree()->isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
       
  2772     return S_OK;
       
  2773 }
       
  2774 
       
  2775 void WebFrame::unmarkAllMisspellings()
       
  2776 {
       
  2777     Frame* coreFrame = core(this);
       
  2778     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
  2779         Document *doc = frame->document();
       
  2780         if (!doc)
       
  2781             return;
       
  2782 
       
  2783         doc->removeMarkers(DocumentMarker::Spelling);
       
  2784     }
       
  2785 }
       
  2786 
       
  2787 void WebFrame::unmarkAllBadGrammar()
       
  2788 {
       
  2789     Frame* coreFrame = core(this);
       
  2790     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
       
  2791         Document *doc = frame->document();
       
  2792         if (!doc)
       
  2793             return;
       
  2794 
       
  2795         doc->removeMarkers(DocumentMarker::Grammar);
       
  2796     }
       
  2797 }