1/* 2 * Copyright (C) 2006-2009, 2011, 2013 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 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 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 "HTMLFrameOwnerElement.h" 35#include "MarshallingHelpers.h" 36#include "WebActionPropertyBag.h" 37#include "WebChromeClient.h" 38#include "WebDataSource.h" 39#include "WebDocumentLoader.h" 40#include "WebDownload.h" 41#include "WebEditorClient.h" 42#include "WebError.h" 43#include "WebFrameLoaderClient.h" 44#include "WebFramePolicyListener.h" 45#include "WebHistory.h" 46#include "WebHistoryItem.h" 47#include "WebKit.h" 48#include "WebKitStatisticsPrivate.h" 49#include "WebMutableURLRequest.h" 50#include "WebNotificationCenter.h" 51#include "WebScriptWorld.h" 52#include "WebURLResponse.h" 53#include "WebView.h" 54#include <WebCore/AnimationController.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/Editor.h> 64#include <WebCore/Event.h> 65#include <WebCore/EventHandler.h> 66#include <WebCore/FormState.h> 67#include <WebCore/FrameLoader.h> 68#include <WebCore/FrameLoadRequest.h> 69#include <WebCore/FrameTree.h> 70#include <WebCore/FrameView.h> 71#include <WebCore/FrameWin.h> 72#include <WebCore/GDIObjectCounter.h> 73#include <WebCore/GraphicsContext.h> 74#include <WebCore/HistoryItem.h> 75#include <WebCore/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/MainFrame.h> 84#include <WebCore/MouseRelatedEvent.h> 85#include <WebCore/NotImplemented.h> 86#include <WebCore/Page.h> 87#include <WebCore/PlatformKeyboardEvent.h> 88#include <WebCore/PluginData.h> 89#include <WebCore/PluginDatabase.h> 90#include <WebCore/PluginView.h> 91#include <WebCore/PolicyChecker.h> 92#include <WebCore/PrintContext.h> 93#include <WebCore/ResourceHandle.h> 94#include <WebCore/ResourceLoader.h> 95#include <WebCore/ResourceRequest.h> 96#include <WebCore/RenderView.h> 97#include <WebCore/RenderTreeAsText.h> 98#include <WebCore/Settings.h> 99#include <WebCore/TextIterator.h> 100#include <WebCore/JSDOMBinding.h> 101#include <WebCore/ScriptController.h> 102#include <WebCore/SecurityOrigin.h> 103#include <JavaScriptCore/APICast.h> 104#include <JavaScriptCore/JSCJSValue.h> 105#include <JavaScriptCore/JSLock.h> 106#include <JavaScriptCore/JSObject.h> 107#include <bindings/ScriptValue.h> 108#include <wtf/MathExtras.h> 109 110#if USE(CG) 111#include <CoreGraphics/CoreGraphics.h> 112#elif USE(CAIRO) 113#include "PlatformContextCairo.h" 114#include <cairo-win32.h> 115#endif 116 117#if USE(CG) 118// CG SPI used for printing 119extern "C" { 120 CGAffineTransform CGContextGetBaseCTM(CGContextRef c); 121 void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m); 122} 123#endif 124 125using namespace WebCore; 126using namespace HTMLNames; 127using namespace std; 128 129using JSC::JSGlobalObject; 130using JSC::JSLock; 131using JSC::JSValue; 132 133#define FLASH_REDRAW 0 134 135 136// By imaging to a width a little wider than the available pixels, 137// thin pages will be scaled down a little, matching the way they 138// print in IE and Camino. This lets them use fewer sheets than they 139// would otherwise, which is presumably why other browsers do this. 140// Wide pages will be scaled down more than this. 141const float PrintingMinimumShrinkFactor = 1.25f; 142 143// This number determines how small we are willing to reduce the page content 144// in order to accommodate the widest line. If the page would have to be 145// reduced smaller to make the widest line fit, we just clip instead (this 146// behavior matches MacIE and Mozilla, at least) 147const float PrintingMaximumShrinkFactor = 2.0f; 148 149//----------------------------------------------------------------------------- 150// Helpers to convert from WebCore to WebKit type 151WebFrame* kit(Frame* frame) 152{ 153 if (!frame) 154 return 0; 155 156 // FIXME: Doesn't this need to be aware of EmptyFrameLoaderClient? 157 FrameLoaderClient& frameLoaderClient = frame->loader().client(); 158 return static_cast<WebFrameLoaderClient&>(frameLoaderClient).webFrame(); 159} 160 161Frame* core(WebFrame* webFrame) 162{ 163 if (!webFrame) 164 return 0; 165 return webFrame->impl(); 166} 167 168// 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 169Frame* core(const WebFrame* webFrame) 170{ 171 if (!webFrame) 172 return 0; 173 return const_cast<WebFrame*>(webFrame)->impl(); 174} 175 176//----------------------------------------------------------------------------- 177 178static Element *elementFromDOMElement(IDOMElement *element) 179{ 180 if (!element) 181 return 0; 182 183 COMPtr<IDOMElementPrivate> elePriv; 184 HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv); 185 if (SUCCEEDED(hr)) { 186 Element* ele; 187 hr = elePriv->coreElement((void**)&ele); 188 if (SUCCEEDED(hr)) 189 return ele; 190 } 191 return 0; 192} 193 194static HTMLFormElement *formElementFromDOMElement(IDOMElement *element) 195{ 196 if (!element) 197 return 0; 198 199 IDOMElementPrivate* elePriv; 200 HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv); 201 if (SUCCEEDED(hr)) { 202 Element* ele; 203 hr = elePriv->coreElement((void**)&ele); 204 elePriv->Release(); 205 if (SUCCEEDED(hr) && ele && isHTMLFormElement(ele)) 206 return toHTMLFormElement(ele); 207 } 208 return 0; 209} 210 211static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element) 212{ 213 if (!element) 214 return 0; 215 216 IDOMElementPrivate* elePriv; 217 HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv); 218 if (SUCCEEDED(hr)) { 219 Element* ele; 220 hr = elePriv->coreElement((void**)&ele); 221 elePriv->Release(); 222 if (SUCCEEDED(hr) && ele && isHTMLInputElement(ele)) 223 return toHTMLInputElement(ele); 224 } 225 return 0; 226} 227 228// WebFramePrivate ------------------------------------------------------------ 229 230class WebFrame::WebFramePrivate { 231public: 232 WebFramePrivate() 233 : frame(0) 234 , webView(0) 235 { 236 } 237 238 ~WebFramePrivate() { } 239 FrameView* frameView() { return frame ? frame->view() : 0; } 240 241 Frame* frame; 242 WebView* webView; 243}; 244 245// WebFrame ---------------------------------------------------------------- 246 247WebFrame::WebFrame() 248 : m_refCount(0) 249 , d(new WebFrame::WebFramePrivate) 250 , m_quickRedirectComing(false) 251 , m_inPrintingMode(false) 252 , m_pageHeight(0) 253{ 254 WebFrameCount++; 255 gClassCount++; 256 gClassNameCount.add("WebFrame"); 257} 258 259WebFrame::~WebFrame() 260{ 261 delete d; 262 WebFrameCount--; 263 gClassCount--; 264 gClassNameCount.remove("WebFrame"); 265} 266 267WebFrame* WebFrame::createInstance() 268{ 269 WebFrame* instance = new WebFrame(); 270 instance->AddRef(); 271 return instance; 272} 273 274HRESULT STDMETHODCALLTYPE WebFrame::setAllowsScrolling( 275 /* [in] */ BOOL flag) 276{ 277 if (Frame* frame = core(this)) 278 if (FrameView* view = frame->view()) 279 view->setCanHaveScrollbars(!!flag); 280 281 return S_OK; 282} 283 284HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling( 285 /* [retval][out] */ BOOL *flag) 286{ 287 if (flag) 288 if (Frame* frame = core(this)) 289 if (FrameView* view = frame->view()) 290 *flag = view->canHaveScrollbars(); 291 292 return S_OK; 293} 294 295HRESULT STDMETHODCALLTYPE WebFrame::setIsDisconnected( 296 /* [in] */ BOOL flag) 297{ 298 return E_FAIL; 299} 300 301HRESULT STDMETHODCALLTYPE WebFrame::setExcludeFromTextSearch( 302 /* [in] */ BOOL flag) 303{ 304 return E_FAIL; 305} 306 307HRESULT WebFrame::reloadFromOrigin() 308{ 309 Frame* coreFrame = core(this); 310 if (!coreFrame) 311 return E_FAIL; 312 313 coreFrame->loader().reload(true); 314 return S_OK; 315} 316 317HRESULT WebFrame::paintDocumentRectToContext(RECT rect, HDC deviceContext) 318{ 319 Frame* coreFrame = core(this); 320 if (!coreFrame) 321 return E_FAIL; 322 323 FrameView* view = coreFrame->view(); 324 if (!view) 325 return E_FAIL; 326 327 // We can't paint with a layout still pending. 328 view->updateLayoutAndStyleIfNeededRecursive(); 329 330 GraphicsContext gc(deviceContext); 331 gc.setShouldIncludeChildWindows(true); 332 gc.save(); 333 LONG width = rect.right - rect.left; 334 LONG height = rect.bottom - rect.top; 335 FloatRect dirtyRect; 336 dirtyRect.setWidth(width); 337 dirtyRect.setHeight(height); 338 gc.clip(dirtyRect); 339 gc.translate(-rect.left, -rect.top); 340 view->paintContents(&gc, rect); 341 gc.restore(); 342 343 return S_OK; 344} 345 346HRESULT WebFrame::paintScrollViewRectToContextAtPoint(RECT rect, POINT pt, HDC deviceContext) 347{ 348 Frame* coreFrame = core(this); 349 if (!coreFrame) 350 return E_FAIL; 351 352 FrameView* view = coreFrame->view(); 353 if (!view) 354 return E_FAIL; 355 356 // We can't paint with a layout still pending. 357 view->updateLayoutAndStyleIfNeededRecursive(); 358 359 GraphicsContext gc(deviceContext); 360 gc.setShouldIncludeChildWindows(true); 361 gc.save(); 362 IntRect dirtyRect(rect); 363 dirtyRect.move(-pt.x, -pt.y); 364 view->paint(&gc, dirtyRect); 365 gc.restore(); 366 367 return S_OK; 368} 369 370// IUnknown ------------------------------------------------------------------- 371 372HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject) 373{ 374 *ppvObject = 0; 375 if (IsEqualGUID(riid, __uuidof(WebFrame))) 376 *ppvObject = this; 377 else if (IsEqualGUID(riid, IID_IUnknown)) 378 *ppvObject = static_cast<IWebFrame*>(this); 379 else if (IsEqualGUID(riid, IID_IWebFrame)) 380 *ppvObject = static_cast<IWebFrame*>(this); 381 else if (IsEqualGUID(riid, IID_IWebFramePrivate)) 382 *ppvObject = static_cast<IWebFramePrivate*>(this); 383 else if (IsEqualGUID(riid, IID_IWebDocumentText)) 384 *ppvObject = static_cast<IWebDocumentText*>(this); 385 else 386 return E_NOINTERFACE; 387 388 AddRef(); 389 return S_OK; 390} 391 392ULONG STDMETHODCALLTYPE WebFrame::AddRef(void) 393{ 394 return ++m_refCount; 395} 396 397ULONG STDMETHODCALLTYPE WebFrame::Release(void) 398{ 399 ULONG newRef = --m_refCount; 400 if (!newRef) 401 delete(this); 402 403 return newRef; 404} 405 406// IWebFrame ------------------------------------------------------------------- 407 408HRESULT STDMETHODCALLTYPE WebFrame::name( 409 /* [retval][out] */ BSTR* frameName) 410{ 411 if (!frameName) { 412 ASSERT_NOT_REACHED(); 413 return E_POINTER; 414 } 415 416 *frameName = 0; 417 418 Frame* coreFrame = core(this); 419 if (!coreFrame) 420 return E_FAIL; 421 422 *frameName = BString(coreFrame->tree().uniqueName()).release(); 423 return S_OK; 424} 425 426HRESULT STDMETHODCALLTYPE WebFrame::webView( 427 /* [retval][out] */ IWebView** view) 428{ 429 *view = 0; 430 if (!d->webView) 431 return E_FAIL; 432 *view = d->webView; 433 (*view)->AddRef(); 434 return S_OK; 435} 436 437HRESULT STDMETHODCALLTYPE WebFrame::frameView( 438 /* [retval][out] */ IWebFrameView** /*view*/) 439{ 440 ASSERT_NOT_REACHED(); 441 return E_NOTIMPL; 442} 443 444HRESULT STDMETHODCALLTYPE WebFrame::DOMDocument( 445 /* [retval][out] */ IDOMDocument** result) 446{ 447 if (!result) { 448 ASSERT_NOT_REACHED(); 449 return E_POINTER; 450 } 451 452 *result = 0; 453 454 if (Frame* coreFrame = core(this)) 455 if (Document* document = coreFrame->document()) 456 *result = DOMDocument::createInstance(document); 457 458 return *result ? S_OK : E_FAIL; 459} 460 461 462HRESULT WebFrame::DOMWindow(/* [retval][out] */ IDOMWindow** window) 463{ 464 if (!window) { 465 ASSERT_NOT_REACHED(); 466 return E_POINTER; 467 } 468 469 *window = 0; 470 471 if (Frame* coreFrame = core(this)) { 472 if (WebCore::DOMWindow* coreWindow = coreFrame->document()->domWindow()) 473 *window = ::DOMWindow::createInstance(coreWindow); 474 } 475 476 return *window ? S_OK : E_FAIL; 477} 478 479HRESULT STDMETHODCALLTYPE WebFrame::frameElement( 480 /* [retval][out] */ IDOMHTMLElement** frameElement) 481{ 482 if (!frameElement) 483 return E_POINTER; 484 485 *frameElement = 0; 486 Frame* coreFrame = core(this); 487 if (!coreFrame) 488 return E_FAIL; 489 490 COMPtr<IDOMElement> domElement(AdoptCOM, DOMElement::createInstance(coreFrame->ownerElement())); 491 COMPtr<IDOMHTMLElement> htmlElement(Query, domElement); 492 if (!htmlElement) 493 return E_FAIL; 494 return htmlElement.copyRefTo(frameElement); 495} 496 497HRESULT STDMETHODCALLTYPE WebFrame::currentForm( 498 /* [retval][out] */ IDOMElement **currentForm) 499{ 500 if (!currentForm) { 501 ASSERT_NOT_REACHED(); 502 return E_POINTER; 503 } 504 505 *currentForm = 0; 506 507 if (Frame* coreFrame = core(this)) { 508 if (HTMLFormElement* formElement = coreFrame->selection().currentForm()) 509 *currentForm = DOMElement::createInstance(formElement); 510 } 511 512 return *currentForm ? S_OK : E_FAIL; 513} 514 515JSGlobalContextRef STDMETHODCALLTYPE WebFrame::globalContext() 516{ 517 Frame* coreFrame = core(this); 518 if (!coreFrame) 519 return 0; 520 521 return toGlobalRef(coreFrame->script().globalObject(mainThreadNormalWorld())->globalExec()); 522} 523 524JSGlobalContextRef WebFrame::globalContextForScriptWorld(IWebScriptWorld* iWorld) 525{ 526 Frame* coreFrame = core(this); 527 if (!coreFrame) 528 return 0; 529 530 COMPtr<WebScriptWorld> world(Query, iWorld); 531 if (!world) 532 return 0; 533 534 return toGlobalRef(coreFrame->script().globalObject(world->world())->globalExec()); 535} 536 537HRESULT STDMETHODCALLTYPE WebFrame::loadRequest( 538 /* [in] */ IWebURLRequest* request) 539{ 540 COMPtr<WebMutableURLRequest> requestImpl; 541 542 HRESULT hr = request->QueryInterface(&requestImpl); 543 if (FAILED(hr)) 544 return hr; 545 546 Frame* coreFrame = core(this); 547 if (!coreFrame) 548 return E_FAIL; 549 550 coreFrame->loader().load(FrameLoadRequest(coreFrame, requestImpl->resourceRequest())); 551 return S_OK; 552} 553 554void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL) 555{ 556 String mimeTypeString(mimeType, SysStringLen(mimeType)); 557 if (!mimeType) 558 mimeTypeString = "text/html"; 559 560 String encodingString(textEncodingName, SysStringLen(textEncodingName)); 561 562 // FIXME: We should really be using MarshallingHelpers::BSTRToKURL here, 563 // but that would turn a null BSTR into a null URL, and we crash inside of 564 // WebCore if we use a null URL in constructing the ResourceRequest. 565 URL baseKURL = URL(URL(), String(baseURL ? baseURL : L"", SysStringLen(baseURL))); 566 567 URL failingKURL = MarshallingHelpers::BSTRToKURL(failingURL); 568 569 ResourceRequest request(baseKURL); 570 SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL); 571 572 // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null. 573 if (Frame* coreFrame = core(this)) 574 coreFrame->loader().load(FrameLoadRequest(coreFrame, request, substituteData)); 575} 576 577 578HRESULT STDMETHODCALLTYPE WebFrame::loadData( 579 /* [in] */ IStream* data, 580 /* [in] */ BSTR mimeType, 581 /* [in] */ BSTR textEncodingName, 582 /* [in] */ BSTR url) 583{ 584 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(); 585 586 STATSTG stat; 587 if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) { 588 if (!stat.cbSize.HighPart && stat.cbSize.LowPart) { 589 Vector<char> dataBuffer(stat.cbSize.LowPart); 590 ULONG read; 591 // FIXME: this does a needless copy, would be better to read right into the SharedBuffer 592 // or adopt the Vector or something. 593 if (SUCCEEDED(data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read))) 594 sharedBuffer->append(dataBuffer.data(), static_cast<int>(dataBuffer.size())); 595 } 596 } 597 598 loadData(sharedBuffer, mimeType, textEncodingName, url, 0); 599 return S_OK; 600} 601 602HRESULT WebFrame::loadPlainTextString( 603 /* [in] */ BSTR string, 604 /* [in] */ BSTR url) 605{ 606 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string)); 607 BString plainTextMimeType(TEXT("text/plain"), 10); 608 BString utf16Encoding(TEXT("utf-16"), 6); 609 loadData(sharedBuffer.release(), plainTextMimeType, utf16Encoding, url, 0); 610 return S_OK; 611} 612 613void WebFrame::loadHTMLString(BSTR string, BSTR baseURL, BSTR unreachableURL) 614{ 615 RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string)); 616 BString utf16Encoding(TEXT("utf-16"), 6); 617 loadData(sharedBuffer.release(), 0, utf16Encoding, baseURL, unreachableURL); 618} 619 620HRESULT STDMETHODCALLTYPE WebFrame::loadHTMLString( 621 /* [in] */ BSTR string, 622 /* [in] */ BSTR baseURL) 623{ 624 loadHTMLString(string, baseURL, 0); 625 return S_OK; 626} 627 628HRESULT STDMETHODCALLTYPE WebFrame::loadAlternateHTMLString( 629 /* [in] */ BSTR str, 630 /* [in] */ BSTR baseURL, 631 /* [in] */ BSTR unreachableURL) 632{ 633 loadHTMLString(str, baseURL, unreachableURL); 634 return S_OK; 635} 636 637HRESULT STDMETHODCALLTYPE WebFrame::loadArchive( 638 /* [in] */ IWebArchive* /*archive*/) 639{ 640 ASSERT_NOT_REACHED(); 641 return E_NOTIMPL; 642} 643 644static inline WebDataSource *getWebDataSource(DocumentLoader* loader) 645{ 646 return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0; 647} 648 649HRESULT STDMETHODCALLTYPE WebFrame::dataSource( 650 /* [retval][out] */ IWebDataSource** source) 651{ 652 if (!source) { 653 ASSERT_NOT_REACHED(); 654 return E_POINTER; 655 } 656 657 *source = 0; 658 659 Frame* coreFrame = core(this); 660 if (!coreFrame) 661 return E_FAIL; 662 663 WebDataSource* webDataSource = getWebDataSource(coreFrame->loader().documentLoader()); 664 665 *source = webDataSource; 666 667 if (webDataSource) 668 webDataSource->AddRef(); 669 670 return *source ? S_OK : E_FAIL; 671} 672 673HRESULT STDMETHODCALLTYPE WebFrame::provisionalDataSource( 674 /* [retval][out] */ IWebDataSource** source) 675{ 676 if (!source) { 677 ASSERT_NOT_REACHED(); 678 return E_POINTER; 679 } 680 681 *source = 0; 682 683 Frame* coreFrame = core(this); 684 if (!coreFrame) 685 return E_FAIL; 686 687 WebDataSource* webDataSource = getWebDataSource(coreFrame->loader().provisionalDocumentLoader()); 688 689 *source = webDataSource; 690 691 if (webDataSource) 692 webDataSource->AddRef(); 693 694 return *source ? S_OK : E_FAIL; 695} 696 697URL WebFrame::url() const 698{ 699 Frame* coreFrame = core(this); 700 if (!coreFrame) 701 return URL(); 702 703 return coreFrame->document()->url(); 704} 705 706HRESULT STDMETHODCALLTYPE WebFrame::stopLoading( void) 707{ 708 if (Frame* coreFrame = core(this)) 709 coreFrame->loader().stopAllLoaders(); 710 return S_OK; 711} 712 713HRESULT STDMETHODCALLTYPE WebFrame::reload( void) 714{ 715 Frame* coreFrame = core(this); 716 if (!coreFrame) 717 return E_FAIL; 718 719 coreFrame->loader().reload(); 720 return S_OK; 721} 722 723HRESULT STDMETHODCALLTYPE WebFrame::findFrameNamed( 724 /* [in] */ BSTR name, 725 /* [retval][out] */ IWebFrame** frame) 726{ 727 if (!frame) { 728 ASSERT_NOT_REACHED(); 729 return E_POINTER; 730 } 731 732 *frame = 0; 733 734 Frame* coreFrame = core(this); 735 if (!coreFrame) 736 return E_FAIL; 737 738 Frame* foundFrame = coreFrame->tree().find(AtomicString(name, SysStringLen(name))); 739 if (!foundFrame) 740 return S_OK; 741 742 WebFrame* foundWebFrame = kit(foundFrame); 743 if (!foundWebFrame) 744 return E_FAIL; 745 746 return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame); 747} 748 749HRESULT STDMETHODCALLTYPE WebFrame::parentFrame( 750 /* [retval][out] */ IWebFrame** frame) 751{ 752 HRESULT hr = S_OK; 753 *frame = 0; 754 if (Frame* coreFrame = core(this)) 755 if (WebFrame* webFrame = kit(coreFrame->tree().parent())) 756 hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame); 757 758 return hr; 759} 760 761class EnumChildFrames : public IEnumVARIANT 762{ 763public: 764 EnumChildFrames(Frame* f) : m_refCount(1), m_frame(f), m_curChild(f ? f->tree().firstChild() : 0) { } 765 766 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) 767 { 768 *ppvObject = 0; 769 if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT)) 770 *ppvObject = this; 771 else 772 return E_NOINTERFACE; 773 774 AddRef(); 775 return S_OK; 776 } 777 778 virtual ULONG STDMETHODCALLTYPE AddRef(void) 779 { 780 return ++m_refCount; 781 } 782 783 virtual ULONG STDMETHODCALLTYPE Release(void) 784 { 785 ULONG newRef = --m_refCount; 786 if (!newRef) 787 delete(this); 788 return newRef; 789 } 790 791 virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) 792 { 793 if (pCeltFetched) 794 *pCeltFetched = 0; 795 if (!rgVar) 796 return E_POINTER; 797 VariantInit(rgVar); 798 if (!celt || celt > 1) 799 return S_FALSE; 800 if (!m_frame || !m_curChild) 801 return S_FALSE; 802 803 WebFrame* webFrame = kit(m_curChild); 804 IUnknown* unknown; 805 HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown); 806 if (FAILED(hr)) 807 return hr; 808 809 V_VT(rgVar) = VT_UNKNOWN; 810 V_UNKNOWN(rgVar) = unknown; 811 812 m_curChild = m_curChild->tree().nextSibling(); 813 if (pCeltFetched) 814 *pCeltFetched = 1; 815 return S_OK; 816 } 817 818 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt) 819 { 820 if (!m_frame) 821 return S_FALSE; 822 for (unsigned i = 0; i < celt && m_curChild; i++) 823 m_curChild = m_curChild->tree().nextSibling(); 824 return m_curChild ? S_OK : S_FALSE; 825 } 826 827 virtual HRESULT STDMETHODCALLTYPE Reset(void) 828 { 829 if (!m_frame) 830 return S_FALSE; 831 m_curChild = m_frame->tree().firstChild(); 832 return S_OK; 833 } 834 835 virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**) 836 { 837 return E_NOTIMPL; 838 } 839 840private: 841 ULONG m_refCount; 842 Frame* m_frame; 843 Frame* m_curChild; 844}; 845 846HRESULT STDMETHODCALLTYPE WebFrame::childFrames( 847 /* [retval][out] */ IEnumVARIANT **enumFrames) 848{ 849 if (!enumFrames) 850 return E_POINTER; 851 852 *enumFrames = new EnumChildFrames(core(this)); 853 return S_OK; 854} 855 856// IWebFramePrivate ------------------------------------------------------ 857 858HRESULT WebFrame::renderTreeAsExternalRepresentation(BOOL forPrinting, BSTR *result) 859{ 860 if (!result) 861 return E_POINTER; 862 863 Frame* coreFrame = core(this); 864 if (!coreFrame) 865 return E_FAIL; 866 867 *result = BString(externalRepresentation(coreFrame, forPrinting ? RenderAsTextPrintingMode : RenderAsTextBehaviorNormal)).release(); 868 return S_OK; 869} 870 871HRESULT STDMETHODCALLTYPE WebFrame::pageNumberForElementById( 872 /* [in] */ BSTR id, 873 /* [in] */ float pageWidthInPixels, 874 /* [in] */ float pageHeightInPixels, 875 /* [retval][out] */ int* result) 876{ 877 // TODO: Please remove this function if not needed as this is LTC specific function 878 // and has been moved to Internals. 879 notImplemented(); 880 return E_FAIL; 881} 882 883HRESULT STDMETHODCALLTYPE WebFrame::numberOfPages( 884 /* [in] */ float pageWidthInPixels, 885 /* [in] */ float pageHeightInPixels, 886 /* [retval][out] */ int* result) 887{ 888 // TODO: Please remove this function if not needed as this is LTC specific function 889 // and has been moved to Internals. 890 notImplemented(); 891 return E_FAIL; 892} 893 894HRESULT STDMETHODCALLTYPE WebFrame::scrollOffset( 895 /* [retval][out] */ SIZE* offset) 896{ 897 if (!offset) { 898 ASSERT_NOT_REACHED(); 899 return E_POINTER; 900 } 901 902 Frame* coreFrame = core(this); 903 if (!coreFrame) 904 return E_FAIL; 905 906 FrameView* view = coreFrame->view(); 907 if (!view) 908 return E_FAIL; 909 910 *offset = view->scrollOffset(); 911 return S_OK; 912} 913 914HRESULT STDMETHODCALLTYPE WebFrame::layout() 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 view->layout(); 925 return S_OK; 926} 927 928HRESULT STDMETHODCALLTYPE WebFrame::firstLayoutDone( 929 /* [retval][out] */ BOOL* result) 930{ 931 if (!result) { 932 ASSERT_NOT_REACHED(); 933 return E_POINTER; 934 } 935 936 *result = 0; 937 938 Frame* coreFrame = core(this); 939 if (!coreFrame) 940 return E_FAIL; 941 942 *result = coreFrame->loader().stateMachine().firstLayoutDone(); 943 return S_OK; 944} 945 946HRESULT STDMETHODCALLTYPE WebFrame::pendingFrameUnloadEventCount( 947 /* [retval][out] */ UINT* result) 948{ 949 if (!result) { 950 ASSERT_NOT_REACHED(); 951 return E_POINTER; 952 } 953 954 *result = 0; 955 956 Frame* coreFrame = core(this); 957 if (!coreFrame) 958 return E_FAIL; 959 960 *result = coreFrame->document()->domWindow()->pendingUnloadEventListeners(); 961 return S_OK; 962} 963 964HRESULT STDMETHODCALLTYPE WebFrame::hasSpellingMarker( 965 /* [in] */ UINT from, 966 /* [in] */ UINT length, 967 /* [retval][out] */ BOOL* result) 968{ 969 Frame* coreFrame = core(this); 970 if (!coreFrame) 971 return E_FAIL; 972 *result = coreFrame->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length); 973 return S_OK; 974} 975 976HRESULT STDMETHODCALLTYPE WebFrame::clearOpener() 977{ 978 HRESULT hr = S_OK; 979 if (Frame* coreFrame = core(this)) 980 coreFrame->loader().setOpener(0); 981 982 return hr; 983} 984 985HRESULT WebFrame::setTextDirection(BSTR direction) 986{ 987 Frame* coreFrame = core(this); 988 if (!coreFrame) 989 return E_FAIL; 990 991 String directionString(direction, SysStringLen(direction)); 992 if (directionString == "auto") 993 coreFrame->editor().setBaseWritingDirection(NaturalWritingDirection); 994 else if (directionString == "ltr") 995 coreFrame->editor().setBaseWritingDirection(LeftToRightWritingDirection); 996 else if (directionString == "rtl") 997 coreFrame->editor().setBaseWritingDirection(RightToLeftWritingDirection); 998 return S_OK; 999} 1000 1001// IWebDocumentText ----------------------------------------------------------- 1002 1003HRESULT STDMETHODCALLTYPE WebFrame::supportsTextEncoding( 1004 /* [retval][out] */ BOOL* result) 1005{ 1006 *result = FALSE; 1007 return E_NOTIMPL; 1008} 1009 1010HRESULT STDMETHODCALLTYPE WebFrame::selectedString( 1011 /* [retval][out] */ BSTR* result) 1012{ 1013 *result = 0; 1014 1015 Frame* coreFrame = core(this); 1016 if (!coreFrame) 1017 return E_FAIL; 1018 1019 String text = coreFrame->displayStringModifiedByEncoding(coreFrame->editor().selectedText()); 1020 1021 *result = BString(text).release(); 1022 return S_OK; 1023} 1024 1025HRESULT STDMETHODCALLTYPE WebFrame::selectAll() 1026{ 1027 Frame* coreFrame = core(this); 1028 if (!coreFrame) 1029 return E_FAIL; 1030 1031 if (!coreFrame->editor().command("SelectAll").execute()) 1032 return E_FAIL; 1033 1034 return S_OK; 1035} 1036 1037HRESULT STDMETHODCALLTYPE WebFrame::deselectAll() 1038{ 1039 return E_NOTIMPL; 1040} 1041 1042// WebFrame --------------------------------------------------------------- 1043 1044PassRefPtr<Frame> WebFrame::createSubframeWithOwnerElement(IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement) 1045{ 1046 webView->QueryInterface(&d->webView); 1047 d->webView->Release(); // don't hold the extra ref 1048 1049 HWND viewWindow; 1050 d->webView->viewWindow(&viewWindow); 1051 1052 this->AddRef(); // We release this ref in frameLoaderDestroyed() 1053 RefPtr<Frame> frame = Frame::create(page, ownerElement, new WebFrameLoaderClient(this)); 1054 d->frame = frame.get(); 1055 return frame.release(); 1056} 1057 1058void WebFrame::initWithWebView(IWebView* webView, Page* page) 1059{ 1060 webView->QueryInterface(&d->webView); 1061 d->webView->Release(); // don't hold the extra ref 1062 1063 HWND viewWindow; 1064 d->webView->viewWindow(&viewWindow); 1065 1066 this->AddRef(); // We release this ref in frameLoaderDestroyed() 1067 d->frame = &page->mainFrame(); 1068} 1069 1070Frame* WebFrame::impl() 1071{ 1072 return d->frame; 1073} 1074 1075void WebFrame::invalidate() 1076{ 1077 Frame* coreFrame = core(this); 1078 ASSERT(coreFrame); 1079 1080 if (Document* document = coreFrame->document()) 1081 document->recalcStyle(Style::Force); 1082} 1083 1084HRESULT WebFrame::inViewSourceMode(BOOL* flag) 1085{ 1086 return E_NOTIMPL; 1087} 1088 1089HRESULT WebFrame::setInViewSourceMode(BOOL flag) 1090{ 1091 return E_NOTIMPL; 1092} 1093 1094HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element) 1095{ 1096 if (!form) 1097 return E_INVALIDARG; 1098 1099 HTMLFormElement* formElement = formElementFromDOMElement(form); 1100 if (formElement) { 1101 const Vector<FormAssociatedElement*>& elements = formElement->associatedElements(); 1102 AtomicString targetName((UChar*)name, SysStringLen(name)); 1103 for (unsigned int i = 0; i < elements.size(); i++) { 1104 if (!elements[i]->isFormControlElement()) 1105 continue; 1106 HTMLFormControlElement* elt = toHTMLFormControlElement(elements[i]); 1107 // Skip option elements, other duds 1108 if (elt->name() == targetName) { 1109 *element = DOMElement::createInstance(elt); 1110 return S_OK; 1111 } 1112 } 1113 } 1114 return E_FAIL; 1115} 1116 1117HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form) 1118{ 1119 if (!element) 1120 return E_INVALIDARG; 1121 1122 HTMLInputElement *inputElement = inputElementFromDOMElement(element); 1123 if (!inputElement) 1124 return E_FAIL; 1125 1126 HTMLFormElement *formElement = inputElement->form(); 1127 if (!formElement) 1128 return E_FAIL; 1129 1130 *form = DOMElement::createInstance(formElement); 1131 return S_OK; 1132} 1133 1134HRESULT WebFrame::elementDoesAutoComplete(IDOMElement *element, BOOL *result) 1135{ 1136 *result = false; 1137 if (!element) 1138 return E_INVALIDARG; 1139 1140 HTMLInputElement *inputElement = inputElementFromDOMElement(element); 1141 if (!inputElement) 1142 *result = false; 1143 else 1144 *result = inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->shouldAutocomplete(); 1145 1146 return S_OK; 1147} 1148 1149HRESULT STDMETHODCALLTYPE WebFrame::resumeAnimations() 1150{ 1151 Frame* frame = core(this); 1152 if (!frame) 1153 return E_FAIL; 1154 1155 frame->animation().resumeAnimations(); 1156 return S_OK; 1157} 1158 1159HRESULT STDMETHODCALLTYPE WebFrame::suspendAnimations() 1160{ 1161 Frame* frame = core(this); 1162 if (!frame) 1163 return E_FAIL; 1164 1165 frame->animation().suspendAnimations(); 1166 return S_OK; 1167} 1168 1169HRESULT WebFrame::pauseAnimation(BSTR animationName, IDOMNode* node, double secondsFromNow, BOOL* animationWasRunning) 1170{ 1171 if (!node || !animationWasRunning) 1172 return E_POINTER; 1173 1174 *animationWasRunning = FALSE; 1175 1176 Frame* frame = core(this); 1177 if (!frame) 1178 return E_FAIL; 1179 1180 COMPtr<DOMNode> domNode(Query, node); 1181 if (!domNode) 1182 return E_FAIL; 1183 1184 *animationWasRunning = frame->animation().pauseAnimationAtTime(toRenderElement(domNode->node()->renderer()), String(animationName, SysStringLen(animationName)), secondsFromNow); 1185 return S_OK; 1186} 1187 1188HRESULT WebFrame::pauseTransition(BSTR propertyName, IDOMNode* node, double secondsFromNow, BOOL* transitionWasRunning) 1189{ 1190 if (!node || !transitionWasRunning) 1191 return E_POINTER; 1192 1193 *transitionWasRunning = FALSE; 1194 1195 Frame* frame = core(this); 1196 if (!frame) 1197 return E_FAIL; 1198 1199 COMPtr<DOMNode> domNode(Query, node); 1200 if (!domNode) 1201 return E_FAIL; 1202 1203 *transitionWasRunning = frame->animation().pauseTransitionAtTime(toRenderElement(domNode->node()->renderer()), String(propertyName, SysStringLen(propertyName)), secondsFromNow); 1204 return S_OK; 1205} 1206 1207HRESULT WebFrame::visibleContentRect(RECT* rect) 1208{ 1209 if (!rect) 1210 return E_POINTER; 1211 SetRectEmpty(rect); 1212 1213 Frame* frame = core(this); 1214 if (!frame) 1215 return E_FAIL; 1216 1217 FrameView* view = frame->view(); 1218 if (!view) 1219 return E_FAIL; 1220 1221 *rect = view->visibleContentRect(); 1222 return S_OK; 1223} 1224 1225HRESULT WebFrame::numberOfActiveAnimations(UINT* number) 1226{ 1227 if (!number) 1228 return E_POINTER; 1229 1230 *number = 0; 1231 1232 Frame* frame = core(this); 1233 if (!frame) 1234 return E_FAIL; 1235 1236 *number = frame->animation().numberOfActiveAnimations(frame->document()); 1237 return S_OK; 1238} 1239 1240HRESULT WebFrame::isDisplayingStandaloneImage(BOOL* result) 1241{ 1242 if (!result) 1243 return E_POINTER; 1244 1245 *result = FALSE; 1246 1247 Frame* frame = core(this); 1248 if (!frame) 1249 return E_FAIL; 1250 1251 Document* document = frame->document(); 1252 *result = document && document->isImageDocument(); 1253 return S_OK; 1254} 1255 1256HRESULT WebFrame::allowsFollowingLink(BSTR url, BOOL* result) 1257{ 1258 if (!result) 1259 return E_POINTER; 1260 1261 *result = TRUE; 1262 1263 Frame* frame = core(this); 1264 if (!frame) 1265 return E_FAIL; 1266 1267 *result = frame->document()->securityOrigin()->canDisplay(MarshallingHelpers::BSTRToKURL(url)); 1268 return S_OK; 1269} 1270 1271HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls) 1272{ 1273 if (!form) 1274 return E_INVALIDARG; 1275 1276 HTMLFormElement* formElement = formElementFromDOMElement(form); 1277 if (!formElement) 1278 return E_FAIL; 1279 1280 int inCount = *cControls; 1281 int count = (int) formElement->associatedElements().size(); 1282 *cControls = count; 1283 if (!controls) 1284 return S_OK; 1285 if (inCount < count) 1286 return E_FAIL; 1287 1288 *cControls = 0; 1289 const Vector<FormAssociatedElement*>& elements = formElement->associatedElements(); 1290 for (int i = 0; i < count; i++) { 1291 if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds 1292 controls[*cControls] = DOMElement::createInstance(&elements.at(i)->asHTMLElement()); 1293 (*cControls)++; 1294 } 1295 } 1296 return S_OK; 1297} 1298 1299HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result) 1300{ 1301 HTMLInputElement* inputElement = inputElementFromDOMElement(element); 1302 *result = inputElement && inputElement->isPasswordField(); 1303 return S_OK; 1304} 1305 1306HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, unsigned cLabels, IDOMElement* beforeElement, unsigned* outResultDistance, BOOL* outResultIsInCellAbove, BSTR* result) 1307{ 1308 if (!result) { 1309 ASSERT_NOT_REACHED(); 1310 return E_POINTER; 1311 } 1312 1313 if (outResultDistance) 1314 *outResultDistance = 0; 1315 if (outResultIsInCellAbove) 1316 *outResultIsInCellAbove = FALSE; 1317 *result = 0; 1318 1319 if (!cLabels) 1320 return S_OK; 1321 if (cLabels < 1) 1322 return E_INVALIDARG; 1323 1324 Frame* coreFrame = core(this); 1325 if (!coreFrame) 1326 return E_FAIL; 1327 1328 Vector<String> labelStrings(cLabels); 1329 for (int i=0; i<cLabels; i++) 1330 labelStrings[i] = String(labels[i], SysStringLen(labels[i])); 1331 Element *coreElement = elementFromDOMElement(beforeElement); 1332 if (!coreElement) 1333 return E_FAIL; 1334 1335 size_t resultDistance; 1336 bool resultIsInCellAbove; 1337 String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement, &resultDistance, &resultIsInCellAbove); 1338 1339 *result = BString(label).release(); 1340 if (label.length() && !*result) 1341 return E_OUTOFMEMORY; 1342 if (outResultDistance) 1343 *outResultDistance = resultDistance; 1344 if (outResultIsInCellAbove) 1345 *outResultIsInCellAbove = resultIsInCellAbove; 1346 1347 return S_OK; 1348} 1349 1350HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result) 1351{ 1352 if (!result) { 1353 ASSERT_NOT_REACHED(); 1354 return E_POINTER; 1355 } 1356 1357 *result = 0; 1358 1359 if (!cLabels) 1360 return S_OK; 1361 if (cLabels < 1) 1362 return E_INVALIDARG; 1363 1364 Frame* coreFrame = core(this); 1365 if (!coreFrame) 1366 return E_FAIL; 1367 1368 Vector<String> labelStrings(cLabels); 1369 for (int i=0; i<cLabels; i++) 1370 labelStrings[i] = String(labels[i], SysStringLen(labels[i])); 1371 Element *coreElement = elementFromDOMElement(againstElement); 1372 if (!coreElement) 1373 return E_FAIL; 1374 1375 String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement); 1376 1377 *result = BString(label).release(); 1378 if (label.length() && !*result) 1379 return E_OUTOFMEMORY; 1380 return S_OK; 1381} 1382 1383HRESULT WebFrame::canProvideDocumentSource(bool* result) 1384{ 1385 HRESULT hr = S_OK; 1386 *result = false; 1387 1388 COMPtr<IWebDataSource> dataSource; 1389 hr = WebFrame::dataSource(&dataSource); 1390 if (FAILED(hr)) 1391 return hr; 1392 1393 COMPtr<IWebURLResponse> urlResponse; 1394 hr = dataSource->response(&urlResponse); 1395 if (SUCCEEDED(hr) && urlResponse) { 1396 BString mimeTypeBStr; 1397 if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) { 1398 String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr)); 1399 *result = mimeType == "text/html" || WebCore::DOMImplementation::isXMLMIMEType(mimeType); 1400 } 1401 } 1402 return hr; 1403} 1404 1405HRESULT STDMETHODCALLTYPE WebFrame::layerTreeAsText(BSTR* result) 1406{ 1407 if (!result) 1408 return E_POINTER; 1409 *result = 0; 1410 1411 Frame* frame = core(this); 1412 if (!frame) 1413 return E_FAIL; 1414 1415 String text = frame->layerTreeAsText(); 1416 *result = BString(text).release(); 1417 return S_OK; 1418} 1419 1420void WebFrame::frameLoaderDestroyed() 1421{ 1422 // The FrameLoader going away is equivalent to the Frame going away, 1423 // so we now need to clear our frame pointer. 1424 d->frame = 0; 1425 1426 this->Release(); 1427} 1428 1429static IntRect printerRect(HDC printDC) 1430{ 1431 return IntRect(0, 0, 1432 GetDeviceCaps(printDC, PHYSICALWIDTH) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX), 1433 GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY)); 1434} 1435 1436void WebFrame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot adjustViewSize) 1437{ 1438 Frame* coreFrame = core(this); 1439 ASSERT(coreFrame); 1440 coreFrame->setPrinting(printing, pageSize, originalPageSize, maximumShrinkRatio, adjustViewSize ? AdjustViewSize : DoNotAdjustViewSize); 1441} 1442 1443HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode( 1444 /* [in] */ BOOL value, 1445 /* [in] */ HDC printDC) 1446{ 1447 if (m_inPrintingMode == !!value) 1448 return S_OK; 1449 1450 Frame* coreFrame = core(this); 1451 if (!coreFrame || !coreFrame->document()) 1452 return E_FAIL; 1453 1454 m_inPrintingMode = !!value; 1455 1456 // If we are a frameset just print with the layout we have onscreen, otherwise relayout 1457 // according to the paper size 1458 FloatSize minLayoutSize(0.0, 0.0); 1459 FloatSize originalPageSize(0.0, 0.0); 1460 if (m_inPrintingMode && !coreFrame->document()->isFrameSet()) { 1461 if (!printDC) { 1462 ASSERT_NOT_REACHED(); 1463 return E_POINTER; 1464 } 1465 1466 const int desiredPixelsPerInch = 72; 1467 IntRect printRect = printerRect(printDC); 1468 int paperHorizontalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSX); 1469 int paperVerticalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSY); 1470 int paperWidth = printRect.width() * desiredPixelsPerInch / paperHorizontalPixelsPerInch; 1471 int paperHeight = printRect.height() * desiredPixelsPerInch / paperVerticalPixelsPerInch; 1472 originalPageSize = FloatSize(paperWidth, paperHeight); 1473 Frame* coreFrame = core(this); 1474 minLayoutSize = coreFrame->resizePageRectsKeepingRatio(originalPageSize, FloatSize(paperWidth * PrintingMinimumShrinkFactor, paperHeight * PrintingMinimumShrinkFactor)); 1475 } 1476 1477 setPrinting(m_inPrintingMode, minLayoutSize, originalPageSize, PrintingMaximumShrinkFactor / PrintingMinimumShrinkFactor, AdjustViewSize); 1478 1479 if (!m_inPrintingMode) 1480 m_pageRects.clear(); 1481 1482 return S_OK; 1483} 1484 1485void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight) 1486{ 1487 if (headerHeight) 1488 *headerHeight = 0; 1489 if (footerHeight) 1490 *footerHeight = 0; 1491 float height = 0; 1492 COMPtr<IWebUIDelegate> ui; 1493 if (FAILED(d->webView->uiDelegate(&ui))) 1494 return; 1495 if (headerHeight && SUCCEEDED(ui->webViewHeaderHeight(d->webView, &height))) 1496 *headerHeight = height; 1497 if (footerHeight && SUCCEEDED(ui->webViewFooterHeight(d->webView, &height))) 1498 *footerHeight = height; 1499} 1500 1501IntRect WebFrame::printerMarginRect(HDC printDC) 1502{ 1503 IntRect emptyRect(0, 0, 0, 0); 1504 1505 COMPtr<IWebUIDelegate> ui; 1506 if (FAILED(d->webView->uiDelegate(&ui))) 1507 return emptyRect; 1508 1509 RECT rect; 1510 if (FAILED(ui->webViewPrintingMarginRect(d->webView, &rect))) 1511 return emptyRect; 1512 1513 rect.left = MulDiv(rect.left, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000); 1514 rect.top = MulDiv(rect.top, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000); 1515 rect.right = MulDiv(rect.right, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000); 1516 rect.bottom = MulDiv(rect.bottom, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000); 1517 1518 return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top); 1519} 1520 1521const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC) 1522{ 1523 ASSERT(m_inPrintingMode); 1524 1525 Frame* coreFrame = core(this); 1526 ASSERT(coreFrame); 1527 ASSERT(coreFrame->document()); 1528 1529 if (!printDC) 1530 return m_pageRects; 1531 1532 // adjust the page rect by the header and footer 1533 float headerHeight = 0, footerHeight = 0; 1534 headerAndFooterHeights(&headerHeight, &footerHeight); 1535 IntRect pageRect = printerRect(printDC); 1536 IntRect marginRect = printerMarginRect(printDC); 1537 IntRect adjustedRect = IntRect( 1538 pageRect.x() + marginRect.x(), 1539 pageRect.y() + marginRect.y(), 1540 pageRect.width() - marginRect.x() - marginRect.maxX(), 1541 pageRect.height() - marginRect.y() - marginRect.maxY()); 1542 1543 computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight); 1544 1545 return m_pageRects; 1546} 1547 1548HRESULT STDMETHODCALLTYPE WebFrame::getPrintedPageCount( 1549 /* [in] */ HDC printDC, 1550 /* [retval][out] */ UINT *pageCount) 1551{ 1552 if (!pageCount || !printDC) { 1553 ASSERT_NOT_REACHED(); 1554 return E_POINTER; 1555 } 1556 1557 *pageCount = 0; 1558 1559 if (!m_inPrintingMode) { 1560 ASSERT_NOT_REACHED(); 1561 return E_FAIL; 1562 } 1563 1564 Frame* coreFrame = core(this); 1565 if (!coreFrame || !coreFrame->document()) 1566 return E_FAIL; 1567 1568 const Vector<IntRect>& pages = computePageRects(printDC); 1569 *pageCount = (UINT) pages.size(); 1570 1571 return S_OK; 1572} 1573 1574#if USE(CG) 1575void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight) 1576{ 1577 int x = pageRect.x(); 1578 int y = 0; 1579 RECT headerRect = {x, y, x+pageRect.width(), y+static_cast<int>(headerHeight)}; 1580 ui->drawHeaderInRect(d->webView, &headerRect, reinterpret_cast<ULONG_PTR>(pctx)); 1581} 1582 1583void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight) 1584{ 1585 int x = pageRect.x(); 1586 int y = max((int)headerHeight+pageRect.height(), m_pageHeight-static_cast<int>(footerHeight)); 1587 RECT footerRect = {x, y, x+pageRect.width(), y+static_cast<int>(footerHeight)}; 1588 ui->drawFooterInRect(d->webView, &footerRect, reinterpret_cast<ULONG_PTR>(pctx), page + 1, pageCount); 1589} 1590 1591void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount) 1592{ 1593 Frame* coreFrame = core(this); 1594 1595 IntRect pageRect = m_pageRects[page]; 1596 1597 CGContextSaveGState(pctx); 1598 1599 IntRect printRect = printerRect(printDC); 1600 CGRect mediaBox = CGRectMake(CGFloat(0), 1601 CGFloat(0), 1602 CGFloat(printRect.width()), 1603 CGFloat(printRect.height())); 1604 1605 CGContextBeginPage(pctx, &mediaBox); 1606 1607 CGFloat scale = static_cast<float>(mediaBox.size.width)/static_cast<float>(pageRect.width()); 1608 CGAffineTransform ctm = CGContextGetBaseCTM(pctx); 1609 ctm = CGAffineTransformScale(ctm, -scale, -scale); 1610 ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header 1611 CGContextScaleCTM(pctx, scale, scale); 1612 CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header 1613 CGContextSetBaseCTM(pctx, ctm); 1614 1615 coreFrame->view()->paintContents(spoolCtx, pageRect); 1616 1617 CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight); 1618 1619 if (headerHeight) 1620 drawHeader(pctx, ui, pageRect, headerHeight); 1621 1622 if (footerHeight) 1623 drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight); 1624 1625 CGContextEndPage(pctx); 1626 CGContextRestoreGState(pctx); 1627} 1628#elif USE(CAIRO) 1629static float scaleFactor(HDC printDC, const IntRect& marginRect, const IntRect& pageRect) 1630{ 1631 const IntRect& printRect = printerRect(printDC); 1632 1633 IntRect adjustedRect = IntRect( 1634 printRect.x() + marginRect.x(), 1635 printRect.y() + marginRect.y(), 1636 printRect.width() - marginRect.x() - marginRect.maxX(), 1637 printRect.height() - marginRect.y() - marginRect.maxY()); 1638 1639 float scale = static_cast<float>(adjustedRect.width()) / static_cast<float>(pageRect.width()); 1640 if (!scale) 1641 scale = 1.0; 1642 1643 return scale; 1644} 1645 1646static HDC hdcFromContext(PlatformGraphicsContext* pctx) 1647{ 1648 return cairo_win32_surface_get_dc(cairo_get_target(pctx->cr())); 1649} 1650 1651void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight) 1652{ 1653 HDC hdc = hdcFromContext(pctx); 1654 1655 int x = pageRect.x(); 1656 int y = 0; 1657 RECT headerRect = {x, y, x + pageRect.width(), y + static_cast<int>(headerHeight)}; 1658 1659 ui->drawHeaderInRect(d->webView, &headerRect, reinterpret_cast<ULONG_PTR>(hdc)); 1660} 1661 1662void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight) 1663{ 1664 HDC hdc = hdcFromContext(pctx); 1665 1666 int x = pageRect.x(); 1667 int y = max(static_cast<int>(headerHeight) + pageRect.height(), m_pageHeight -static_cast<int>(footerHeight)); 1668 RECT footerRect = {x, y, x + pageRect.width(), y + static_cast<int>(footerHeight)}; 1669 1670 ui->drawFooterInRect(d->webView, &footerRect, reinterpret_cast<ULONG_PTR>(hdc), page+1, pageCount); 1671} 1672 1673static XFORM buildXFORMFromCairo(HDC targetDC, cairo_t* previewContext) 1674{ 1675 XFORM scaled; 1676 GetWorldTransform(targetDC, &scaled); 1677 1678 cairo_matrix_t ctm; 1679 cairo_get_matrix(previewContext, &ctm); 1680 1681 // Scale to the preview screen bounds 1682 scaled.eM11 = ctm.xx; 1683 scaled.eM22 = ctm.yy; 1684 1685 return scaled; 1686} 1687 1688void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount) 1689{ 1690 Frame* coreFrame = core(this); 1691 1692 const IntRect& pageRect = m_pageRects[page]; 1693 const IntRect& marginRect = printerMarginRect(printDC); 1694 1695 // In preview, the printDC is a placeholder, so just always use the HDC backing the graphics context. 1696 HDC hdc = hdcFromContext(pctx); 1697 1698 spoolCtx->save(); 1699 1700 XFORM original, scaled; 1701 GetWorldTransform(hdc, &original); 1702 1703 cairo_t* cr = pctx->cr(); 1704 bool preview = (hdc != printDC); 1705 if (preview) { 1706 // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo will 1707 // draw correctly. We need to retain the correct preview scale here for use when the Cairo 1708 // drawing completes so that we can scale our GDI-based header/footer calls. This is a 1709 // workaround for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161) 1710 scaled = buildXFORMFromCairo(hdc, cr); 1711 } 1712 1713 float scale = scaleFactor(printDC, marginRect, pageRect); 1714 1715 IntRect cairoMarginRect(marginRect); 1716 cairoMarginRect.scale(1 / scale); 1717 1718 // We cannot scale the display HDC because the print surface also scales fonts, 1719 // resulting in invalid printing (and print preview) 1720 cairo_scale(cr, scale, scale); 1721 cairo_translate(cr, cairoMarginRect.x(), cairoMarginRect.y() + headerHeight); 1722 1723 // Modify Cairo (only) to account for page position. 1724 cairo_translate(cr, -pageRect.x(), -pageRect.y()); 1725 coreFrame->view()->paintContents(spoolCtx, pageRect); 1726 cairo_translate(cr, pageRect.x(), pageRect.y()); 1727 1728 if (preview) { 1729 // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo would 1730 // draw correctly. We need to rescale the HDC to the correct preview scale so our GDI-based 1731 // header/footer calls will draw properly. This is a workaround for a bug in Cairo. 1732 // (see https://bugs.freedesktop.org/show_bug.cgi?id=28161) 1733 SetWorldTransform(hdc, &scaled); 1734 } 1735 1736 XFORM xform = TransformationMatrix().translate(marginRect.x(), marginRect.y()).scale(scale); 1737 ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); 1738 1739 if (headerHeight) 1740 drawHeader(pctx, ui, pageRect, headerHeight); 1741 1742 if (footerHeight) 1743 drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight); 1744 1745 SetWorldTransform(hdc, &original); 1746 1747 cairo_show_page(cr); 1748 ASSERT(!cairo_status(cr)); 1749 spoolCtx->restore(); 1750} 1751 1752static void setCairoTransformToPreviewHDC(cairo_t* previewCtx, HDC previewDC) 1753{ 1754 XFORM passedCTM; 1755 GetWorldTransform(previewDC, &passedCTM); 1756 1757 // Reset HDC WorldTransform to unscaled state. Scaling must be 1758 // done in Cairo to avoid drawing errors. 1759 XFORM unscaledCTM = passedCTM; 1760 unscaledCTM.eM11 = 1.0; 1761 unscaledCTM.eM22 = 1.0; 1762 1763 SetWorldTransform(previewDC, &unscaledCTM); 1764 1765 // Make the Cairo transform match the information passed to WebKit 1766 // in the HDC's WorldTransform. 1767 cairo_matrix_t ctm = { passedCTM.eM11, passedCTM.eM12, passedCTM.eM21, 1768 passedCTM.eM22, passedCTM.eDx, passedCTM.eDy }; 1769 1770 cairo_set_matrix(previewCtx, &ctm); 1771} 1772 1773#endif 1774 1775HRESULT STDMETHODCALLTYPE WebFrame::spoolPages( 1776 /* [in] */ HDC printDC, 1777 /* [in] */ UINT startPage, 1778 /* [in] */ UINT endPage, 1779 /* [retval][out] */ void* ctx) 1780{ 1781#if USE(CG) 1782 if (!printDC || !ctx) { 1783 ASSERT_NOT_REACHED(); 1784 return E_POINTER; 1785 } 1786#elif USE(CAIRO) 1787 if (!printDC) { 1788 ASSERT_NOT_REACHED(); 1789 return E_POINTER; 1790 } 1791 1792 HDC targetDC = (ctx) ? (HDC)ctx : printDC; 1793 1794 cairo_surface_t* printSurface = 0; 1795 if (ctx) 1796 printSurface = cairo_win32_surface_create(targetDC); // in-memory 1797 else 1798 printSurface = cairo_win32_printing_surface_create(targetDC); // metafile 1799 1800 cairo_t* cr = cairo_create(printSurface); 1801 if (!cr) { 1802 cairo_surface_destroy(printSurface); 1803 return E_FAIL; 1804 } 1805 1806 PlatformContextCairo platformContext(cr); 1807 PlatformGraphicsContext* pctx = &platformContext; 1808 cairo_destroy(cr); 1809 1810 if (ctx) { 1811 // If this is a preview, the Windows HDC was sent with scaling information. 1812 // Retrieve it and reset it so that it draws properly. This is a workaround 1813 // for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161) 1814 setCairoTransformToPreviewHDC(cr, targetDC); 1815 } 1816 1817 cairo_surface_set_fallback_resolution(printSurface, 72.0, 72.0); 1818#endif 1819 1820 if (!m_inPrintingMode) { 1821 ASSERT_NOT_REACHED(); 1822 return E_FAIL; 1823 } 1824 1825 Frame* coreFrame = core(this); 1826 if (!coreFrame || !coreFrame->document()) 1827 return E_FAIL; 1828 1829 UINT pageCount = (UINT) m_pageRects.size(); 1830#if USE(CG) 1831 PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx; 1832#endif 1833 1834 if (!pageCount || startPage > pageCount) { 1835 ASSERT_NOT_REACHED(); 1836 return E_FAIL; 1837 } 1838 1839 if (startPage > 0) 1840 startPage--; 1841 1842 if (endPage == 0) 1843 endPage = pageCount; 1844 1845 COMPtr<IWebUIDelegate> ui; 1846 if (FAILED(d->webView->uiDelegate(&ui))) 1847 return E_FAIL; 1848 1849 float headerHeight = 0, footerHeight = 0; 1850 headerAndFooterHeights(&headerHeight, &footerHeight); 1851 GraphicsContext spoolCtx(pctx); 1852 spoolCtx.setShouldIncludeChildWindows(true); 1853 1854 for (UINT ii = startPage; ii < endPage; ii++) 1855 spoolPage(pctx, &spoolCtx, printDC, ui.get(), headerHeight, footerHeight, ii, pageCount); 1856 1857#if USE(CAIRO) 1858 cairo_surface_finish(printSurface); 1859 ASSERT(!cairo_surface_status(printSurface)); 1860 cairo_surface_destroy(printSurface); 1861#endif 1862 1863 return S_OK; 1864} 1865 1866HRESULT STDMETHODCALLTYPE WebFrame::isFrameSet( 1867 /* [retval][out] */ BOOL* result) 1868{ 1869 *result = FALSE; 1870 1871 Frame* coreFrame = core(this); 1872 if (!coreFrame || !coreFrame->document()) 1873 return E_FAIL; 1874 1875 *result = coreFrame->document()->isFrameSet() ? TRUE : FALSE; 1876 return S_OK; 1877} 1878 1879HRESULT STDMETHODCALLTYPE WebFrame::string( 1880 /* [retval][out] */ BSTR *result) 1881{ 1882 *result = 0; 1883 1884 Frame* coreFrame = core(this); 1885 if (!coreFrame) 1886 return E_FAIL; 1887 1888 RefPtr<Range> allRange(rangeOfContents(*coreFrame->document())); 1889 String allString = plainText(allRange.get()); 1890 *result = BString(allString).release(); 1891 return S_OK; 1892} 1893 1894HRESULT STDMETHODCALLTYPE WebFrame::size( 1895 /* [retval][out] */ SIZE *size) 1896{ 1897 if (!size) 1898 return E_POINTER; 1899 size->cx = size->cy = 0; 1900 1901 Frame* coreFrame = core(this); 1902 if (!coreFrame) 1903 return E_FAIL; 1904 FrameView* view = coreFrame->view(); 1905 if (!view) 1906 return E_FAIL; 1907 size->cx = view->width(); 1908 size->cy = view->height(); 1909 return S_OK; 1910} 1911 1912HRESULT STDMETHODCALLTYPE WebFrame::hasScrollBars( 1913 /* [retval][out] */ BOOL *result) 1914{ 1915 if (!result) 1916 return E_POINTER; 1917 *result = FALSE; 1918 1919 Frame* coreFrame = core(this); 1920 if (!coreFrame) 1921 return E_FAIL; 1922 1923 FrameView* view = coreFrame->view(); 1924 if (!view) 1925 return E_FAIL; 1926 1927 if (view->horizontalScrollbar() || view->verticalScrollbar()) 1928 *result = TRUE; 1929 1930 return S_OK; 1931} 1932 1933HRESULT STDMETHODCALLTYPE WebFrame::contentBounds( 1934 /* [retval][out] */ RECT *result) 1935{ 1936 if (!result) 1937 return E_POINTER; 1938 ::SetRectEmpty(result); 1939 1940 Frame* coreFrame = core(this); 1941 if (!coreFrame) 1942 return E_FAIL; 1943 1944 FrameView* view = coreFrame->view(); 1945 if (!view) 1946 return E_FAIL; 1947 1948 result->bottom = view->contentsHeight(); 1949 result->right = view->contentsWidth(); 1950 return S_OK; 1951} 1952 1953HRESULT STDMETHODCALLTYPE WebFrame::frameBounds( 1954 /* [retval][out] */ RECT *result) 1955{ 1956 if (!result) 1957 return E_POINTER; 1958 ::SetRectEmpty(result); 1959 1960 Frame* coreFrame = core(this); 1961 if (!coreFrame) 1962 return E_FAIL; 1963 1964 FrameView* view = coreFrame->view(); 1965 if (!view) 1966 return E_FAIL; 1967 1968 FloatRect bounds = view->visibleContentRectIncludingScrollbars(); 1969 result->bottom = (LONG) bounds.height(); 1970 result->right = (LONG) bounds.width(); 1971 return S_OK; 1972} 1973 1974HRESULT STDMETHODCALLTYPE WebFrame::isDescendantOfFrame( 1975 /* [in] */ IWebFrame *ancestor, 1976 /* [retval][out] */ BOOL *result) 1977{ 1978 if (!result) 1979 return E_POINTER; 1980 *result = FALSE; 1981 1982 Frame* coreFrame = core(this); 1983 COMPtr<WebFrame> ancestorWebFrame(Query, ancestor); 1984 if (!ancestorWebFrame) 1985 return S_OK; 1986 1987 *result = (coreFrame && coreFrame->tree().isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE; 1988 return S_OK; 1989} 1990 1991HRESULT WebFrame::stringByEvaluatingJavaScriptInScriptWorld(IWebScriptWorld* iWorld, JSObjectRef globalObjectRef, BSTR script, BSTR* evaluationResult) 1992{ 1993 if (!evaluationResult) 1994 return E_POINTER; 1995 *evaluationResult = 0; 1996 1997 if (!iWorld) 1998 return E_POINTER; 1999 2000 COMPtr<WebScriptWorld> world(Query, iWorld); 2001 if (!world) 2002 return E_INVALIDARG; 2003 2004 Frame* coreFrame = core(this); 2005 String string = String(script, SysStringLen(script)); 2006 2007 // Start off with some guess at a frame and a global object, we'll try to do better...! 2008 JSDOMWindow* anyWorldGlobalObject = coreFrame->script().globalObject(mainThreadNormalWorld()); 2009 2010 // The global object is probably a shell object? - if so, we know how to use this! 2011 JSC::JSObject* globalObjectObj = toJS(globalObjectRef); 2012 if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell")) 2013 anyWorldGlobalObject = static_cast<JSDOMWindowShell*>(globalObjectObj)->window(); 2014 2015 // Get the frame frome the global object we've settled on. 2016 Frame* frame = anyWorldGlobalObject->impl().frame(); 2017 ASSERT(frame->document()); 2018 JSValue result = frame->script().executeScriptInWorld(world->world(), string, true).jsValue(); 2019 2020 if (!frame) // In case the script removed our frame from the page. 2021 return S_OK; 2022 2023 // This bizarre set of rules matches behavior from WebKit for Safari 2.0. 2024 // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 2025 // JSEvaluateScript instead, since they have less surprising semantics. 2026 if (!result || !result.isBoolean() && !result.isString() && !result.isNumber()) 2027 return S_OK; 2028 2029 JSC::ExecState* exec = anyWorldGlobalObject->globalExec(); 2030 JSC::JSLockHolder lock(exec); 2031 String resultString = result.toWTFString(exec); 2032 *evaluationResult = BString(resultString).release(); 2033 2034 return S_OK; 2035} 2036 2037void WebFrame::unmarkAllMisspellings() 2038{ 2039 Frame* coreFrame = core(this); 2040 for (Frame* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) { 2041 Document *doc = frame->document(); 2042 if (!doc) 2043 return; 2044 2045 doc->markers().removeMarkers(DocumentMarker::Spelling); 2046 } 2047} 2048 2049void WebFrame::unmarkAllBadGrammar() 2050{ 2051 Frame* coreFrame = core(this); 2052 for (Frame* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) { 2053 Document *doc = frame->document(); 2054 if (!doc) 2055 return; 2056 2057 doc->markers().removeMarkers(DocumentMarker::Grammar); 2058 } 2059} 2060 2061WebView* WebFrame::webView() const 2062{ 2063 return d->webView; 2064} 2065 2066void WebFrame::setWebView(WebView* webView) 2067{ 2068 d->webView = webView; 2069} 2070 2071COMPtr<IAccessible> WebFrame::accessible() const 2072{ 2073 Frame* coreFrame = core(this); 2074 ASSERT(coreFrame); 2075 2076 Document* currentDocument = coreFrame->document(); 2077 if (!currentDocument) 2078 m_accessible = 0; 2079 else if (!m_accessible || m_accessible->document() != currentDocument) { 2080 // Either we've never had a wrapper for this frame's top-level Document, 2081 // the Document renderer was destroyed and its wrapper was detached, or 2082 // the previous Document is in the page cache, and the current document 2083 // needs to be wrapped. 2084 m_accessible = new AccessibleDocument(currentDocument, webView()->viewWindow()); 2085 } 2086 return m_accessible.get(); 2087} 2088 2089void WebFrame::updateBackground() 2090{ 2091 Color backgroundColor = webView()->transparent() ? Color::transparent : Color::white; 2092 Frame* coreFrame = core(this); 2093 2094 if (!coreFrame || !coreFrame->view()) 2095 return; 2096 2097 coreFrame->view()->updateBackgroundRecursively(backgroundColor, webView()->transparent()); 2098} 2099 2100