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