[Release] Webkit2-efl-123997_0.11.86
[framework/web/webkit-efl.git] / Source / WebKit / win / WebFrame.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
3  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28 #include "WebKitDLL.h"
29 #include "WebFrame.h"
30
31 #include "CFDictionaryPropertyBag.h"
32 #include "COMPropertyBag.h"
33 #include "DOMCoreClasses.h"
34 #include "DefaultPolicyDelegate.h"
35 #include "HTMLFrameOwnerElement.h"
36 #include "MarshallingHelpers.h"
37 #include "WebActionPropertyBag.h"
38 #include "WebChromeClient.h"
39 #include "WebDataSource.h"
40 #include "WebDocumentLoader.h"
41 #include "WebDownload.h"
42 #include "WebEditorClient.h"
43 #include "WebError.h"
44 #include "WebFrameNetworkingContext.h"
45 #include "WebFramePolicyListener.h"
46 #include "WebHistory.h"
47 #include "WebHistoryItem.h"
48 #include "WebKit.h"
49 #include "WebKitStatisticsPrivate.h"
50 #include "WebMutableURLRequest.h"
51 #include "WebNotificationCenter.h"
52 #include "WebScriptWorld.h"
53 #include "WebURLResponse.h"
54 #include "WebView.h"
55 #include <WebCore/BString.h>
56 #include <WebCore/COMPtr.h>
57 #include <WebCore/MemoryCache.h>
58 #include <WebCore/Document.h>
59 #include <WebCore/DocumentLoader.h>
60 #include <WebCore/DocumentMarkerController.h>
61 #include <WebCore/DOMImplementation.h>
62 #include <WebCore/DOMWindow.h>
63 #include <WebCore/Event.h>
64 #include <WebCore/EventHandler.h>
65 #include <WebCore/FormState.h>
66 #include <WebCore/Frame.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/HTMLAppletElement.h>
76 #include <WebCore/HTMLFormElement.h>
77 #include <WebCore/HTMLFormControlElement.h>
78 #include <WebCore/HTMLInputElement.h>
79 #include <WebCore/HTMLNames.h>
80 #include <WebCore/HTMLPlugInElement.h>
81 #include <WebCore/JSDOMWindow.h>
82 #include <WebCore/KeyboardEvent.h>
83 #include <WebCore/MouseRelatedEvent.h>
84 #include <WebCore/NotImplemented.h>
85 #include <WebCore/Page.h>
86 #include <WebCore/PlatformKeyboardEvent.h>
87 #include <WebCore/PluginData.h>
88 #include <WebCore/PluginDatabase.h>
89 #include <WebCore/PluginView.h>
90 #include <WebCore/PrintContext.h>
91 #include <WebCore/ResourceHandle.h>
92 #include <WebCore/ResourceRequest.h>
93 #include <WebCore/RenderView.h>
94 #include <WebCore/RenderTreeAsText.h>
95 #include <WebCore/Settings.h>
96 #include <WebCore/TextIterator.h>
97 #include <WebCore/JSDOMBinding.h>
98 #include <WebCore/ScriptController.h>
99 #include <WebCore/ScriptValue.h>
100 #include <WebCore/SecurityOrigin.h>
101 #include <JavaScriptCore/APICast.h>
102 #include <JavaScriptCore/JSLock.h>
103 #include <JavaScriptCore/JSObject.h>
104 #include <JavaScriptCore/JSValue.h>
105 #include <wtf/MathExtras.h>
106
107 #if USE(CG)
108 #include <CoreGraphics/CoreGraphics.h>
109 #elif USE(CAIRO)
110 #include "PlatformContextCairo.h"
111 #include <cairo-win32.h>
112 #endif
113
114 #if USE(CG)
115 // CG SPI used for printing
116 extern "C" {
117     CGAffineTransform CGContextGetBaseCTM(CGContextRef c); 
118     void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m); 
119 }
120 #endif
121
122 using namespace WebCore;
123 using namespace HTMLNames;
124 using namespace std;
125
126 using JSC::JSGlobalObject;
127 using JSC::JSLock;
128 using JSC::JSValue;
129
130 #define FLASH_REDRAW 0
131
132
133 // By imaging to a width a little wider than the available pixels,
134 // thin pages will be scaled down a little, matching the way they
135 // print in IE and Camino. This lets them use fewer sheets than they
136 // would otherwise, which is presumably why other browsers do this.
137 // Wide pages will be scaled down more than this.
138 const float PrintingMinimumShrinkFactor = 1.25f;
139
140 // This number determines how small we are willing to reduce the page content
141 // in order to accommodate the widest line. If the page would have to be
142 // reduced smaller to make the widest line fit, we just clip instead (this
143 // behavior matches MacIE and Mozilla, at least)
144 const float PrintingMaximumShrinkFactor = 2.0f;
145
146 //-----------------------------------------------------------------------------
147 // Helpers to convert from WebCore to WebKit type
148 WebFrame* kit(Frame* frame)
149 {
150     if (!frame)
151         return 0;
152
153     FrameLoaderClient* frameLoaderClient = frame->loader()->client();
154     if (frameLoaderClient)
155         return static_cast<WebFrame*>(frameLoaderClient);  // eek, is there a better way than static cast?
156     return 0;
157 }
158
159 Frame* core(WebFrame* webFrame)
160 {
161     if (!webFrame)
162         return 0;
163     return webFrame->impl();
164 }
165
166 // 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
167 Frame* core(const WebFrame* webFrame)
168 {
169     if (!webFrame)
170         return 0;
171     return const_cast<WebFrame*>(webFrame)->impl();
172 }
173
174 //-----------------------------------------------------------------------------
175
176 static Element *elementFromDOMElement(IDOMElement *element)
177 {
178     if (!element)
179         return 0;
180
181     COMPtr<IDOMElementPrivate> elePriv;
182     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
183     if (SUCCEEDED(hr)) {
184         Element* ele;
185         hr = elePriv->coreElement((void**)&ele);
186         if (SUCCEEDED(hr))
187             return ele;
188     }
189     return 0;
190 }
191
192 static HTMLFormElement *formElementFromDOMElement(IDOMElement *element)
193 {
194     if (!element)
195         return 0;
196
197     IDOMElementPrivate* elePriv;
198     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
199     if (SUCCEEDED(hr)) {
200         Element* ele;
201         hr = elePriv->coreElement((void**)&ele);
202         elePriv->Release();
203         if (SUCCEEDED(hr) && ele && ele->hasTagName(formTag))
204             return static_cast<HTMLFormElement*>(ele);
205     }
206     return 0;
207 }
208
209 static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element)
210 {
211     if (!element)
212         return 0;
213
214     IDOMElementPrivate* elePriv;
215     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
216     if (SUCCEEDED(hr)) {
217         Element* ele;
218         hr = elePriv->coreElement((void**)&ele);
219         elePriv->Release();
220         if (SUCCEEDED(hr) && ele && ele->hasTagName(inputTag))
221             return static_cast<HTMLInputElement*>(ele);
222     }
223     return 0;
224 }
225
226 // WebFramePrivate ------------------------------------------------------------
227
228 class WebFrame::WebFramePrivate {
229 public:
230     WebFramePrivate() 
231         : frame(0)
232         , webView(0)
233         , m_policyFunction(0)
234     { 
235     }
236
237     ~WebFramePrivate() { }
238     FrameView* frameView() { return frame ? frame->view() : 0; }
239
240     Frame* frame;
241     WebView* webView;
242     FramePolicyFunction m_policyFunction;
243     COMPtr<WebFramePolicyListener> m_policyListener;
244 };
245
246 // WebFrame ----------------------------------------------------------------
247
248 WebFrame::WebFrame()
249     : WebFrameLoaderClient(this)
250     , m_refCount(0)
251     , d(new WebFrame::WebFramePrivate)
252     , m_quickRedirectComing(false)
253     , m_inPrintingMode(false)
254     , m_pageHeight(0)
255 {
256     WebFrameCount++;
257     gClassCount++;
258     gClassNameCount.add("WebFrame");
259 }
260
261 WebFrame::~WebFrame()
262 {
263     delete d;
264     WebFrameCount--;
265     gClassCount--;
266     gClassNameCount.remove("WebFrame");
267 }
268
269 WebFrame* WebFrame::createInstance()
270 {
271     WebFrame* instance = new WebFrame();
272     instance->AddRef();
273     return instance;
274 }
275
276 HRESULT STDMETHODCALLTYPE WebFrame::setAllowsScrolling(
277     /* [in] */ BOOL flag)
278 {
279     if (Frame* frame = core(this))
280         if (FrameView* view = frame->view())
281             view->setCanHaveScrollbars(!!flag);
282
283     return S_OK;
284 }
285
286 HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling(
287     /* [retval][out] */ BOOL *flag)
288 {
289     if (flag)
290         if (Frame* frame = core(this))
291             if (FrameView* view = frame->view())
292                 *flag = view->canHaveScrollbars();
293
294     return S_OK;
295 }
296
297 HRESULT STDMETHODCALLTYPE WebFrame::setIsDisconnected(
298     /* [in] */ BOOL flag)
299 {
300     return E_FAIL;
301 }
302
303 HRESULT STDMETHODCALLTYPE WebFrame::setExcludeFromTextSearch(
304     /* [in] */ BOOL flag)
305 {
306     return E_FAIL;
307 }
308
309 HRESULT WebFrame::reloadFromOrigin()
310 {
311     Frame* coreFrame = core(this);
312     if (!coreFrame)
313         return E_FAIL;
314
315     coreFrame->loader()->reload(true);
316     return S_OK;
317 }
318
319 HRESULT STDMETHODCALLTYPE WebFrame::paintDocumentRectToContext(
320     /* [in] */ RECT rect,
321     /* [in] */ OLE_HANDLE deviceContext)
322 {
323     Frame* coreFrame = core(this);
324     if (!coreFrame)
325         return E_FAIL;
326
327     FrameView* view = coreFrame->view();
328     if (!view)
329         return E_FAIL;
330
331     // We can't paint with a layout still pending.
332     view->updateLayoutAndStyleIfNeededRecursive();
333
334     HDC dc = reinterpret_cast<HDC>(static_cast<ULONG64>(deviceContext));
335     GraphicsContext gc(dc);
336     gc.setShouldIncludeChildWindows(true);
337     gc.save();
338     LONG width = rect.right - rect.left;
339     LONG height = rect.bottom - rect.top;
340     FloatRect dirtyRect;
341     dirtyRect.setWidth(width);
342     dirtyRect.setHeight(height);
343     gc.clip(dirtyRect);
344     gc.translate(-rect.left, -rect.top);
345     view->paintContents(&gc, rect);
346     gc.restore();
347
348     return S_OK;
349 }
350
351 HRESULT STDMETHODCALLTYPE WebFrame::paintScrollViewRectToContextAtPoint(
352     /* [in] */ RECT rect,
353     /* [in] */ POINT pt,
354     /* [in] */ OLE_HANDLE deviceContext)
355 {
356     Frame* coreFrame = core(this);
357     if (!coreFrame)
358         return E_FAIL;
359
360     FrameView* view = coreFrame->view();
361     if (!view)
362         return E_FAIL;
363
364     // We can't paint with a layout still pending.
365     view->updateLayoutAndStyleIfNeededRecursive();
366
367     HDC dc = reinterpret_cast<HDC>(static_cast<ULONG64>(deviceContext));
368     GraphicsContext gc(dc);
369     gc.setShouldIncludeChildWindows(true);
370     gc.save();
371     IntRect dirtyRect(rect);
372     dirtyRect.move(-pt.x, -pt.y);
373     view->paint(&gc, dirtyRect);
374     gc.restore();
375
376     return S_OK;
377 }
378
379 // IUnknown -------------------------------------------------------------------
380
381 HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject)
382 {
383     *ppvObject = 0;
384     if (IsEqualGUID(riid, __uuidof(WebFrame)))
385         *ppvObject = this;
386     else if (IsEqualGUID(riid, IID_IUnknown))
387         *ppvObject = static_cast<IWebFrame*>(this);
388     else if (IsEqualGUID(riid, IID_IWebFrame))
389         *ppvObject = static_cast<IWebFrame*>(this);
390     else if (IsEqualGUID(riid, IID_IWebFramePrivate))
391         *ppvObject = static_cast<IWebFramePrivate*>(this);
392     else if (IsEqualGUID(riid, IID_IWebDocumentText))
393         *ppvObject = static_cast<IWebDocumentText*>(this);
394     else
395         return E_NOINTERFACE;
396
397     AddRef();
398     return S_OK;
399 }
400
401 ULONG STDMETHODCALLTYPE WebFrame::AddRef(void)
402 {
403     return ++m_refCount;
404 }
405
406 ULONG STDMETHODCALLTYPE WebFrame::Release(void)
407 {
408     ULONG newRef = --m_refCount;
409     if (!newRef)
410         delete(this);
411
412     return newRef;
413 }
414
415 // IWebFrame -------------------------------------------------------------------
416
417 HRESULT STDMETHODCALLTYPE WebFrame::name( 
418     /* [retval][out] */ BSTR* frameName)
419 {
420     if (!frameName) {
421         ASSERT_NOT_REACHED();
422         return E_POINTER;
423     }
424
425     *frameName = 0;
426
427     Frame* coreFrame = core(this);
428     if (!coreFrame)
429         return E_FAIL;
430
431     *frameName = BString(coreFrame->tree()->uniqueName()).release();
432     return S_OK;
433 }
434
435 HRESULT STDMETHODCALLTYPE WebFrame::webView( 
436     /* [retval][out] */ IWebView** view)
437 {
438     *view = 0;
439     if (!d->webView)
440         return E_FAIL;
441     *view = d->webView;
442     (*view)->AddRef();
443     return S_OK;
444 }
445
446 HRESULT STDMETHODCALLTYPE WebFrame::frameView(
447     /* [retval][out] */ IWebFrameView** /*view*/)
448 {
449     ASSERT_NOT_REACHED();
450     return E_NOTIMPL;
451 }
452
453 HRESULT STDMETHODCALLTYPE WebFrame::DOMDocument( 
454     /* [retval][out] */ IDOMDocument** result)
455 {
456     if (!result) {
457         ASSERT_NOT_REACHED();
458         return E_POINTER;
459     }
460
461     *result = 0;
462
463     if (Frame* coreFrame = core(this))
464         if (Document* document = coreFrame->document())
465             *result = DOMDocument::createInstance(document);
466
467     return *result ? S_OK : E_FAIL;
468 }
469
470
471 HRESULT WebFrame::DOMWindow(/* [retval][out] */ IDOMWindow** window)
472 {
473     if (!window) {
474         ASSERT_NOT_REACHED();
475         return E_POINTER;
476     }
477
478     *window = 0;
479
480     if (Frame* coreFrame = core(this)) {
481         if (WebCore::DOMWindow* coreWindow = coreFrame->domWindow())
482             *window = ::DOMWindow::createInstance(coreWindow);
483     }
484
485     return *window ? S_OK : E_FAIL;
486 }
487
488 HRESULT STDMETHODCALLTYPE WebFrame::frameElement( 
489     /* [retval][out] */ IDOMHTMLElement** frameElement)
490 {
491     if (!frameElement)
492         return E_POINTER;
493
494     *frameElement = 0;
495     Frame* coreFrame = core(this);
496     if (!coreFrame)
497         return E_FAIL;
498
499     COMPtr<IDOMElement> domElement(AdoptCOM, DOMElement::createInstance(coreFrame->ownerElement()));
500     COMPtr<IDOMHTMLElement> htmlElement(Query, domElement);
501     if (!htmlElement)
502         return E_FAIL;
503     return htmlElement.copyRefTo(frameElement);
504 }
505
506 HRESULT STDMETHODCALLTYPE WebFrame::currentForm( 
507         /* [retval][out] */ IDOMElement **currentForm)
508 {
509     if (!currentForm) {
510         ASSERT_NOT_REACHED();
511         return E_POINTER;
512     }
513
514     *currentForm = 0;
515
516     if (Frame* coreFrame = core(this)) {
517         if (HTMLFormElement* formElement = coreFrame->selection()->currentForm())
518             *currentForm = DOMElement::createInstance(formElement);
519     }
520
521     return *currentForm ? S_OK : E_FAIL;
522 }
523
524 JSGlobalContextRef STDMETHODCALLTYPE WebFrame::globalContext()
525 {
526     Frame* coreFrame = core(this);
527     if (!coreFrame)
528         return 0;
529
530     return toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
531 }
532
533 JSGlobalContextRef WebFrame::globalContextForScriptWorld(IWebScriptWorld* iWorld)
534 {
535     Frame* coreFrame = core(this);
536     if (!coreFrame)
537         return 0;
538
539     COMPtr<WebScriptWorld> world(Query, iWorld);
540     if (!world)
541         return 0;
542
543     return toGlobalRef(coreFrame->script()->globalObject(world->world())->globalExec());
544 }
545
546 HRESULT STDMETHODCALLTYPE WebFrame::loadRequest( 
547     /* [in] */ IWebURLRequest* request)
548 {
549     COMPtr<WebMutableURLRequest> requestImpl;
550
551     HRESULT hr = request->QueryInterface(&requestImpl);
552     if (FAILED(hr))
553         return hr;
554  
555     Frame* coreFrame = core(this);
556     if (!coreFrame)
557         return E_FAIL;
558
559     coreFrame->loader()->load(requestImpl->resourceRequest(), false);
560     return S_OK;
561 }
562
563 void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL)
564 {
565     String mimeTypeString(mimeType, SysStringLen(mimeType));
566     if (!mimeType)
567         mimeTypeString = "text/html";
568
569     String encodingString(textEncodingName, SysStringLen(textEncodingName));
570
571     // FIXME: We should really be using MarshallingHelpers::BSTRToKURL here,
572     // but that would turn a null BSTR into a null KURL, and we crash inside of
573     // WebCore if we use a null KURL in constructing the ResourceRequest.
574     KURL baseKURL = KURL(KURL(), String(baseURL ? baseURL : L"", SysStringLen(baseURL)));
575
576     KURL failingKURL = MarshallingHelpers::BSTRToKURL(failingURL);
577
578     ResourceRequest request(baseKURL);
579     SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL);
580
581     // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.
582     if (Frame* coreFrame = core(this))
583         coreFrame->loader()->load(request, substituteData, false);
584 }
585
586
587 HRESULT STDMETHODCALLTYPE WebFrame::loadData( 
588     /* [in] */ IStream* data,
589     /* [in] */ BSTR mimeType,
590     /* [in] */ BSTR textEncodingName,
591     /* [in] */ BSTR url)
592 {
593     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create();
594
595     STATSTG stat;
596     if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {
597         if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {
598             Vector<char> dataBuffer(stat.cbSize.LowPart);
599             ULONG read;
600             // FIXME: this does a needless copy, would be better to read right into the SharedBuffer
601             // or adopt the Vector or something.
602             if (SUCCEEDED(data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read)))
603                 sharedBuffer->append(dataBuffer.data(), static_cast<int>(dataBuffer.size()));
604         }
605     }
606
607     loadData(sharedBuffer, mimeType, textEncodingName, url, 0);
608     return S_OK;
609 }
610
611 HRESULT WebFrame::loadPlainTextString(
612     /* [in] */ BSTR string,
613     /* [in] */ BSTR url)
614 {
615     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string));
616     BString plainTextMimeType(TEXT("text/plain"), 10);
617     BString utf16Encoding(TEXT("utf-16"), 6);
618     loadData(sharedBuffer.release(), plainTextMimeType, utf16Encoding, url, 0);
619     return S_OK;
620 }
621
622 void WebFrame::loadHTMLString(BSTR string, BSTR baseURL, BSTR unreachableURL)
623 {
624     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string));
625     BString utf16Encoding(TEXT("utf-16"), 6);
626     loadData(sharedBuffer.release(), 0, utf16Encoding, baseURL, unreachableURL);
627 }
628
629 HRESULT STDMETHODCALLTYPE WebFrame::loadHTMLString( 
630     /* [in] */ BSTR string,
631     /* [in] */ BSTR baseURL)
632 {
633     loadHTMLString(string, baseURL, 0);
634     return S_OK;
635 }
636
637 HRESULT STDMETHODCALLTYPE WebFrame::loadAlternateHTMLString( 
638     /* [in] */ BSTR str,
639     /* [in] */ BSTR baseURL,
640     /* [in] */ BSTR unreachableURL)
641 {
642     loadHTMLString(str, baseURL, unreachableURL);
643     return S_OK;
644 }
645
646 HRESULT STDMETHODCALLTYPE WebFrame::loadArchive( 
647     /* [in] */ IWebArchive* /*archive*/)
648 {
649     ASSERT_NOT_REACHED();
650     return E_NOTIMPL;
651 }
652
653 static inline WebDataSource *getWebDataSource(DocumentLoader* loader)
654 {
655     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
656 }
657
658 HRESULT STDMETHODCALLTYPE WebFrame::dataSource( 
659     /* [retval][out] */ IWebDataSource** source)
660 {
661     if (!source) {
662         ASSERT_NOT_REACHED();
663         return E_POINTER;
664     }
665
666     *source = 0;
667
668     Frame* coreFrame = core(this);
669     if (!coreFrame)
670         return E_FAIL;
671
672     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->documentLoader());
673
674     *source = webDataSource;
675
676     if (webDataSource)
677         webDataSource->AddRef(); 
678
679     return *source ? S_OK : E_FAIL;
680 }
681
682 HRESULT STDMETHODCALLTYPE WebFrame::provisionalDataSource( 
683     /* [retval][out] */ IWebDataSource** source)
684 {
685     if (!source) {
686         ASSERT_NOT_REACHED();
687         return E_POINTER;
688     }
689
690     *source = 0;
691
692     Frame* coreFrame = core(this);
693     if (!coreFrame)
694         return E_FAIL;
695
696     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->provisionalDocumentLoader());
697
698     *source = webDataSource;
699
700     if (webDataSource)
701         webDataSource->AddRef(); 
702
703     return *source ? S_OK : E_FAIL;
704 }
705
706 KURL WebFrame::url() const
707 {
708     Frame* coreFrame = core(this);
709     if (!coreFrame)
710         return KURL();
711
712     return coreFrame->document()->url();
713 }
714
715 HRESULT STDMETHODCALLTYPE WebFrame::stopLoading( void)
716 {
717     if (Frame* coreFrame = core(this))
718         coreFrame->loader()->stopAllLoaders();
719     return S_OK;
720 }
721
722 HRESULT STDMETHODCALLTYPE WebFrame::reload( void)
723 {
724     Frame* coreFrame = core(this);
725     if (!coreFrame)
726         return E_FAIL;
727
728     coreFrame->loader()->reload();
729     return S_OK;
730 }
731
732 HRESULT STDMETHODCALLTYPE WebFrame::findFrameNamed( 
733     /* [in] */ BSTR name,
734     /* [retval][out] */ IWebFrame** frame)
735 {
736     if (!frame) {
737         ASSERT_NOT_REACHED();
738         return E_POINTER;
739     }
740
741     *frame = 0;
742
743     Frame* coreFrame = core(this);
744     if (!coreFrame)
745         return E_FAIL;
746
747     Frame* foundFrame = coreFrame->tree()->find(AtomicString(name, SysStringLen(name)));
748     if (!foundFrame)
749         return S_OK;
750
751     WebFrame* foundWebFrame = kit(foundFrame);
752     if (!foundWebFrame)
753         return E_FAIL;
754
755     return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame);
756 }
757
758 HRESULT STDMETHODCALLTYPE WebFrame::parentFrame( 
759     /* [retval][out] */ IWebFrame** frame)
760 {
761     HRESULT hr = S_OK;
762     *frame = 0;
763     if (Frame* coreFrame = core(this))
764         if (WebFrame* webFrame = kit(coreFrame->tree()->parent()))
765             hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame);
766
767     return hr;
768 }
769
770 class EnumChildFrames : public IEnumVARIANT
771 {
772 public:
773     EnumChildFrames(Frame* f) : m_refCount(1), m_frame(f), m_curChild(f ? f->tree()->firstChild() : 0) { }
774
775     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
776     {
777         *ppvObject = 0;
778         if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT))
779             *ppvObject = this;
780         else
781             return E_NOINTERFACE;
782
783         AddRef();
784         return S_OK;
785     }
786
787     virtual ULONG STDMETHODCALLTYPE AddRef(void)
788     {
789         return ++m_refCount;
790     }
791
792     virtual ULONG STDMETHODCALLTYPE Release(void)
793     {
794         ULONG newRef = --m_refCount;
795         if (!newRef)
796             delete(this);
797         return newRef;
798     }
799
800     virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
801     {
802         if (pCeltFetched)
803             *pCeltFetched = 0;
804         if (!rgVar)
805             return E_POINTER;
806         VariantInit(rgVar);
807         if (!celt || celt > 1)
808             return S_FALSE;
809         if (!m_frame || !m_curChild)
810             return S_FALSE;
811
812         WebFrame* webFrame = kit(m_curChild);
813         IUnknown* unknown;
814         HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown);
815         if (FAILED(hr))
816             return hr;
817
818         V_VT(rgVar) = VT_UNKNOWN;
819         V_UNKNOWN(rgVar) = unknown;
820
821         m_curChild = m_curChild->tree()->nextSibling();
822         if (pCeltFetched)
823             *pCeltFetched = 1;
824         return S_OK;
825     }
826
827     virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
828     {
829         if (!m_frame)
830             return S_FALSE;
831         for (unsigned i = 0; i < celt && m_curChild; i++)
832             m_curChild = m_curChild->tree()->nextSibling();
833         return m_curChild ? S_OK : S_FALSE;
834     }
835
836     virtual HRESULT STDMETHODCALLTYPE Reset(void)
837     {
838         if (!m_frame)
839             return S_FALSE;
840         m_curChild = m_frame->tree()->firstChild();
841         return S_OK;
842     }
843
844     virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**)
845     {
846         return E_NOTIMPL;
847     }
848
849 private:
850     ULONG m_refCount;
851     Frame* m_frame;
852     Frame* m_curChild;
853 };
854
855 HRESULT STDMETHODCALLTYPE WebFrame::childFrames( 
856     /* [retval][out] */ IEnumVARIANT **enumFrames)
857 {
858     if (!enumFrames)
859         return E_POINTER;
860
861     *enumFrames = new EnumChildFrames(core(this));
862     return S_OK;
863 }
864
865 // IWebFramePrivate ------------------------------------------------------
866
867 HRESULT WebFrame::renderTreeAsExternalRepresentation(BOOL forPrinting, BSTR *result)
868 {
869     if (!result)
870         return E_POINTER;
871
872     Frame* coreFrame = core(this);
873     if (!coreFrame)
874         return E_FAIL;
875
876     *result = BString(externalRepresentation(coreFrame, forPrinting ? RenderAsTextPrintingMode : RenderAsTextBehaviorNormal)).release();
877     return S_OK;
878 }
879
880 HRESULT STDMETHODCALLTYPE WebFrame::pageNumberForElementById(
881     /* [in] */ BSTR id,
882     /* [in] */ float pageWidthInPixels,
883     /* [in] */ float pageHeightInPixels,
884     /* [retval][out] */ int* result)
885 {
886     // TODO: Please remove this function if not needed as this is LTC specific function
887     // and has been moved to Internals.
888     notImplemented();
889     return E_FAIL;
890 }
891
892 HRESULT STDMETHODCALLTYPE WebFrame::numberOfPages(
893     /* [in] */ float pageWidthInPixels,
894     /* [in] */ float pageHeightInPixels,
895     /* [retval][out] */ int* result)
896 {
897     if (!result)
898         return E_POINTER;
899
900     Frame* coreFrame = core(this);
901     if (!coreFrame)
902         return E_FAIL;
903
904     *result = PrintContext::numberOfPages(coreFrame, FloatSize(pageWidthInPixels, pageHeightInPixels));
905     return S_OK;
906 }
907
908 HRESULT STDMETHODCALLTYPE WebFrame::scrollOffset(
909         /* [retval][out] */ SIZE* offset)
910 {
911     if (!offset) {
912         ASSERT_NOT_REACHED();
913         return E_POINTER;
914     }
915
916     Frame* coreFrame = core(this);
917     if (!coreFrame)
918         return E_FAIL;
919
920     FrameView* view = coreFrame->view();
921     if (!view)
922         return E_FAIL;
923
924     *offset = view->scrollOffset();
925     return S_OK;
926 }
927
928 HRESULT STDMETHODCALLTYPE WebFrame::layout()
929 {
930     Frame* coreFrame = core(this);
931     if (!coreFrame)
932         return E_FAIL;
933
934     FrameView* view = coreFrame->view();
935     if (!view)
936         return E_FAIL;
937
938     view->layout();
939     return S_OK;
940 }
941
942 HRESULT STDMETHODCALLTYPE WebFrame::firstLayoutDone(
943     /* [retval][out] */ BOOL* result)
944 {
945     if (!result) {
946         ASSERT_NOT_REACHED();
947         return E_POINTER;
948     }
949
950     *result = 0;
951
952     Frame* coreFrame = core(this);
953     if (!coreFrame)
954         return E_FAIL;
955
956     *result = coreFrame->loader()->stateMachine()->firstLayoutDone();
957     return S_OK;
958 }
959
960 HRESULT STDMETHODCALLTYPE WebFrame::loadType( 
961     /* [retval][out] */ WebFrameLoadType* type)
962 {
963     if (!type) {
964         ASSERT_NOT_REACHED();
965         return E_POINTER;
966     }
967
968     *type = (WebFrameLoadType)0;
969
970     Frame* coreFrame = core(this);
971     if (!coreFrame)
972         return E_FAIL;
973
974     *type = (WebFrameLoadType)coreFrame->loader()->loadType();
975     return S_OK;
976 }
977
978 HRESULT STDMETHODCALLTYPE WebFrame::pendingFrameUnloadEventCount( 
979     /* [retval][out] */ UINT* result)
980 {
981     if (!result) {
982         ASSERT_NOT_REACHED();
983         return E_POINTER;
984     }
985
986     *result = 0;
987
988     Frame* coreFrame = core(this);
989     if (!coreFrame)
990         return E_FAIL;
991
992     *result = coreFrame->domWindow()->pendingUnloadEventListeners();
993     return S_OK;
994 }
995
996 HRESULT STDMETHODCALLTYPE WebFrame::unused2()
997 {
998     return E_NOTIMPL;
999 }
1000
1001 HRESULT STDMETHODCALLTYPE WebFrame::hasSpellingMarker(
1002         /* [in] */ UINT from,
1003         /* [in] */ UINT length,
1004         /* [retval][out] */ BOOL* result)
1005 {
1006     Frame* coreFrame = core(this);
1007     if (!coreFrame)
1008         return E_FAIL;
1009     *result = coreFrame->editor()->selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1010     return S_OK;
1011 }
1012
1013 HRESULT STDMETHODCALLTYPE WebFrame::clearOpener()
1014 {
1015     HRESULT hr = S_OK;
1016     if (Frame* coreFrame = core(this))
1017         coreFrame->loader()->setOpener(0);
1018
1019     return hr;
1020 }
1021
1022 HRESULT WebFrame::setTextDirection(BSTR direction)
1023 {
1024     Frame* coreFrame = core(this);
1025     if (!coreFrame || !coreFrame->editor())
1026         return E_FAIL;
1027
1028     String directionString(direction, SysStringLen(direction));
1029     if (directionString == "auto")
1030         coreFrame->editor()->setBaseWritingDirection(NaturalWritingDirection);
1031     else if (directionString == "ltr")
1032         coreFrame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
1033     else if (directionString == "rtl")
1034         coreFrame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
1035     return S_OK;
1036 }
1037
1038 // IWebDocumentText -----------------------------------------------------------
1039
1040 HRESULT STDMETHODCALLTYPE WebFrame::supportsTextEncoding( 
1041     /* [retval][out] */ BOOL* result)
1042 {
1043     *result = FALSE;
1044     return E_NOTIMPL;
1045 }
1046
1047 HRESULT STDMETHODCALLTYPE WebFrame::selectedString( 
1048     /* [retval][out] */ BSTR* result)
1049 {
1050     *result = 0;
1051
1052     Frame* coreFrame = core(this);
1053     if (!coreFrame)
1054         return E_FAIL;
1055
1056     String text = coreFrame->displayStringModifiedByEncoding(coreFrame->editor()->selectedText());
1057
1058     *result = BString(text).release();
1059     return S_OK;
1060 }
1061
1062 HRESULT STDMETHODCALLTYPE WebFrame::selectAll()
1063 {
1064     Frame* coreFrame = core(this);
1065     if (!coreFrame)
1066         return E_FAIL;
1067
1068     if (!coreFrame->editor()->command("SelectAll").execute())
1069         return E_FAIL;
1070
1071     return S_OK;
1072 }
1073
1074 HRESULT STDMETHODCALLTYPE WebFrame::deselectAll()
1075 {
1076     return E_NOTIMPL;
1077 }
1078
1079 // WebFrame ---------------------------------------------------------------
1080
1081 PassRefPtr<Frame> WebFrame::init(IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement)
1082 {
1083     webView->QueryInterface(&d->webView);
1084     d->webView->Release(); // don't hold the extra ref
1085
1086     HWND viewWindow;
1087     d->webView->viewWindow((OLE_HANDLE*)&viewWindow);
1088
1089     this->AddRef(); // We release this ref in frameLoaderDestroyed()
1090     RefPtr<Frame> frame = Frame::create(page, ownerElement, this);
1091     d->frame = frame.get();
1092     return frame.release();
1093 }
1094
1095 Frame* WebFrame::impl()
1096 {
1097     return d->frame;
1098 }
1099
1100 void WebFrame::invalidate()
1101 {
1102     Frame* coreFrame = core(this);
1103     ASSERT(coreFrame);
1104
1105     if (Document* document = coreFrame->document())
1106         document->recalcStyle(Node::Force);
1107 }
1108
1109 HRESULT WebFrame::inViewSourceMode(BOOL* flag)
1110 {
1111     if (!flag) {
1112         ASSERT_NOT_REACHED();
1113         return E_POINTER;
1114     }
1115
1116     *flag = FALSE;
1117
1118     Frame* coreFrame = core(this);
1119     if (!coreFrame)
1120         return E_FAIL;
1121
1122     *flag = coreFrame->inViewSourceMode() ? TRUE : FALSE;
1123     return S_OK;
1124 }
1125
1126 HRESULT WebFrame::setInViewSourceMode(BOOL flag)
1127 {
1128     Frame* coreFrame = core(this);
1129     if (!coreFrame)
1130         return E_FAIL;
1131
1132     coreFrame->setInViewSourceMode(!!flag);
1133     return S_OK;
1134 }
1135
1136 HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element)
1137 {
1138     if (!form)
1139         return E_INVALIDARG;
1140
1141     HTMLFormElement* formElement = formElementFromDOMElement(form);
1142     if (formElement) {
1143         const Vector<FormAssociatedElement*>& elements = formElement->associatedElements();
1144         AtomicString targetName((UChar*)name, SysStringLen(name));
1145         for (unsigned int i = 0; i < elements.size(); i++) {
1146             if (!elements[i]->isFormControlElement())
1147                 continue;
1148             HTMLFormControlElement* elt = static_cast<HTMLFormControlElement*>(elements[i]);
1149             // Skip option elements, other duds
1150             if (elt->name() == targetName) {
1151                 *element = DOMElement::createInstance(elt);
1152                 return S_OK;
1153             }
1154         }
1155     }
1156     return E_FAIL;
1157 }
1158
1159 HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form)
1160 {
1161     if (!element)
1162         return E_INVALIDARG;
1163
1164     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1165     if (!inputElement)
1166         return E_FAIL;
1167
1168     HTMLFormElement *formElement = inputElement->form();
1169     if (!formElement)
1170         return E_FAIL;
1171
1172     *form = DOMElement::createInstance(formElement);
1173     return S_OK;
1174 }
1175
1176 HRESULT WebFrame::elementDoesAutoComplete(IDOMElement *element, BOOL *result)
1177 {
1178     *result = false;
1179     if (!element)
1180         return E_INVALIDARG;
1181
1182     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1183     if (!inputElement)
1184         *result = false;
1185     else
1186         *result = inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->shouldAutocomplete();
1187
1188     return S_OK;
1189 }
1190
1191 HRESULT STDMETHODCALLTYPE WebFrame::resumeAnimations()
1192 {
1193     Frame* frame = core(this);
1194     if (!frame)
1195         return E_FAIL;
1196
1197     frame->animation()->resumeAnimations();
1198     return S_OK;
1199 }
1200
1201 HRESULT STDMETHODCALLTYPE WebFrame::suspendAnimations()
1202 {
1203     Frame* frame = core(this);
1204     if (!frame)
1205         return E_FAIL;
1206
1207     frame->animation()->suspendAnimations();
1208     return S_OK;
1209 }
1210
1211 HRESULT WebFrame::pauseAnimation(BSTR animationName, IDOMNode* node, double secondsFromNow, BOOL* animationWasRunning)
1212 {
1213     if (!node || !animationWasRunning)
1214         return E_POINTER;
1215
1216     *animationWasRunning = FALSE;
1217
1218     Frame* frame = core(this);
1219     if (!frame)
1220         return E_FAIL;
1221
1222     AnimationController* controller = frame->animation();
1223     if (!controller)
1224         return E_FAIL;
1225
1226     COMPtr<DOMNode> domNode(Query, node);
1227     if (!domNode)
1228         return E_FAIL;
1229
1230     *animationWasRunning = controller->pauseAnimationAtTime(domNode->node()->renderer(), String(animationName, SysStringLen(animationName)), secondsFromNow);
1231     return S_OK;
1232 }
1233
1234 HRESULT WebFrame::pauseTransition(BSTR propertyName, IDOMNode* node, double secondsFromNow, BOOL* transitionWasRunning)
1235 {
1236     if (!node || !transitionWasRunning)
1237         return E_POINTER;
1238
1239     *transitionWasRunning = FALSE;
1240
1241     Frame* frame = core(this);
1242     if (!frame)
1243         return E_FAIL;
1244
1245     AnimationController* controller = frame->animation();
1246     if (!controller)
1247         return E_FAIL;
1248
1249     COMPtr<DOMNode> domNode(Query, node);
1250     if (!domNode)
1251         return E_FAIL;
1252
1253     *transitionWasRunning = controller->pauseTransitionAtTime(domNode->node()->renderer(), String(propertyName, SysStringLen(propertyName)), secondsFromNow);
1254     return S_OK;
1255 }
1256
1257 HRESULT WebFrame::visibleContentRect(RECT* rect)
1258 {
1259     if (!rect)
1260         return E_POINTER;
1261     SetRectEmpty(rect);
1262
1263     Frame* frame = core(this);
1264     if (!frame)
1265         return E_FAIL;
1266
1267     FrameView* view = frame->view();
1268     if (!view)
1269         return E_FAIL;
1270
1271     *rect = view->visibleContentRect(false);
1272     return S_OK;
1273 }
1274
1275 HRESULT WebFrame::numberOfActiveAnimations(UINT* number)
1276 {
1277     if (!number)
1278         return E_POINTER;
1279
1280     *number = 0;
1281
1282     Frame* frame = core(this);
1283     if (!frame)
1284         return E_FAIL;
1285
1286     AnimationController* controller = frame->animation();
1287     if (!controller)
1288         return E_FAIL;
1289
1290     *number = controller->numberOfActiveAnimations(frame->document());
1291     return S_OK;
1292 }
1293
1294 HRESULT WebFrame::isDisplayingStandaloneImage(BOOL* result)
1295 {
1296     if (!result)
1297         return E_POINTER;
1298
1299     *result = FALSE;
1300
1301     Frame* frame = core(this);
1302     if (!frame)
1303         return E_FAIL;
1304
1305     Document* document = frame->document();
1306     *result = document && document->isImageDocument();
1307     return S_OK;
1308 }
1309
1310 HRESULT WebFrame::allowsFollowingLink(BSTR url, BOOL* result)
1311 {
1312     if (!result)
1313         return E_POINTER;
1314
1315     *result = TRUE;
1316
1317     Frame* frame = core(this);
1318     if (!frame)
1319         return E_FAIL;
1320
1321     *result = frame->document()->securityOrigin()->canDisplay(MarshallingHelpers::BSTRToKURL(url));
1322     return S_OK;
1323 }
1324
1325 HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls)
1326 {
1327     if (!form)
1328         return E_INVALIDARG;
1329
1330     HTMLFormElement* formElement = formElementFromDOMElement(form);
1331     if (!formElement)
1332         return E_FAIL;
1333
1334     int inCount = *cControls;
1335     int count = (int) formElement->associatedElements().size();
1336     *cControls = count;
1337     if (!controls)
1338         return S_OK;
1339     if (inCount < count)
1340         return E_FAIL;
1341
1342     *cControls = 0;
1343     const Vector<FormAssociatedElement*>& elements = formElement->associatedElements();
1344     for (int i = 0; i < count; i++) {
1345         if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds
1346             controls[*cControls] = DOMElement::createInstance(toHTMLElement(elements.at(i)));
1347             (*cControls)++;
1348         }
1349     }
1350     return S_OK;
1351 }
1352
1353 HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result)
1354 {
1355     HTMLInputElement* inputElement = inputElementFromDOMElement(element);
1356     *result = inputElement && inputElement->isPasswordField();
1357     return S_OK;
1358 }
1359
1360 HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, unsigned cLabels, IDOMElement* beforeElement, unsigned* outResultDistance, BOOL* outResultIsInCellAbove, BSTR* result)
1361 {
1362     if (!result) {
1363         ASSERT_NOT_REACHED();
1364         return E_POINTER;
1365     }
1366
1367     if (outResultDistance)
1368         *outResultDistance = 0;
1369     if (outResultIsInCellAbove)
1370         *outResultIsInCellAbove = FALSE;
1371     *result = 0;
1372
1373     if (!cLabels)
1374         return S_OK;
1375     if (cLabels < 1)
1376         return E_INVALIDARG;
1377
1378     Frame* coreFrame = core(this);
1379     if (!coreFrame)
1380         return E_FAIL;
1381
1382     Vector<String> labelStrings(cLabels);
1383     for (int i=0; i<cLabels; i++)
1384         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1385     Element *coreElement = elementFromDOMElement(beforeElement);
1386     if (!coreElement)
1387         return E_FAIL;
1388
1389     size_t resultDistance;
1390     bool resultIsInCellAbove;
1391     String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement, &resultDistance, &resultIsInCellAbove);
1392     
1393     *result = SysAllocStringLen(label.characters(), label.length());
1394     if (label.length() && !*result)
1395         return E_OUTOFMEMORY;
1396     if (outResultDistance)
1397         *outResultDistance = resultDistance;
1398     if (outResultIsInCellAbove)
1399         *outResultIsInCellAbove = resultIsInCellAbove;
1400
1401     return S_OK;
1402 }
1403
1404 HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result)
1405 {
1406     if (!result) {
1407         ASSERT_NOT_REACHED();
1408         return E_POINTER;
1409     }
1410
1411     *result = 0;
1412
1413     if (!cLabels)
1414         return S_OK;
1415     if (cLabels < 1)
1416         return E_INVALIDARG;
1417
1418     Frame* coreFrame = core(this);
1419     if (!coreFrame)
1420         return E_FAIL;
1421
1422     Vector<String> labelStrings(cLabels);
1423     for (int i=0; i<cLabels; i++)
1424         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1425     Element *coreElement = elementFromDOMElement(againstElement);
1426     if (!coreElement)
1427         return E_FAIL;
1428
1429     String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement);
1430     
1431     *result = SysAllocStringLen(label.characters(), label.length());
1432     if (label.length() && !*result)
1433         return E_OUTOFMEMORY;
1434     return S_OK;
1435 }
1436
1437 HRESULT WebFrame::canProvideDocumentSource(bool* result)
1438 {
1439     HRESULT hr = S_OK;
1440     *result = false;
1441
1442     COMPtr<IWebDataSource> dataSource;
1443     hr = WebFrame::dataSource(&dataSource);
1444     if (FAILED(hr))
1445         return hr;
1446
1447     COMPtr<IWebURLResponse> urlResponse;
1448     hr = dataSource->response(&urlResponse);
1449     if (SUCCEEDED(hr) && urlResponse) {
1450         BSTR mimeTypeBStr;
1451         if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) {
1452             String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr));
1453             *result = mimeType == "text/html" || WebCore::DOMImplementation::isXMLMIMEType(mimeType);
1454             SysFreeString(mimeTypeBStr);
1455         }
1456     }
1457     return hr;
1458 }
1459
1460 HRESULT STDMETHODCALLTYPE WebFrame::layerTreeAsText(BSTR* result)
1461 {
1462     if (!result)
1463         return E_POINTER;
1464     *result = 0;
1465
1466     Frame* frame = core(this);
1467     if (!frame)
1468         return E_FAIL;
1469
1470     String text = frame->layerTreeAsText();
1471     *result = BString(text).release();
1472     return S_OK;
1473 }
1474
1475 void WebFrame::frameLoaderDestroyed()
1476 {
1477     // The FrameLoader going away is equivalent to the Frame going away,
1478     // so we now need to clear our frame pointer.
1479     d->frame = 0;
1480
1481     this->Release();
1482 }
1483
1484 void WebFrame::makeRepresentation(DocumentLoader*)
1485 {
1486     notImplemented();
1487 }
1488
1489 void WebFrame::forceLayoutForNonHTML()
1490 {
1491     notImplemented();
1492 }
1493
1494 void WebFrame::setCopiesOnScroll()
1495 {
1496     notImplemented();
1497 }
1498
1499 void WebFrame::detachedFromParent2()
1500 {
1501     notImplemented();
1502 }
1503
1504 void WebFrame::detachedFromParent3()
1505 {
1506     notImplemented();
1507 }
1508
1509 void WebFrame::cancelPolicyCheck()
1510 {
1511     if (d->m_policyListener) {
1512         d->m_policyListener->invalidate();
1513         d->m_policyListener = 0;
1514     }
1515
1516     d->m_policyFunction = 0;
1517 }
1518
1519 void WebFrame::dispatchWillSendSubmitEvent(PassRefPtr<WebCore::FormState>)
1520 {
1521 }
1522
1523 void WebFrame::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
1524 {
1525     Frame* coreFrame = core(this);
1526     ASSERT(coreFrame);
1527
1528     COMPtr<IWebFormDelegate> formDelegate;
1529
1530     if (FAILED(d->webView->formDelegate(&formDelegate))) {
1531         (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1532         return;
1533     }
1534
1535     COMPtr<IDOMElement> formElement(AdoptCOM, DOMElement::createInstance(formState->form()));
1536
1537     HashMap<String, String> formValuesMap;
1538     const StringPairVector& textFieldValues = formState->textFieldValues();
1539     size_t size = textFieldValues.size();
1540     for (size_t i = 0; i < size; ++i)
1541         formValuesMap.add(textFieldValues[i].first, textFieldValues[i].second);
1542
1543     COMPtr<IPropertyBag> formValuesPropertyBag(AdoptCOM, COMPropertyBag<String>::createInstance(formValuesMap));
1544
1545     COMPtr<WebFrame> sourceFrame(kit(formState->sourceDocument()->frame()));
1546     if (SUCCEEDED(formDelegate->willSubmitForm(this, sourceFrame.get(), formElement.get(), formValuesPropertyBag.get(), setUpPolicyListener(function).get())))
1547         return;
1548
1549     // FIXME: Add a sane default implementation
1550     (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1551 }
1552
1553 void WebFrame::revertToProvisionalState(DocumentLoader*)
1554 {
1555     notImplemented();
1556 }
1557
1558 void WebFrame::setMainFrameDocumentReady(bool)
1559 {
1560     notImplemented();
1561 }
1562
1563 void WebFrame::willChangeTitle(DocumentLoader*)
1564 {
1565     notImplemented();
1566 }
1567
1568 void WebFrame::didChangeTitle(DocumentLoader*)
1569 {
1570     notImplemented();
1571 }
1572
1573 void WebFrame::didChangeIcons(DocumentLoader*)
1574 {
1575     notImplemented();
1576 }
1577
1578 bool WebFrame::canHandleRequest(const ResourceRequest& request) const
1579 {
1580     return WebView::canHandleRequest(request);
1581 }
1582
1583 bool WebFrame::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const
1584 {
1585     notImplemented();
1586     return true;
1587 }
1588
1589 bool WebFrame::canShowMIMEType(const String& /*MIMEType*/) const
1590 {
1591     notImplemented();
1592     return true;
1593 }
1594
1595 bool WebFrame::representationExistsForURLScheme(const String& /*URLScheme*/) const
1596 {
1597     notImplemented();
1598     return false;
1599 }
1600
1601 String WebFrame::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1602 {
1603     notImplemented();
1604     ASSERT_NOT_REACHED();
1605     return String();
1606 }
1607
1608 void WebFrame::frameLoadCompleted()
1609 {
1610 }
1611
1612 void WebFrame::restoreViewState()
1613 {
1614 }
1615
1616 void WebFrame::provisionalLoadStarted()
1617 {
1618     notImplemented();
1619 }
1620
1621 bool WebFrame::shouldTreatURLAsSameAsCurrent(const KURL&) const
1622 {
1623     notImplemented();
1624     return false;
1625 }
1626
1627 void WebFrame::addHistoryItemForFragmentScroll()
1628 {
1629     notImplemented();
1630 }
1631
1632 void WebFrame::didFinishLoad()
1633 {
1634     notImplemented();
1635 }
1636
1637 void WebFrame::prepareForDataSourceReplacement()
1638 {
1639     notImplemented();
1640 }
1641
1642 String WebFrame::userAgent(const KURL& url)
1643 {
1644     return d->webView->userAgentForKURL(url);
1645 }
1646
1647 void WebFrame::saveViewStateToItem(HistoryItem*)
1648 {
1649 }
1650
1651 ResourceError WebFrame::cancelledError(const ResourceRequest& request)
1652 {
1653     // FIXME: Need ChickenCat to include CFNetwork/CFURLError.h to get these values
1654     // Alternatively, we could create our own error domain/codes.
1655     return ResourceError(String(WebURLErrorDomain), -999, request.url().string(), String());
1656 }
1657
1658 ResourceError WebFrame::blockedError(const ResourceRequest& request)
1659 {
1660     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1661     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotUseRestrictedPort, request.url().string(), String());
1662 }
1663
1664 ResourceError WebFrame::cannotShowURLError(const ResourceRequest& request)
1665 {
1666     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1667     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotShowURL, request.url().string(), String());
1668 }
1669
1670 ResourceError WebFrame::interruptedForPolicyChangeError(const ResourceRequest& request)
1671 {
1672     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1673     return ResourceError(String(WebKitErrorDomain), WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(), String());
1674 }
1675
1676 ResourceError WebFrame::cannotShowMIMETypeError(const ResourceResponse&)
1677 {
1678     notImplemented();
1679     return ResourceError();
1680 }
1681
1682 ResourceError WebFrame::fileDoesNotExistError(const ResourceResponse&)
1683 {
1684     notImplemented();
1685     return ResourceError();
1686 }
1687
1688 ResourceError WebFrame::pluginWillHandleLoadError(const ResourceResponse& response)
1689 {
1690     return ResourceError(String(WebKitErrorDomain), WebKitErrorPlugInWillHandleLoad, response.url().string(), String());
1691 }
1692
1693 bool WebFrame::shouldFallBack(const ResourceError& error)
1694 {
1695     if (error.errorCode() == WebURLErrorCancelled && error.domain() == String(WebURLErrorDomain))
1696         return false;
1697
1698     if (error.errorCode() == WebKitErrorPlugInWillHandleLoad && error.domain() == String(WebKitErrorDomain))
1699         return false;
1700
1701     return true;
1702 }
1703
1704 COMPtr<WebFramePolicyListener> WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction function)
1705 {
1706     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1707
1708     if (d->m_policyListener)
1709         d->m_policyListener->invalidate();
1710
1711     Frame* coreFrame = core(this);
1712     ASSERT(coreFrame);
1713
1714     d->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
1715     d->m_policyFunction = function;
1716
1717     return d->m_policyListener;
1718 }
1719
1720 void WebFrame::receivedPolicyDecision(PolicyAction action)
1721 {
1722     ASSERT(d->m_policyListener);
1723     ASSERT(d->m_policyFunction);
1724
1725     FramePolicyFunction function = d->m_policyFunction;
1726
1727     d->m_policyListener = 0;
1728     d->m_policyFunction = 0;
1729
1730     Frame* coreFrame = core(this);
1731     ASSERT(coreFrame);
1732
1733     (coreFrame->loader()->policyChecker()->*function)(action);
1734 }
1735
1736 void WebFrame::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& request)
1737 {
1738     Frame* coreFrame = core(this);
1739     ASSERT(coreFrame);
1740
1741     COMPtr<IWebPolicyDelegate> policyDelegate;
1742     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1743         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1744
1745     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1746
1747     if (SUCCEEDED(policyDelegate->decidePolicyForMIMEType(d->webView, BString(response.mimeType()), urlRequest.get(), this, setUpPolicyListener(function).get())))
1748         return;
1749
1750     (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1751 }
1752
1753 void WebFrame::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
1754 {
1755     Frame* coreFrame = core(this);
1756     ASSERT(coreFrame);
1757
1758     COMPtr<IWebPolicyDelegate> policyDelegate;
1759     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1760         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1761
1762     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1763     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? formState->form() : 0, coreFrame));
1764
1765     if (SUCCEEDED(policyDelegate->decidePolicyForNewWindowAction(d->webView, actionInformation.get(), urlRequest.get(), BString(frameName), setUpPolicyListener(function).get())))
1766         return;
1767
1768     (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1769 }
1770
1771 void WebFrame::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState)
1772 {
1773     Frame* coreFrame = core(this);
1774     ASSERT(coreFrame);
1775
1776     COMPtr<IWebPolicyDelegate> policyDelegate;
1777     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1778         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1779
1780     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1781     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? formState->form() : 0, coreFrame));
1782
1783     if (SUCCEEDED(policyDelegate->decidePolicyForNavigationAction(d->webView, actionInformation.get(), urlRequest.get(), this, setUpPolicyListener(function).get())))
1784         return;
1785
1786     (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1787 }
1788
1789 void WebFrame::dispatchUnableToImplementPolicy(const ResourceError& error)
1790 {
1791     COMPtr<IWebPolicyDelegate> policyDelegate;
1792     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1793         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1794
1795     COMPtr<IWebError> webError(AdoptCOM, WebError::createInstance(error));
1796     policyDelegate->unableToImplementPolicyWithError(d->webView, webError.get(), this);
1797 }
1798
1799 void WebFrame::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response)
1800 {
1801     COMPtr<IWebDownloadDelegate> downloadDelegate;
1802     COMPtr<IWebView> webView;
1803     if (SUCCEEDED(this->webView(&webView))) {
1804         if (FAILED(webView->downloadDelegate(&downloadDelegate))) {
1805             // If the WebView doesn't successfully provide a download delegate we'll pass a null one
1806             // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
1807             LOG_ERROR("Failed to get downloadDelegate from WebView");
1808             downloadDelegate = 0;
1809         }
1810     }
1811
1812     // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
1813     // when this method returns
1814     COMPtr<WebDownload> download;
1815     download.adoptRef(WebDownload::createInstance(handle, request, response, downloadDelegate.get()));
1816 }
1817
1818 bool WebFrame::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
1819 {
1820     notImplemented();
1821     return false;
1822 }
1823
1824 void WebFrame::dispatchDidFailProvisionalLoad(const ResourceError& error)
1825 {
1826     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1827     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
1828         COMPtr<IWebError> webError;
1829         webError.adoptRef(WebError::createInstance(error));
1830         frameLoadDelegate->didFailProvisionalLoadWithError(d->webView, webError.get(), this);
1831     }
1832 }
1833
1834 void WebFrame::dispatchDidFailLoad(const ResourceError& error)
1835 {
1836     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1837     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
1838         COMPtr<IWebError> webError;
1839         webError.adoptRef(WebError::createInstance(error));
1840         frameLoadDelegate->didFailLoadWithError(d->webView, webError.get(), this);
1841     }
1842 }
1843
1844 void WebFrame::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
1845 {
1846     d->webView->downloadURL(request.url());
1847 }
1848
1849 PassRefPtr<Widget> WebFrame::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const KURL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
1850 {
1851     RefPtr<PluginView> pluginView = PluginView::create(core(this), pluginSize, element, KURL(), paramNames, paramValues, "application/x-java-applet", false);
1852
1853     // Check if the plugin can be loaded successfully
1854     if (pluginView->plugin() && pluginView->plugin()->load())
1855         return pluginView;
1856
1857     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1858     if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
1859         return pluginView;
1860
1861     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
1862
1863     ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, String(), String());
1864     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1865      
1866     resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
1867
1868     return pluginView;
1869 }
1870
1871 ObjectContentType WebFrame::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
1872 {
1873     return WebCore::FrameLoader::defaultObjectContentType(url, mimeType, shouldPreferPlugInsForImages);
1874 }
1875
1876 String WebFrame::overrideMediaType() const
1877 {
1878     notImplemented();
1879     return String();
1880 }
1881
1882 void WebFrame::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1883 {
1884     Frame* coreFrame = core(this);
1885     ASSERT(coreFrame);
1886
1887     Settings* settings = coreFrame->settings();
1888     if (!settings || !settings->isScriptEnabled())
1889         return;
1890
1891     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1892     if (FAILED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1893         return;
1894
1895     COMPtr<IWebFrameLoadDelegatePrivate2> delegatePrivate(Query, frameLoadDelegate);
1896     if (delegatePrivate && delegatePrivate->didClearWindowObjectForFrameInScriptWorld(d->webView, this, WebScriptWorld::findOrCreateWorld(world).get()) != E_NOTIMPL)
1897         return;
1898
1899     if (world != mainThreadNormalWorld())
1900         return;
1901
1902     JSContextRef context = toRef(coreFrame->script()->globalObject(world)->globalExec());
1903     JSObjectRef windowObject = toRef(coreFrame->script()->globalObject(world));
1904     ASSERT(windowObject);
1905
1906     if (FAILED(frameLoadDelegate->didClearWindowObject(d->webView, context, windowObject, this)))
1907         frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
1908 }
1909
1910 void WebFrame::documentElementAvailable()
1911 {
1912 }
1913
1914 void WebFrame::didPerformFirstNavigation() const
1915 {
1916     COMPtr<IWebPreferences> preferences;
1917     if (FAILED(d->webView->preferences(&preferences)))
1918         return;
1919
1920     COMPtr<IWebPreferencesPrivate> preferencesPrivate(Query, preferences);
1921     if (!preferencesPrivate)
1922         return;
1923     BOOL automaticallyDetectsCacheModel;
1924     if (FAILED(preferencesPrivate->automaticallyDetectsCacheModel(&automaticallyDetectsCacheModel)))
1925         return;
1926
1927     WebCacheModel cacheModel;
1928     if (FAILED(preferences->cacheModel(&cacheModel)))
1929         return;
1930
1931     if (automaticallyDetectsCacheModel && cacheModel < WebCacheModelDocumentBrowser)
1932         preferences->setCacheModel(WebCacheModelDocumentBrowser);
1933 }
1934
1935 void WebFrame::registerForIconNotification(bool listen)
1936 {
1937     d->webView->registerForIconNotification(listen);
1938 }
1939
1940 static IntRect printerRect(HDC printDC)
1941 {
1942     return IntRect(0, 0, 
1943                    GetDeviceCaps(printDC, PHYSICALWIDTH)  - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX),
1944                    GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
1945 }
1946
1947 void WebFrame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot adjustViewSize)
1948 {
1949     Frame* coreFrame = core(this);
1950     ASSERT(coreFrame);
1951     coreFrame->setPrinting(printing, pageSize, originalPageSize, maximumShrinkRatio, adjustViewSize ? AdjustViewSize : DoNotAdjustViewSize);
1952 }
1953
1954 HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode( 
1955     /* [in] */ BOOL value,
1956     /* [in] */ HDC printDC)
1957 {
1958     if (m_inPrintingMode == !!value)
1959         return S_OK;
1960
1961     Frame* coreFrame = core(this);
1962     if (!coreFrame || !coreFrame->document())
1963         return E_FAIL;
1964
1965     m_inPrintingMode = !!value;
1966
1967     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
1968     // according to the paper size
1969     FloatSize minLayoutSize(0.0, 0.0);
1970     FloatSize originalPageSize(0.0, 0.0);
1971     if (m_inPrintingMode && !coreFrame->document()->isFrameSet()) {
1972         if (!printDC) {
1973             ASSERT_NOT_REACHED();
1974             return E_POINTER;
1975         }
1976
1977         const int desiredPixelsPerInch = 72;
1978         IntRect printRect = printerRect(printDC);
1979         int paperHorizontalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSX);
1980         int paperVerticalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSY);
1981         int paperWidth = printRect.width() * desiredPixelsPerInch / paperHorizontalPixelsPerInch;
1982         int paperHeight = printRect.height() * desiredPixelsPerInch / paperVerticalPixelsPerInch;
1983         originalPageSize = FloatSize(paperWidth, paperHeight);
1984         Frame* coreFrame = core(this);
1985         minLayoutSize = coreFrame->resizePageRectsKeepingRatio(originalPageSize, FloatSize(paperWidth * PrintingMinimumShrinkFactor, paperHeight * PrintingMinimumShrinkFactor));
1986     }
1987
1988     setPrinting(m_inPrintingMode, minLayoutSize, originalPageSize, PrintingMaximumShrinkFactor / PrintingMinimumShrinkFactor, AdjustViewSize);
1989
1990     if (!m_inPrintingMode)
1991         m_pageRects.clear();
1992
1993     return S_OK;
1994 }
1995
1996 void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
1997 {
1998     if (headerHeight)
1999         *headerHeight = 0;
2000     if (footerHeight)
2001         *footerHeight = 0;
2002     float height = 0;
2003     COMPtr<IWebUIDelegate> ui;
2004     if (FAILED(d->webView->uiDelegate(&ui)))
2005         return;
2006     if (headerHeight && SUCCEEDED(ui->webViewHeaderHeight(d->webView, &height)))
2007         *headerHeight = height;
2008     if (footerHeight && SUCCEEDED(ui->webViewFooterHeight(d->webView, &height)))
2009         *footerHeight = height;
2010 }
2011
2012 IntRect WebFrame::printerMarginRect(HDC printDC)
2013 {
2014     IntRect emptyRect(0, 0, 0, 0);
2015
2016     COMPtr<IWebUIDelegate> ui;
2017     if (FAILED(d->webView->uiDelegate(&ui)))
2018         return emptyRect;
2019
2020     RECT rect;
2021     if (FAILED(ui->webViewPrintingMarginRect(d->webView, &rect)))
2022         return emptyRect;
2023
2024     rect.left = MulDiv(rect.left, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
2025     rect.top = MulDiv(rect.top, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
2026     rect.right = MulDiv(rect.right, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
2027     rect.bottom = MulDiv(rect.bottom, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
2028
2029     return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top);
2030 }
2031
2032 const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
2033 {
2034     ASSERT(m_inPrintingMode);
2035     
2036     Frame* coreFrame = core(this);
2037     ASSERT(coreFrame);
2038     ASSERT(coreFrame->document());
2039
2040     if (!printDC)
2041         return m_pageRects;
2042
2043     // adjust the page rect by the header and footer
2044     float headerHeight = 0, footerHeight = 0;
2045     headerAndFooterHeights(&headerHeight, &footerHeight);
2046     IntRect pageRect = printerRect(printDC);
2047     IntRect marginRect = printerMarginRect(printDC);
2048     IntRect adjustedRect = IntRect(
2049         pageRect.x() + marginRect.x(),
2050         pageRect.y() + marginRect.y(),
2051         pageRect.width() - marginRect.x() - marginRect.maxX(),
2052         pageRect.height() - marginRect.y() - marginRect.maxY());
2053
2054     computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight);
2055     
2056     return m_pageRects;
2057 }
2058
2059 HRESULT STDMETHODCALLTYPE WebFrame::getPrintedPageCount( 
2060     /* [in] */ HDC printDC,
2061     /* [retval][out] */ UINT *pageCount)
2062 {
2063     if (!pageCount || !printDC) {
2064         ASSERT_NOT_REACHED();
2065         return E_POINTER;
2066     }
2067
2068     *pageCount = 0;
2069
2070     if (!m_inPrintingMode) {
2071         ASSERT_NOT_REACHED();
2072         return E_FAIL;
2073     }
2074
2075     Frame* coreFrame = core(this);
2076     if (!coreFrame || !coreFrame->document())
2077         return E_FAIL;
2078
2079     const Vector<IntRect>& pages = computePageRects(printDC);
2080     *pageCount = (UINT) pages.size();
2081     
2082     return S_OK;
2083 }
2084
2085 #if USE(CG)
2086 void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
2087 {
2088     int x = pageRect.x();
2089     int y = 0;
2090     RECT headerRect = {x, y, x+pageRect.width(), y+static_cast<int>(headerHeight)};
2091     ui->drawHeaderInRect(d->webView, &headerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(pctx)));
2092 }
2093
2094 void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
2095 {
2096     int x = pageRect.x();
2097     int y = max((int)headerHeight+pageRect.height(), m_pageHeight-static_cast<int>(footerHeight));
2098     RECT footerRect = {x, y, x+pageRect.width(), y+static_cast<int>(footerHeight)};
2099     ui->drawFooterInRect(d->webView, &footerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(pctx)), page+1, pageCount);
2100 }
2101
2102 void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
2103 {
2104     Frame* coreFrame = core(this);
2105
2106     IntRect pageRect = m_pageRects[page];
2107
2108     CGContextSaveGState(pctx);
2109
2110     IntRect printRect = printerRect(printDC);
2111     CGRect mediaBox = CGRectMake(CGFloat(0),
2112                                  CGFloat(0),
2113                                  CGFloat(printRect.width()),
2114                                  CGFloat(printRect.height()));
2115
2116     CGContextBeginPage(pctx, &mediaBox);
2117
2118     CGFloat scale = static_cast<float>(mediaBox.size.width)/static_cast<float>(pageRect.width());
2119     CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
2120     ctm = CGAffineTransformScale(ctm, -scale, -scale);
2121     ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
2122     CGContextScaleCTM(pctx, scale, scale);
2123     CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight));   // reserves space for header
2124     CGContextSetBaseCTM(pctx, ctm);
2125
2126     coreFrame->view()->paintContents(spoolCtx, pageRect);
2127
2128     CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);
2129
2130     if (headerHeight)
2131         drawHeader(pctx, ui, pageRect, headerHeight);
2132
2133     if (footerHeight)
2134         drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);
2135
2136     CGContextEndPage(pctx);
2137     CGContextRestoreGState(pctx);
2138 }
2139 #elif USE(CAIRO)
2140 static float scaleFactor(HDC printDC, const IntRect& marginRect, const IntRect& pageRect)
2141 {
2142     const IntRect& printRect = printerRect(printDC);
2143
2144     IntRect adjustedRect = IntRect(
2145         printRect.x() + marginRect.x(),
2146         printRect.y() + marginRect.y(),
2147         printRect.width() - marginRect.x() - marginRect.maxX(),
2148         printRect.height() - marginRect.y() - marginRect.maxY());
2149
2150     float scale = static_cast<float>(adjustedRect.width()) / static_cast<float>(pageRect.width());
2151     if (!scale)
2152        scale = 1.0;
2153
2154     return scale;
2155 }
2156
2157 static HDC hdcFromContext(PlatformGraphicsContext* pctx)
2158 {
2159     return cairo_win32_surface_get_dc(cairo_get_target(pctx->cr()));
2160 }
2161
2162 void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
2163 {
2164     HDC hdc = hdcFromContext(pctx);
2165
2166     int x = pageRect.x();
2167     int y = 0;
2168     RECT headerRect = {x, y, x + pageRect.width(), y + static_cast<int>(headerHeight)};
2169
2170     ui->drawHeaderInRect(d->webView, &headerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(hdc)));
2171 }
2172
2173 void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
2174 {
2175     HDC hdc = hdcFromContext(pctx);
2176     
2177     int x = pageRect.x();
2178     int y = max(static_cast<int>(headerHeight) + pageRect.height(), m_pageHeight  -static_cast<int>(footerHeight));
2179     RECT footerRect = {x, y, x + pageRect.width(), y + static_cast<int>(footerHeight)};
2180
2181     ui->drawFooterInRect(d->webView, &footerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(hdc)), page+1, pageCount);
2182 }
2183
2184 static XFORM buildXFORMFromCairo(HDC targetDC, cairo_t* previewContext)
2185 {
2186     XFORM scaled;
2187     GetWorldTransform(targetDC, &scaled);
2188
2189     cairo_matrix_t ctm;
2190     cairo_get_matrix(previewContext, &ctm);    
2191         
2192     // Scale to the preview screen bounds
2193     scaled.eM11 = ctm.xx;
2194     scaled.eM22 = ctm.yy;
2195
2196     return scaled;
2197 }
2198
2199 void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
2200 {
2201     Frame* coreFrame = core(this);
2202
2203     const IntRect& pageRect = m_pageRects[page];
2204     const IntRect& marginRect = printerMarginRect(printDC);
2205
2206     // In preview, the printDC is a placeholder, so just always use the HDC backing the graphics context.
2207     HDC hdc = hdcFromContext(pctx);
2208
2209     spoolCtx->save();
2210     
2211     XFORM original, scaled;
2212     GetWorldTransform(hdc, &original);
2213     
2214     cairo_t* cr = pctx->cr();
2215     bool preview = (hdc != printDC);
2216     if (preview) {
2217         // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo will
2218         // draw correctly.  We need to retain the correct preview scale here for use when the Cairo
2219         // drawing completes so that we can scale our GDI-based header/footer calls. This is a
2220         // workaround for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
2221         scaled = buildXFORMFromCairo(hdc, cr);
2222     }
2223
2224     float scale = scaleFactor(printDC, marginRect, pageRect);
2225     
2226     IntRect cairoMarginRect(marginRect);
2227     cairoMarginRect.scale(1 / scale);
2228
2229     // We cannot scale the display HDC because the print surface also scales fonts,
2230     // resulting in invalid printing (and print preview)
2231     cairo_scale(cr, scale, scale);
2232     cairo_translate(cr, cairoMarginRect.x(), cairoMarginRect.y() + headerHeight);
2233
2234     // Modify Cairo (only) to account for page position.
2235     cairo_translate(cr, -pageRect.x(), -pageRect.y());
2236     coreFrame->view()->paintContents(spoolCtx, pageRect);
2237     cairo_translate(cr, pageRect.x(), pageRect.y());
2238     
2239     if (preview) {
2240         // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo would
2241         // draw correctly.  We need to rescale the HDC to the correct preview scale so our GDI-based
2242         // header/footer calls will draw properly.  This is a workaround for a bug in Cairo.
2243         // (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
2244         SetWorldTransform(hdc, &scaled);
2245     }
2246     
2247     XFORM xform = TransformationMatrix().translate(marginRect.x(), marginRect.y()).scale(scale);
2248     ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
2249    
2250     if (headerHeight)
2251         drawHeader(pctx, ui, pageRect, headerHeight);
2252     
2253     if (footerHeight)
2254         drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);
2255
2256     SetWorldTransform(hdc, &original);
2257
2258     cairo_show_page(cr);
2259     ASSERT(!cairo_status(cr));
2260     spoolCtx->restore();
2261 }
2262
2263 static void setCairoTransformToPreviewHDC(cairo_t* previewCtx, HDC previewDC)
2264 {
2265     XFORM passedCTM;
2266     GetWorldTransform(previewDC, &passedCTM);
2267
2268     // Reset HDC WorldTransform to unscaled state.  Scaling must be
2269     // done in Cairo to avoid drawing errors.
2270     XFORM unscaledCTM = passedCTM;
2271     unscaledCTM.eM11 = 1.0;
2272     unscaledCTM.eM22 = 1.0;
2273         
2274     SetWorldTransform(previewDC, &unscaledCTM);
2275
2276     // Make the Cairo transform match the information passed to WebKit
2277     // in the HDC's WorldTransform.
2278     cairo_matrix_t ctm = { passedCTM.eM11, passedCTM.eM12, passedCTM.eM21,
2279                            passedCTM.eM22, passedCTM.eDx, passedCTM.eDy };
2280
2281     cairo_set_matrix(previewCtx, &ctm);    
2282 }
2283
2284 #endif
2285
2286 HRESULT STDMETHODCALLTYPE WebFrame::spoolPages( 
2287     /* [in] */ HDC printDC,
2288     /* [in] */ UINT startPage,
2289     /* [in] */ UINT endPage,
2290     /* [retval][out] */ void* ctx)
2291 {
2292 #if USE(CG)
2293     if (!printDC || !ctx) {
2294         ASSERT_NOT_REACHED();
2295         return E_POINTER;
2296     }
2297 #elif USE(CAIRO)
2298     if (!printDC) {
2299         ASSERT_NOT_REACHED();
2300         return E_POINTER;
2301     }
2302     
2303     HDC targetDC = (ctx) ? (HDC)ctx : printDC;
2304
2305     cairo_surface_t* printSurface = 0;
2306     if (ctx)
2307         printSurface = cairo_win32_surface_create(targetDC); // in-memory
2308     else
2309         printSurface = cairo_win32_printing_surface_create(targetDC); // metafile
2310     
2311     cairo_t* cr = cairo_create(printSurface);
2312     if (!cr) {
2313         cairo_surface_destroy(printSurface);    
2314         return E_FAIL;
2315     }
2316
2317     PlatformContextCairo platformContext(cr);
2318     PlatformGraphicsContext* pctx = &platformContext;
2319     cairo_destroy(cr);
2320
2321     if (ctx) {
2322         // If this is a preview, the Windows HDC was sent with scaling information.
2323         // Retrieve it and reset it so that it draws properly.  This is a workaround
2324         // for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
2325         setCairoTransformToPreviewHDC(cr, targetDC);
2326     }
2327     
2328     cairo_surface_set_fallback_resolution(printSurface, 72.0, 72.0);
2329 #endif
2330
2331     if (!m_inPrintingMode) {
2332         ASSERT_NOT_REACHED();
2333         return E_FAIL;
2334     }
2335
2336     Frame* coreFrame = core(this);
2337     if (!coreFrame || !coreFrame->document())
2338         return E_FAIL;
2339
2340     UINT pageCount = (UINT) m_pageRects.size();
2341 #if USE(CG)
2342     PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
2343 #endif
2344
2345     if (!pageCount || startPage > pageCount) {
2346         ASSERT_NOT_REACHED();
2347         return E_FAIL;
2348     }
2349
2350     if (startPage > 0)
2351         startPage--;
2352
2353     if (endPage == 0)
2354         endPage = pageCount;
2355
2356     COMPtr<IWebUIDelegate> ui;
2357     if (FAILED(d->webView->uiDelegate(&ui)))
2358         return E_FAIL;
2359
2360     float headerHeight = 0, footerHeight = 0;
2361     headerAndFooterHeights(&headerHeight, &footerHeight);
2362     GraphicsContext spoolCtx(pctx);
2363     spoolCtx.setShouldIncludeChildWindows(true);
2364
2365     for (UINT ii = startPage; ii < endPage; ii++)
2366         spoolPage(pctx, &spoolCtx, printDC, ui.get(), headerHeight, footerHeight, ii, pageCount);
2367
2368 #if USE(CAIRO)
2369     cairo_surface_finish(printSurface);
2370     ASSERT(!cairo_surface_status(printSurface));
2371     cairo_surface_destroy(printSurface);
2372 #endif
2373
2374     return S_OK;
2375 }
2376
2377 HRESULT STDMETHODCALLTYPE WebFrame::isFrameSet( 
2378     /* [retval][out] */ BOOL* result)
2379 {
2380     *result = FALSE;
2381
2382     Frame* coreFrame = core(this);
2383     if (!coreFrame || !coreFrame->document())
2384         return E_FAIL;
2385
2386     *result = coreFrame->document()->isFrameSet() ? TRUE : FALSE;
2387     return S_OK;
2388 }
2389
2390 HRESULT STDMETHODCALLTYPE WebFrame::string( 
2391     /* [retval][out] */ BSTR *result)
2392 {
2393     *result = 0;
2394
2395     Frame* coreFrame = core(this);
2396     if (!coreFrame)
2397         return E_FAIL;
2398
2399     RefPtr<Range> allRange(rangeOfContents(coreFrame->document()));
2400     String allString = plainText(allRange.get());
2401     *result = BString(allString).release();
2402     return S_OK;
2403 }
2404
2405 HRESULT STDMETHODCALLTYPE WebFrame::size( 
2406     /* [retval][out] */ SIZE *size)
2407 {
2408     if (!size)
2409         return E_POINTER;
2410     size->cx = size->cy = 0;
2411
2412     Frame* coreFrame = core(this);
2413     if (!coreFrame)
2414         return E_FAIL;
2415     FrameView* view = coreFrame->view();
2416     if (!view)
2417         return E_FAIL;
2418     size->cx = view->width();
2419     size->cy = view->height();
2420     return S_OK;
2421 }
2422
2423 HRESULT STDMETHODCALLTYPE WebFrame::hasScrollBars( 
2424     /* [retval][out] */ BOOL *result)
2425 {
2426     if (!result)
2427         return E_POINTER;
2428     *result = FALSE;
2429
2430     Frame* coreFrame = core(this);
2431     if (!coreFrame)
2432         return E_FAIL;
2433
2434     FrameView* view = coreFrame->view();
2435     if (!view)
2436         return E_FAIL;
2437
2438     if (view->horizontalScrollbar() || view->verticalScrollbar())
2439         *result = TRUE;
2440
2441     return S_OK;
2442 }
2443
2444 HRESULT STDMETHODCALLTYPE WebFrame::contentBounds( 
2445     /* [retval][out] */ RECT *result)
2446 {
2447     if (!result)
2448         return E_POINTER;
2449     ::SetRectEmpty(result);
2450
2451     Frame* coreFrame = core(this);
2452     if (!coreFrame)
2453         return E_FAIL;
2454
2455     FrameView* view = coreFrame->view();
2456     if (!view)
2457         return E_FAIL;
2458
2459     result->bottom = view->contentsHeight();
2460     result->right = view->contentsWidth();
2461     return S_OK;
2462 }
2463
2464 HRESULT STDMETHODCALLTYPE WebFrame::frameBounds( 
2465     /* [retval][out] */ RECT *result)
2466 {
2467     if (!result)
2468         return E_POINTER;
2469     ::SetRectEmpty(result);
2470
2471     Frame* coreFrame = core(this);
2472     if (!coreFrame)
2473         return E_FAIL;
2474
2475     FrameView* view = coreFrame->view();
2476     if (!view)
2477         return E_FAIL;
2478
2479     FloatRect bounds = view->visibleContentRect(true);
2480     result->bottom = (LONG) bounds.height();
2481     result->right = (LONG) bounds.width();
2482     return S_OK;
2483 }
2484
2485 HRESULT STDMETHODCALLTYPE WebFrame::isDescendantOfFrame( 
2486     /* [in] */ IWebFrame *ancestor,
2487     /* [retval][out] */ BOOL *result)
2488 {
2489     if (!result)
2490         return E_POINTER;
2491     *result = FALSE;
2492
2493     Frame* coreFrame = core(this);
2494     COMPtr<WebFrame> ancestorWebFrame(Query, ancestor);
2495     if (!ancestorWebFrame)
2496         return S_OK;
2497
2498     *result = (coreFrame && coreFrame->tree()->isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
2499     return S_OK;
2500 }
2501
2502 HRESULT WebFrame::stringByEvaluatingJavaScriptInScriptWorld(IWebScriptWorld* iWorld, JSObjectRef globalObjectRef, BSTR script, BSTR* evaluationResult)
2503 {
2504     if (!evaluationResult)
2505         return E_POINTER;
2506     *evaluationResult = 0;
2507
2508     if (!iWorld)
2509         return E_POINTER;
2510
2511     COMPtr<WebScriptWorld> world(Query, iWorld);
2512     if (!world)
2513         return E_INVALIDARG;
2514
2515     Frame* coreFrame = core(this);
2516     String string = String(script, SysStringLen(script));
2517
2518     // Start off with some guess at a frame and a global object, we'll try to do better...!
2519     JSDOMWindow* anyWorldGlobalObject = coreFrame->script()->globalObject(mainThreadNormalWorld());
2520
2521     // The global object is probably a shell object? - if so, we know how to use this!
2522     JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
2523     if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell"))
2524         anyWorldGlobalObject = static_cast<JSDOMWindowShell*>(globalObjectObj)->window();
2525
2526     // Get the frame frome the global object we've settled on.
2527     Frame* frame = anyWorldGlobalObject->impl()->frame();
2528     ASSERT(frame->document());
2529     JSValue result = frame->script()->executeScriptInWorld(world->world(), string, true).jsValue();
2530
2531     if (!frame) // In case the script removed our frame from the page.
2532         return S_OK;
2533
2534     // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
2535     // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 
2536     // JSEvaluateScript instead, since they have less surprising semantics.
2537     if (!result || !result.isBoolean() && !result.isString() && !result.isNumber())
2538         return S_OK;
2539
2540     JSC::ExecState* exec = anyWorldGlobalObject->globalExec();
2541     JSC::JSLockHolder lock(exec);
2542     String resultString = ustringToString(result.toString(exec)->value(exec));
2543     *evaluationResult = BString(resultString).release();
2544
2545     return S_OK;
2546 }
2547
2548 void WebFrame::unmarkAllMisspellings()
2549 {
2550     Frame* coreFrame = core(this);
2551     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2552         Document *doc = frame->document();
2553         if (!doc)
2554             return;
2555
2556         doc->markers()->removeMarkers(DocumentMarker::Spelling);
2557     }
2558 }
2559
2560 void WebFrame::unmarkAllBadGrammar()
2561 {
2562     Frame* coreFrame = core(this);
2563     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2564         Document *doc = frame->document();
2565         if (!doc)
2566             return;
2567
2568         doc->markers()->removeMarkers(DocumentMarker::Grammar);
2569     }
2570 }
2571
2572 WebView* WebFrame::webView() const
2573 {
2574     return d->webView;
2575 }
2576
2577 void WebFrame::setWebView(WebView* webView)
2578 {
2579     d->webView = webView;
2580 }
2581
2582 COMPtr<IAccessible> WebFrame::accessible() const
2583 {
2584     Frame* coreFrame = core(this);
2585     ASSERT(coreFrame);
2586
2587     Document* currentDocument = coreFrame->document();
2588     if (!currentDocument)
2589         m_accessible = 0;
2590     else if (!m_accessible || m_accessible->document() != currentDocument) {
2591         // Either we've never had a wrapper for this frame's top-level Document,
2592         // the Document renderer was destroyed and its wrapper was detached, or
2593         // the previous Document is in the page cache, and the current document
2594         // needs to be wrapped.
2595         m_accessible = new AccessibleDocument(currentDocument);
2596     }
2597     return m_accessible.get();
2598 }
2599
2600 void WebFrame::updateBackground()
2601 {
2602     Color backgroundColor = webView()->transparent() ? Color::transparent : Color::white;
2603     Frame* coreFrame = core(this);
2604
2605     if (!coreFrame || !coreFrame->view())
2606         return;
2607
2608     coreFrame->view()->updateBackgroundRecursively(backgroundColor, webView()->transparent());
2609 }
2610
2611 PassRefPtr<FrameNetworkingContext> WebFrame::createNetworkingContext()
2612 {
2613     return WebFrameNetworkingContext::create(core(this), userAgent(url()));
2614 }