1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 // How ownership works 32 // ------------------- 33 // 34 // Big oh represents a refcounted relationship: owner O--- ownee 35 // 36 // WebView (for the toplevel frame only) 37 // O 38 // | WebFrame 39 // | O 40 // | | 41 // Page O------- LocalFrame (m_mainFrame) O-------O FrameView 42 // || 43 // || 44 // FrameLoader 45 // 46 // FrameLoader and LocalFrame are formerly one object that was split apart because 47 // it got too big. They basically have the same lifetime, hence the double line. 48 // 49 // From the perspective of the embedder, WebFrame is simply an object that it 50 // allocates by calling WebFrame::create() and must be freed by calling close(). 51 // Internally, WebFrame is actually refcounted and it holds a reference to its 52 // corresponding LocalFrame in blink. 53 // 54 // Oilpan: the middle objects + Page in the above diagram are Oilpan heap allocated, 55 // WebView and FrameView are currently not. In terms of ownership and control, the 56 // relationships stays the same, but the references from the off-heap WebView to the 57 // on-heap Page is handled by a Persistent<>, not a RefPtr<>. Similarly, the mutual 58 // strong references between the on-heap LocalFrame and the off-heap FrameView 59 // is through a RefPtr (from LocalFrame to FrameView), and a Persistent refers 60 // to the LocalFrame in the other direction. 61 // 62 // From the embedder's point of view, the use of Oilpan brings no changes. close() 63 // must still be used to signal that the embedder is through with the WebFrame. 64 // Calling it will bring about the release and finalization of the frame object, 65 // and everything underneath. 66 // 67 // How frames are destroyed 68 // ------------------------ 69 // 70 // The main frame is never destroyed and is re-used. The FrameLoader is re-used 71 // and a reference to the main frame is kept by the Page. 72 // 73 // When frame content is replaced, all subframes are destroyed. This happens 74 // in FrameLoader::detachFromParent for each subframe in a pre-order depth-first 75 // traversal. Note that child node order may not match DOM node order! 76 // detachFromParent() calls FrameLoaderClient::detachedFromParent(), which calls 77 // WebFrame::frameDetached(). This triggers WebFrame to clear its reference to 78 // LocalFrame, and also notifies the embedder via WebFrameClient that the frame is 79 // detached. Most embedders will invoke close() on the WebFrame at this point, 80 // triggering its deletion unless something else is still retaining a reference. 81 // 82 // The client is expected to be set whenever the WebLocalFrameImpl is attached to 83 // the DOM. 84 85 #include "config.h" 86 #include "web/WebLocalFrameImpl.h" 87 88 #include "bindings/core/v8/DOMWrapperWorld.h" 89 #include "bindings/core/v8/ExceptionState.h" 90 #include "bindings/core/v8/ExceptionStatePlaceholder.h" 91 #include "bindings/core/v8/ScriptController.h" 92 #include "bindings/core/v8/ScriptSourceCode.h" 93 #include "bindings/core/v8/ScriptValue.h" 94 #include "bindings/core/v8/V8Binding.h" 95 #include "bindings/core/v8/V8GCController.h" 96 #include "bindings/core/v8/V8PerIsolateData.h" 97 #include "core/HTMLNames.h" 98 #include "core/dom/Document.h" 99 #include "core/dom/IconURL.h" 100 #include "core/dom/MessagePort.h" 101 #include "core/dom/Node.h" 102 #include "core/dom/NodeTraversal.h" 103 #include "core/dom/shadow/ShadowRoot.h" 104 #include "core/editing/Editor.h" 105 #include "core/editing/FrameSelection.h" 106 #include "core/editing/InputMethodController.h" 107 #include "core/editing/PlainTextRange.h" 108 #include "core/editing/SpellChecker.h" 109 #include "core/editing/TextAffinity.h" 110 #include "core/editing/TextIterator.h" 111 #include "core/editing/htmlediting.h" 112 #include "core/editing/markup.h" 113 #include "core/fetch/ResourceFetcher.h" 114 #include "core/frame/Console.h" 115 #include "core/frame/LocalDOMWindow.h" 116 #include "core/frame/FrameHost.h" 117 #include "core/frame/FrameView.h" 118 #include "core/frame/Settings.h" 119 #include "core/html/HTMLAnchorElement.h" 120 #include "core/html/HTMLCollection.h" 121 #include "core/html/HTMLFormElement.h" 122 #include "core/html/HTMLFrameElementBase.h" 123 #include "core/html/HTMLFrameOwnerElement.h" 124 #include "core/html/HTMLHeadElement.h" 125 #include "core/html/HTMLInputElement.h" 126 #include "core/html/HTMLLinkElement.h" 127 #include "core/html/PluginDocument.h" 128 #include "core/inspector/ConsoleMessage.h" 129 #include "core/inspector/InspectorController.h" 130 #include "core/inspector/ScriptCallStack.h" 131 #include "core/loader/DocumentLoader.h" 132 #include "core/loader/FrameLoadRequest.h" 133 #include "core/loader/FrameLoader.h" 134 #include "core/loader/HistoryItem.h" 135 #include "core/loader/SubstituteData.h" 136 #include "core/page/Chrome.h" 137 #include "core/page/EventHandler.h" 138 #include "core/page/FocusController.h" 139 #include "core/page/FrameTree.h" 140 #include "core/page/Page.h" 141 #include "core/page/PrintContext.h" 142 #include "core/rendering/HitTestResult.h" 143 #include "core/rendering/RenderBox.h" 144 #include "core/rendering/RenderFrame.h" 145 #include "core/rendering/RenderLayer.h" 146 #include "core/rendering/RenderObject.h" 147 #include "core/rendering/RenderTreeAsText.h" 148 #include "core/rendering/RenderView.h" 149 #include "core/rendering/style/StyleInheritedData.h" 150 #include "core/timing/Performance.h" 151 #include "modules/geolocation/GeolocationController.h" 152 #include "modules/notifications/NotificationController.h" 153 #include "modules/notifications/NotificationPermissionClient.h" 154 #include "modules/screen_orientation/ScreenOrientationController.h" 155 #include "platform/TraceEvent.h" 156 #include "platform/UserGestureIndicator.h" 157 #include "platform/clipboard/ClipboardUtilities.h" 158 #include "platform/fonts/FontCache.h" 159 #include "platform/graphics/GraphicsContext.h" 160 #include "platform/graphics/GraphicsLayerClient.h" 161 #include "platform/graphics/skia/SkiaUtils.h" 162 #include "platform/heap/Handle.h" 163 #include "platform/network/ResourceRequest.h" 164 #include "platform/scroll/ScrollTypes.h" 165 #include "platform/scroll/ScrollbarTheme.h" 166 #include "platform/weborigin/KURL.h" 167 #include "platform/weborigin/SchemeRegistry.h" 168 #include "platform/weborigin/SecurityPolicy.h" 169 #include "public/platform/Platform.h" 170 #include "public/platform/WebFloatPoint.h" 171 #include "public/platform/WebFloatRect.h" 172 #include "public/platform/WebLayer.h" 173 #include "public/platform/WebPoint.h" 174 #include "public/platform/WebRect.h" 175 #include "public/platform/WebSize.h" 176 #include "public/platform/WebURLError.h" 177 #include "public/platform/WebVector.h" 178 #include "public/web/WebConsoleMessage.h" 179 #include "public/web/WebDOMEvent.h" 180 #include "public/web/WebDocument.h" 181 #include "public/web/WebFindOptions.h" 182 #include "public/web/WebFormElement.h" 183 #include "public/web/WebFrameClient.h" 184 #include "public/web/WebHistoryItem.h" 185 #include "public/web/WebIconURL.h" 186 #include "public/web/WebInputElement.h" 187 #include "public/web/WebNode.h" 188 #include "public/web/WebPerformance.h" 189 #include "public/web/WebPlugin.h" 190 #include "public/web/WebPrintParams.h" 191 #include "public/web/WebRange.h" 192 #include "public/web/WebScriptSource.h" 193 #include "public/web/WebSecurityOrigin.h" 194 #include "public/web/WebSerializedScriptValue.h" 195 #include "web/AssociatedURLLoader.h" 196 #include "web/CompositionUnderlineVectorBuilder.h" 197 #include "web/FindInPageCoordinates.h" 198 #include "web/GeolocationClientProxy.h" 199 #include "web/LocalFileSystemClient.h" 200 #include "web/MIDIClientProxy.h" 201 #include "web/NotificationPermissionClientImpl.h" 202 #include "web/PageOverlay.h" 203 #include "web/SharedWorkerRepositoryClientImpl.h" 204 #include "web/TextFinder.h" 205 #include "web/WebDataSourceImpl.h" 206 #include "web/WebDevToolsAgentPrivate.h" 207 #include "web/WebPluginContainerImpl.h" 208 #include "web/WebViewImpl.h" 209 #include "wtf/CurrentTime.h" 210 #include "wtf/HashMap.h" 211 #include <algorithm> 212 213 namespace blink { 214 215 static int frameCount = 0; 216 217 // Key for a StatsCounter tracking how many WebFrames are active. 218 static const char webFrameActiveCount[] = "WebFrameActiveCount"; 219 220 static void frameContentAsPlainText(size_t maxChars, LocalFrame* frame, StringBuilder& output) 221 { 222 Document* document = frame->document(); 223 if (!document) 224 return; 225 226 if (!frame->view()) 227 return; 228 229 // Select the document body. 230 RefPtrWillBeRawPtr<Range> range(document->createRange()); 231 TrackExceptionState exceptionState; 232 range->selectNodeContents(document->body(), exceptionState); 233 234 if (!exceptionState.hadException()) { 235 // The text iterator will walk nodes giving us text. This is similar to 236 // the plainText() function in core/editing/TextIterator.h, but we implement the maximum 237 // size and also copy the results directly into a wstring, avoiding the 238 // string conversion. 239 for (TextIterator it(range.get()); !it.atEnd(); it.advance()) { 240 it.appendTextToStringBuilder(output, 0, maxChars - output.length()); 241 if (output.length() >= maxChars) 242 return; // Filled up the buffer. 243 } 244 } 245 246 // The separator between frames when the frames are converted to plain text. 247 const LChar frameSeparator[] = { '\n', '\n' }; 248 const size_t frameSeparatorLength = WTF_ARRAY_LENGTH(frameSeparator); 249 250 // Recursively walk the children. 251 const FrameTree& frameTree = frame->tree(); 252 for (Frame* curChild = frameTree.firstChild(); curChild; curChild = curChild->tree().nextSibling()) { 253 if (!curChild->isLocalFrame()) 254 continue; 255 LocalFrame* curLocalChild = toLocalFrame(curChild); 256 // Ignore the text of non-visible frames. 257 RenderView* contentRenderer = curLocalChild->contentRenderer(); 258 RenderPart* ownerRenderer = curLocalChild->ownerRenderer(); 259 if (!contentRenderer || !contentRenderer->width() || !contentRenderer->height() 260 || (contentRenderer->x() + contentRenderer->width() <= 0) || (contentRenderer->y() + contentRenderer->height() <= 0) 261 || (ownerRenderer && ownerRenderer->style() && ownerRenderer->style()->visibility() != VISIBLE)) { 262 continue; 263 } 264 265 // Make sure the frame separator won't fill up the buffer, and give up if 266 // it will. The danger is if the separator will make the buffer longer than 267 // maxChars. This will cause the computation above: 268 // maxChars - output->size() 269 // to be a negative number which will crash when the subframe is added. 270 if (output.length() >= maxChars - frameSeparatorLength) 271 return; 272 273 output.append(frameSeparator, frameSeparatorLength); 274 frameContentAsPlainText(maxChars, curLocalChild, output); 275 if (output.length() >= maxChars) 276 return; // Filled up the buffer. 277 } 278 } 279 280 WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromFrame(LocalFrame* frame) 281 { 282 if (!frame) 283 return 0; 284 if (!frame->document() || !frame->document()->isPluginDocument()) 285 return 0; 286 PluginDocument* pluginDocument = toPluginDocument(frame->document()); 287 return toWebPluginContainerImpl(pluginDocument->pluginWidget()); 288 } 289 290 WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromNode(LocalFrame* frame, const WebNode& node) 291 { 292 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame); 293 if (pluginContainer) 294 return pluginContainer; 295 return toWebPluginContainerImpl(node.pluginContainer()); 296 } 297 298 // Simple class to override some of PrintContext behavior. Some of the methods 299 // made virtual so that they can be overridden by ChromePluginPrintContext. 300 class ChromePrintContext : public PrintContext { 301 WTF_MAKE_NONCOPYABLE(ChromePrintContext); 302 public: 303 ChromePrintContext(LocalFrame* frame) 304 : PrintContext(frame) 305 , m_printedPageWidth(0) 306 { 307 } 308 309 virtual ~ChromePrintContext() { } 310 311 virtual void begin(float width, float height) 312 { 313 ASSERT(!m_printedPageWidth); 314 m_printedPageWidth = width; 315 PrintContext::begin(m_printedPageWidth, height); 316 } 317 318 virtual float getPageShrink(int pageNumber) const 319 { 320 IntRect pageRect = m_pageRects[pageNumber]; 321 return m_printedPageWidth / pageRect.width(); 322 } 323 324 float spoolSinglePage(GraphicsContext& graphicsContext, int pageNumber) 325 { 326 // FIXME: Why is it ok to proceed without all the null checks that 327 // spoolAllPagesWithBoundaries does? 328 frame()->view()->updateLayoutAndStyleForPainting(); 329 return spoolPage(graphicsContext, pageNumber); 330 } 331 332 void spoolAllPagesWithBoundaries(GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels) 333 { 334 if (!frame()->document() || !frame()->view() || !frame()->document()->renderView()) 335 return; 336 337 frame()->view()->updateLayoutAndStyleForPainting(); 338 339 float pageHeight; 340 computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, pageHeight); 341 342 const float pageWidth = pageSizeInPixels.width(); 343 size_t numPages = pageRects().size(); 344 int totalHeight = numPages * (pageSizeInPixels.height() + 1) - 1; 345 346 // Fill the whole background by white. 347 graphicsContext.setFillColor(Color::white); 348 graphicsContext.fillRect(FloatRect(0, 0, pageWidth, totalHeight)); 349 350 int currentHeight = 0; 351 for (size_t pageIndex = 0; pageIndex < numPages; pageIndex++) { 352 // Draw a line for a page boundary if this isn't the first page. 353 if (pageIndex > 0) { 354 graphicsContext.save(); 355 graphicsContext.setStrokeColor(Color(0, 0, 255)); 356 graphicsContext.setFillColor(Color(0, 0, 255)); 357 graphicsContext.drawLine(IntPoint(0, currentHeight), IntPoint(pageWidth, currentHeight)); 358 graphicsContext.restore(); 359 } 360 361 graphicsContext.save(); 362 363 graphicsContext.translate(0, currentHeight); 364 #if OS(WIN) || OS(MACOSX) 365 // Account for the disabling of scaling in spoolPage. In the context 366 // of spoolAllPagesWithBoundaries the scale HAS NOT been pre-applied. 367 float scale = getPageShrink(pageIndex); 368 graphicsContext.scale(scale, scale); 369 #endif 370 spoolPage(graphicsContext, pageIndex); 371 graphicsContext.restore(); 372 373 currentHeight += pageSizeInPixels.height() + 1; 374 } 375 } 376 377 protected: 378 // Spools the printed page, a subrect of frame(). Skip the scale step. 379 // NativeTheme doesn't play well with scaling. Scaling is done browser side 380 // instead. Returns the scale to be applied. 381 // On Linux, we don't have the problem with NativeTheme, hence we let WebKit 382 // do the scaling and ignore the return value. 383 virtual float spoolPage(GraphicsContext& context, int pageNumber) 384 { 385 IntRect pageRect = m_pageRects[pageNumber]; 386 float scale = m_printedPageWidth / pageRect.width(); 387 388 context.save(); 389 #if OS(POSIX) && !OS(MACOSX) 390 context.scale(scale, scale); 391 #endif 392 context.translate(static_cast<float>(-pageRect.x()), static_cast<float>(-pageRect.y())); 393 context.clip(pageRect); 394 frame()->view()->paintContents(&context, pageRect); 395 outputLinkAndLinkedDestinations(context, frame()->document(), pageRect); 396 context.restore(); 397 return scale; 398 } 399 400 private: 401 // Set when printing. 402 float m_printedPageWidth; 403 }; 404 405 // Simple class to override some of PrintContext behavior. This is used when 406 // the frame hosts a plugin that supports custom printing. In this case, we 407 // want to delegate all printing related calls to the plugin. 408 class ChromePluginPrintContext FINAL : public ChromePrintContext { 409 public: 410 ChromePluginPrintContext(LocalFrame* frame, WebPluginContainerImpl* plugin, const WebPrintParams& printParams) 411 : ChromePrintContext(frame), m_plugin(plugin), m_printParams(printParams) 412 { 413 } 414 415 virtual ~ChromePluginPrintContext() { } 416 417 virtual void begin(float width, float height) OVERRIDE 418 { 419 } 420 421 virtual void end() OVERRIDE 422 { 423 m_plugin->printEnd(); 424 } 425 426 virtual float getPageShrink(int pageNumber) const OVERRIDE 427 { 428 // We don't shrink the page (maybe we should ask the widget ??) 429 return 1.0; 430 } 431 432 virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) OVERRIDE 433 { 434 m_printParams.printContentArea = IntRect(printRect); 435 m_pageRects.fill(IntRect(printRect), m_plugin->printBegin(m_printParams)); 436 } 437 438 virtual void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling) OVERRIDE 439 { 440 ASSERT_NOT_REACHED(); 441 } 442 443 protected: 444 // Spools the printed page, a subrect of frame(). Skip the scale step. 445 // NativeTheme doesn't play well with scaling. Scaling is done browser side 446 // instead. Returns the scale to be applied. 447 virtual float spoolPage(GraphicsContext& context, int pageNumber) OVERRIDE 448 { 449 m_plugin->printPage(pageNumber, &context); 450 return 1.0; 451 } 452 453 private: 454 // Set when printing. 455 WebPluginContainerImpl* m_plugin; 456 WebPrintParams m_printParams; 457 }; 458 459 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) 460 { 461 return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0; 462 } 463 464 // WebFrame ------------------------------------------------------------------- 465 466 int WebFrame::instanceCount() 467 { 468 return frameCount; 469 } 470 471 WebLocalFrame* WebLocalFrame::frameForCurrentContext() 472 { 473 v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentContext(); 474 if (context.IsEmpty()) 475 return 0; 476 return frameForContext(context); 477 } 478 479 WebLocalFrame* WebLocalFrame::frameForContext(v8::Handle<v8::Context> context) 480 { 481 return WebLocalFrameImpl::fromFrame(toFrameIfNotDetached(context)); 482 } 483 484 WebLocalFrame* WebLocalFrame::fromFrameOwnerElement(const WebElement& element) 485 { 486 return WebLocalFrameImpl::fromFrameOwnerElement(PassRefPtrWillBeRawPtr<Element>(element).get()); 487 } 488 489 bool WebLocalFrameImpl::isWebLocalFrame() const 490 { 491 return true; 492 } 493 494 WebLocalFrame* WebLocalFrameImpl::toWebLocalFrame() 495 { 496 return this; 497 } 498 499 bool WebLocalFrameImpl::isWebRemoteFrame() const 500 { 501 return false; 502 } 503 504 WebRemoteFrame* WebLocalFrameImpl::toWebRemoteFrame() 505 { 506 ASSERT_NOT_REACHED(); 507 return 0; 508 } 509 510 void WebLocalFrameImpl::close() 511 { 512 m_client = 0; 513 514 #if ENABLE(OILPAN) 515 m_selfKeepAlive.clear(); 516 #else 517 deref(); // Balances ref() acquired in WebFrame::create 518 #endif 519 } 520 521 WebString WebLocalFrameImpl::uniqueName() const 522 { 523 return frame()->tree().uniqueName(); 524 } 525 526 WebString WebLocalFrameImpl::assignedName() const 527 { 528 return frame()->tree().name(); 529 } 530 531 void WebLocalFrameImpl::setName(const WebString& name) 532 { 533 frame()->tree().setName(name); 534 } 535 536 WebVector<WebIconURL> WebLocalFrameImpl::iconURLs(int iconTypesMask) const 537 { 538 // The URL to the icon may be in the header. As such, only 539 // ask the loader for the icon if it's finished loading. 540 if (frame()->loader().state() == FrameStateComplete) 541 return frame()->document()->iconURLs(iconTypesMask); 542 return WebVector<WebIconURL>(); 543 } 544 545 void WebLocalFrameImpl::setIsRemote(bool isRemote) 546 { 547 m_isRemote = isRemote; 548 if (isRemote) 549 client()->initializeChildFrame(frame()->view()->frameRect(), frame()->view()->visibleContentScaleFactor()); 550 } 551 552 void WebLocalFrameImpl::setRemoteWebLayer(WebLayer* webLayer) 553 { 554 if (!frame()) 555 return; 556 557 frame()->setRemotePlatformLayer(webLayer); 558 } 559 560 void WebLocalFrameImpl::setPermissionClient(WebPermissionClient* permissionClient) 561 { 562 m_permissionClient = permissionClient; 563 } 564 565 void WebLocalFrameImpl::setSharedWorkerRepositoryClient(WebSharedWorkerRepositoryClient* client) 566 { 567 m_sharedWorkerRepositoryClient = SharedWorkerRepositoryClientImpl::create(client); 568 } 569 570 WebSize WebLocalFrameImpl::scrollOffset() const 571 { 572 FrameView* view = frameView(); 573 if (!view) 574 return WebSize(); 575 return view->scrollOffset(); 576 } 577 578 WebSize WebLocalFrameImpl::minimumScrollOffset() const 579 { 580 FrameView* view = frameView(); 581 if (!view) 582 return WebSize(); 583 return toIntSize(view->minimumScrollPosition()); 584 } 585 586 WebSize WebLocalFrameImpl::maximumScrollOffset() const 587 { 588 FrameView* view = frameView(); 589 if (!view) 590 return WebSize(); 591 return toIntSize(view->maximumScrollPosition()); 592 } 593 594 void WebLocalFrameImpl::setScrollOffset(const WebSize& offset) 595 { 596 if (FrameView* view = frameView()) 597 view->setScrollOffset(IntPoint(offset.width, offset.height)); 598 } 599 600 WebSize WebLocalFrameImpl::contentsSize() const 601 { 602 if (FrameView* view = frameView()) 603 return view->contentsSize(); 604 return WebSize(); 605 } 606 607 bool WebLocalFrameImpl::hasVisibleContent() const 608 { 609 if (RenderPart* renderer = frame()->ownerRenderer()) { 610 if (renderer->style()->visibility() != VISIBLE) 611 return false; 612 } 613 614 if (FrameView* view = frameView()) 615 return view->visibleWidth() > 0 && view->visibleHeight() > 0; 616 return false; 617 } 618 619 WebRect WebLocalFrameImpl::visibleContentRect() const 620 { 621 if (FrameView* view = frameView()) 622 return view->visibleContentRect(); 623 return WebRect(); 624 } 625 626 bool WebLocalFrameImpl::hasHorizontalScrollbar() const 627 { 628 return frame() && frame()->view() && frame()->view()->horizontalScrollbar(); 629 } 630 631 bool WebLocalFrameImpl::hasVerticalScrollbar() const 632 { 633 return frame() && frame()->view() && frame()->view()->verticalScrollbar(); 634 } 635 636 WebView* WebLocalFrameImpl::view() const 637 { 638 return viewImpl(); 639 } 640 641 void WebLocalFrameImpl::setOpener(WebFrame* opener) 642 { 643 // FIXME: Does this need to move up into WebFrame too? 644 if (WebFrame::opener() && !opener && m_client) 645 m_client->didDisownOpener(this); 646 647 WebFrame::setOpener(opener); 648 649 ASSERT(m_frame); 650 if (m_frame && m_frame->document()) 651 m_frame->document()->initSecurityContext(); 652 } 653 654 WebDocument WebLocalFrameImpl::document() const 655 { 656 if (!frame() || !frame()->document()) 657 return WebDocument(); 658 return WebDocument(frame()->document()); 659 } 660 661 WebPerformance WebLocalFrameImpl::performance() const 662 { 663 if (!frame()) 664 return WebPerformance(); 665 return WebPerformance(&frame()->domWindow()->performance()); 666 } 667 668 bool WebLocalFrameImpl::dispatchBeforeUnloadEvent() 669 { 670 if (!frame()) 671 return true; 672 return frame()->loader().shouldClose(); 673 } 674 675 void WebLocalFrameImpl::dispatchUnloadEvent() 676 { 677 if (!frame()) 678 return; 679 frame()->loader().closeURL(); 680 } 681 682 NPObject* WebLocalFrameImpl::windowObject() const 683 { 684 if (!frame()) 685 return 0; 686 return frame()->script().windowScriptNPObject(); 687 } 688 689 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object) 690 { 691 bindToWindowObject(name, object, 0); 692 } 693 694 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object, void*) 695 { 696 if (!frame() || !frame()->script().canExecuteScripts(NotAboutToExecuteScript)) 697 return; 698 frame()->script().bindToWindowObject(frame(), String(name), object); 699 } 700 701 void WebLocalFrameImpl::executeScript(const WebScriptSource& source) 702 { 703 ASSERT(frame()); 704 TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first()); 705 v8::HandleScope handleScope(toIsolate(frame())); 706 frame()->script().executeScriptInMainWorld(ScriptSourceCode(source.code, source.url, position)); 707 } 708 709 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup) 710 { 711 ASSERT(frame()); 712 RELEASE_ASSERT(worldID > 0); 713 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit); 714 715 Vector<ScriptSourceCode> sources; 716 for (unsigned i = 0; i < numSources; ++i) { 717 TextPosition position(OrdinalNumber::fromOneBasedInt(sourcesIn[i].startLine), OrdinalNumber::first()); 718 sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position)); 719 } 720 721 v8::HandleScope handleScope(toIsolate(frame())); 722 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0); 723 } 724 725 void WebLocalFrameImpl::setIsolatedWorldSecurityOrigin(int worldID, const WebSecurityOrigin& securityOrigin) 726 { 727 ASSERT(frame()); 728 DOMWrapperWorld::setIsolatedWorldSecurityOrigin(worldID, securityOrigin.get()); 729 } 730 731 void WebLocalFrameImpl::setIsolatedWorldContentSecurityPolicy(int worldID, const WebString& policy) 732 { 733 ASSERT(frame()); 734 DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(worldID, policy); 735 } 736 737 void WebLocalFrameImpl::setIsolatedWorldHumanReadableName(int worldID, const WebString& humanReadableName) 738 { 739 ASSERT(frame()); 740 DOMWrapperWorld::setIsolatedWorldHumanReadableName(worldID, humanReadableName); 741 } 742 743 void WebLocalFrameImpl::addMessageToConsole(const WebConsoleMessage& message) 744 { 745 ASSERT(frame()); 746 747 MessageLevel webCoreMessageLevel; 748 switch (message.level) { 749 case WebConsoleMessage::LevelDebug: 750 webCoreMessageLevel = DebugMessageLevel; 751 break; 752 case WebConsoleMessage::LevelLog: 753 webCoreMessageLevel = LogMessageLevel; 754 break; 755 case WebConsoleMessage::LevelWarning: 756 webCoreMessageLevel = WarningMessageLevel; 757 break; 758 case WebConsoleMessage::LevelError: 759 webCoreMessageLevel = ErrorMessageLevel; 760 break; 761 default: 762 ASSERT_NOT_REACHED(); 763 return; 764 } 765 766 frame()->document()->addConsoleMessage(ConsoleMessage::create(OtherMessageSource, webCoreMessageLevel, message.text)); 767 } 768 769 void WebLocalFrameImpl::collectGarbage() 770 { 771 if (!frame()) 772 return; 773 if (!frame()->settings()->scriptEnabled()) 774 return; 775 V8GCController::collectGarbage(v8::Isolate::GetCurrent()); 776 } 777 778 bool WebLocalFrameImpl::checkIfRunInsecureContent(const WebURL& url) const 779 { 780 ASSERT(frame()); 781 return frame()->loader().mixedContentChecker()->canFrameInsecureContent(frame()->document()->securityOrigin(), url); 782 } 783 784 v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValue(const WebScriptSource& source) 785 { 786 ASSERT(frame()); 787 788 TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first()); 789 return frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source.code, source.url, position)); 790 } 791 792 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, WebVector<v8::Local<v8::Value> >* results) 793 { 794 ASSERT(frame()); 795 RELEASE_ASSERT(worldID > 0); 796 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit); 797 798 Vector<ScriptSourceCode> sources; 799 800 for (unsigned i = 0; i < numSources; ++i) { 801 TextPosition position(OrdinalNumber::fromOneBasedInt(sourcesIn[i].startLine), OrdinalNumber::first()); 802 sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position)); 803 } 804 805 if (results) { 806 Vector<v8::Local<v8::Value> > scriptResults; 807 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, &scriptResults); 808 WebVector<v8::Local<v8::Value> > v8Results(scriptResults.size()); 809 for (unsigned i = 0; i < scriptResults.size(); i++) 810 v8Results[i] = v8::Local<v8::Value>::New(toIsolate(frame()), scriptResults[i]); 811 results->swap(v8Results); 812 } else { 813 v8::HandleScope handleScope(toIsolate(frame())); 814 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0); 815 } 816 } 817 818 v8::Handle<v8::Value> WebLocalFrameImpl::callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> argv[]) 819 { 820 ASSERT(frame()); 821 return frame()->script().callFunction(function, receiver, argc, argv); 822 } 823 824 v8::Local<v8::Context> WebLocalFrameImpl::mainWorldScriptContext() const 825 { 826 return toV8Context(frame(), DOMWrapperWorld::mainWorld()); 827 } 828 829 void WebLocalFrameImpl::reload(bool ignoreCache) 830 { 831 ASSERT(frame()); 832 frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload); 833 } 834 835 void WebLocalFrameImpl::reloadWithOverrideURL(const WebURL& overrideUrl, bool ignoreCache) 836 { 837 ASSERT(frame()); 838 frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload, overrideUrl); 839 } 840 841 void WebLocalFrameImpl::loadRequest(const WebURLRequest& request) 842 { 843 ASSERT(frame()); 844 ASSERT(!request.isNull()); 845 const ResourceRequest& resourceRequest = request.toResourceRequest(); 846 847 if (resourceRequest.url().protocolIs("javascript")) { 848 loadJavaScriptURL(resourceRequest.url()); 849 return; 850 } 851 852 frame()->loader().load(FrameLoadRequest(0, resourceRequest)); 853 } 854 855 void WebLocalFrameImpl::loadHistoryItem(const WebHistoryItem& item, WebHistoryLoadType loadType, WebURLRequest::CachePolicy cachePolicy) 856 { 857 ASSERT(frame()); 858 RefPtr<HistoryItem> historyItem = PassRefPtr<HistoryItem>(item); 859 ASSERT(historyItem); 860 frame()->loader().loadHistoryItem(historyItem.get(), static_cast<HistoryLoadType>(loadType), static_cast<ResourceRequestCachePolicy>(cachePolicy)); 861 } 862 863 void WebLocalFrameImpl::loadData(const WebData& data, const WebString& mimeType, const WebString& textEncoding, const WebURL& baseURL, const WebURL& unreachableURL, bool replace) 864 { 865 ASSERT(frame()); 866 867 // If we are loading substitute data to replace an existing load, then 868 // inherit all of the properties of that original request. This way, 869 // reload will re-attempt the original request. It is essential that 870 // we only do this when there is an unreachableURL since a non-empty 871 // unreachableURL informs FrameLoader::reload to load unreachableURL 872 // instead of the currently loaded URL. 873 ResourceRequest request; 874 if (replace && !unreachableURL.isEmpty() && frame()->loader().provisionalDocumentLoader()) 875 request = frame()->loader().provisionalDocumentLoader()->originalRequest(); 876 request.setURL(baseURL); 877 878 FrameLoadRequest frameRequest(0, request, SubstituteData(data, mimeType, textEncoding, unreachableURL)); 879 ASSERT(frameRequest.substituteData().isValid()); 880 frameRequest.setLockBackForwardList(replace); 881 frame()->loader().load(frameRequest); 882 } 883 884 void WebLocalFrameImpl::loadHTMLString(const WebData& data, const WebURL& baseURL, const WebURL& unreachableURL, bool replace) 885 { 886 ASSERT(frame()); 887 loadData(data, WebString::fromUTF8("text/html"), WebString::fromUTF8("UTF-8"), baseURL, unreachableURL, replace); 888 } 889 890 void WebLocalFrameImpl::stopLoading() 891 { 892 if (!frame()) 893 return; 894 // FIXME: Figure out what we should really do here. It seems like a bug 895 // that FrameLoader::stopLoading doesn't call stopAllLoaders. 896 frame()->loader().stopAllLoaders(); 897 } 898 899 WebDataSource* WebLocalFrameImpl::provisionalDataSource() const 900 { 901 ASSERT(frame()); 902 903 // We regard the policy document loader as still provisional. 904 DocumentLoader* documentLoader = frame()->loader().provisionalDocumentLoader(); 905 if (!documentLoader) 906 documentLoader = frame()->loader().policyDocumentLoader(); 907 908 return DataSourceForDocLoader(documentLoader); 909 } 910 911 WebDataSource* WebLocalFrameImpl::dataSource() const 912 { 913 ASSERT(frame()); 914 return DataSourceForDocLoader(frame()->loader().documentLoader()); 915 } 916 917 void WebLocalFrameImpl::enableViewSourceMode(bool enable) 918 { 919 if (frame()) 920 frame()->setInViewSourceMode(enable); 921 } 922 923 bool WebLocalFrameImpl::isViewSourceModeEnabled() const 924 { 925 if (!frame()) 926 return false; 927 return frame()->inViewSourceMode(); 928 } 929 930 void WebLocalFrameImpl::setReferrerForRequest(WebURLRequest& request, const WebURL& referrerURL) 931 { 932 String referrer = referrerURL.isEmpty() ? frame()->document()->outgoingReferrer() : String(referrerURL.spec().utf16()); 933 referrer = SecurityPolicy::generateReferrerHeader(frame()->document()->referrerPolicy(), request.url(), referrer); 934 if (referrer.isEmpty()) 935 return; 936 request.setHTTPReferrer(referrer, static_cast<WebReferrerPolicy>(frame()->document()->referrerPolicy())); 937 } 938 939 void WebLocalFrameImpl::dispatchWillSendRequest(WebURLRequest& request) 940 { 941 ResourceResponse response; 942 frame()->loader().client()->dispatchWillSendRequest(0, 0, request.toMutableResourceRequest(), response); 943 } 944 945 WebURLLoader* WebLocalFrameImpl::createAssociatedURLLoader(const WebURLLoaderOptions& options) 946 { 947 return new AssociatedURLLoader(this, options); 948 } 949 950 unsigned WebLocalFrameImpl::unloadListenerCount() const 951 { 952 return frame()->domWindow()->pendingUnloadEventListeners(); 953 } 954 955 void WebLocalFrameImpl::replaceSelection(const WebString& text) 956 { 957 bool selectReplacement = false; 958 bool smartReplace = true; 959 frame()->editor().replaceSelectionWithText(text, selectReplacement, smartReplace); 960 } 961 962 void WebLocalFrameImpl::insertText(const WebString& text) 963 { 964 if (frame()->inputMethodController().hasComposition()) 965 frame()->inputMethodController().confirmComposition(text); 966 else 967 frame()->editor().insertText(text, 0); 968 } 969 970 void WebLocalFrameImpl::setMarkedText(const WebString& text, unsigned location, unsigned length) 971 { 972 Vector<CompositionUnderline> decorations; 973 frame()->inputMethodController().setComposition(text, decorations, location, length); 974 } 975 976 void WebLocalFrameImpl::unmarkText() 977 { 978 frame()->inputMethodController().cancelComposition(); 979 } 980 981 bool WebLocalFrameImpl::hasMarkedText() const 982 { 983 return frame()->inputMethodController().hasComposition(); 984 } 985 986 WebRange WebLocalFrameImpl::markedRange() const 987 { 988 return frame()->inputMethodController().compositionRange(); 989 } 990 991 bool WebLocalFrameImpl::firstRectForCharacterRange(unsigned location, unsigned length, WebRect& rect) const 992 { 993 if ((location + length < location) && (location + length)) 994 length = 0; 995 996 Element* editable = frame()->selection().rootEditableElementOrDocumentElement(); 997 ASSERT(editable); 998 RefPtrWillBeRawPtr<Range> range = PlainTextRange(location, location + length).createRange(*editable); 999 if (!range) 1000 return false; 1001 IntRect intRect = frame()->editor().firstRectForRange(range.get()); 1002 rect = WebRect(intRect); 1003 rect = frame()->view()->contentsToWindow(rect); 1004 return true; 1005 } 1006 1007 size_t WebLocalFrameImpl::characterIndexForPoint(const WebPoint& webPoint) const 1008 { 1009 if (!frame()) 1010 return kNotFound; 1011 1012 IntPoint point = frame()->view()->windowToContents(webPoint); 1013 HitTestResult result = frame()->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active); 1014 RefPtrWillBeRawPtr<Range> range = frame()->rangeForPoint(result.roundedPointInInnerNodeFrame()); 1015 if (!range) 1016 return kNotFound; 1017 Element* editable = frame()->selection().rootEditableElementOrDocumentElement(); 1018 ASSERT(editable); 1019 return PlainTextRange::create(*editable, *range.get()).start(); 1020 } 1021 1022 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebNode& node) 1023 { 1024 ASSERT(frame()); 1025 1026 if (name.length() <= 2) 1027 return false; 1028 1029 // Since we don't have NSControl, we will convert the format of command 1030 // string and call the function on Editor directly. 1031 String command = name; 1032 1033 // Make sure the first letter is upper case. 1034 command.replace(0, 1, command.substring(0, 1).upper()); 1035 1036 // Remove the trailing ':' if existing. 1037 if (command[command.length() - 1] == UChar(':')) 1038 command = command.substring(0, command.length() - 1); 1039 1040 WebPluginContainerImpl* pluginContainer = pluginContainerFromNode(frame(), node); 1041 if (pluginContainer && pluginContainer->executeEditCommand(name)) 1042 return true; 1043 1044 return frame()->editor().executeCommand(command); 1045 } 1046 1047 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebString& value, const WebNode& node) 1048 { 1049 ASSERT(frame()); 1050 1051 WebPluginContainerImpl* pluginContainer = pluginContainerFromNode(frame(), node); 1052 if (pluginContainer && pluginContainer->executeEditCommand(name, value)) 1053 return true; 1054 1055 return frame()->editor().executeCommand(name, value); 1056 } 1057 1058 bool WebLocalFrameImpl::isCommandEnabled(const WebString& name) const 1059 { 1060 ASSERT(frame()); 1061 return frame()->editor().command(name).isEnabled(); 1062 } 1063 1064 void WebLocalFrameImpl::enableContinuousSpellChecking(bool enable) 1065 { 1066 if (enable == isContinuousSpellCheckingEnabled()) 1067 return; 1068 frame()->spellChecker().toggleContinuousSpellChecking(); 1069 } 1070 1071 bool WebLocalFrameImpl::isContinuousSpellCheckingEnabled() const 1072 { 1073 return frame()->spellChecker().isContinuousSpellCheckingEnabled(); 1074 } 1075 1076 void WebLocalFrameImpl::requestTextChecking(const WebElement& webElement) 1077 { 1078 if (webElement.isNull()) 1079 return; 1080 frame()->spellChecker().requestTextChecking(*webElement.constUnwrap<Element>()); 1081 } 1082 1083 void WebLocalFrameImpl::replaceMisspelledRange(const WebString& text) 1084 { 1085 // If this caret selection has two or more markers, this function replace the range covered by the first marker with the specified word as Microsoft Word does. 1086 if (pluginContainerFromFrame(frame())) 1087 return; 1088 frame()->spellChecker().replaceMisspelledRange(text); 1089 } 1090 1091 void WebLocalFrameImpl::removeSpellingMarkers() 1092 { 1093 frame()->spellChecker().removeSpellingMarkers(); 1094 } 1095 1096 bool WebLocalFrameImpl::hasSelection() const 1097 { 1098 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); 1099 if (pluginContainer) 1100 return pluginContainer->plugin()->hasSelection(); 1101 1102 // frame()->selection()->isNone() never returns true. 1103 return frame()->selection().start() != frame()->selection().end(); 1104 } 1105 1106 WebRange WebLocalFrameImpl::selectionRange() const 1107 { 1108 return frame()->selection().toNormalizedRange(); 1109 } 1110 1111 WebString WebLocalFrameImpl::selectionAsText() const 1112 { 1113 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); 1114 if (pluginContainer) 1115 return pluginContainer->plugin()->selectionAsText(); 1116 1117 RefPtrWillBeRawPtr<Range> range = frame()->selection().toNormalizedRange(); 1118 if (!range) 1119 return WebString(); 1120 1121 String text = range->text(); 1122 #if OS(WIN) 1123 replaceNewlinesWithWindowsStyleNewlines(text); 1124 #endif 1125 replaceNBSPWithSpace(text); 1126 return text; 1127 } 1128 1129 WebString WebLocalFrameImpl::selectionAsMarkup() const 1130 { 1131 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); 1132 if (pluginContainer) 1133 return pluginContainer->plugin()->selectionAsMarkup(); 1134 1135 RefPtrWillBeRawPtr<Range> range = frame()->selection().toNormalizedRange(); 1136 if (!range) 1137 return WebString(); 1138 1139 return createMarkup(range.get(), 0, AnnotateForInterchange, false, ResolveNonLocalURLs); 1140 } 1141 1142 void WebLocalFrameImpl::selectWordAroundPosition(LocalFrame* frame, VisiblePosition position) 1143 { 1144 VisibleSelection selection(position); 1145 selection.expandUsingGranularity(WordGranularity); 1146 1147 TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity; 1148 frame->selection().setSelection(selection, granularity); 1149 } 1150 1151 bool WebLocalFrameImpl::selectWordAroundCaret() 1152 { 1153 FrameSelection& selection = frame()->selection(); 1154 if (selection.isNone() || selection.isRange()) 1155 return false; 1156 selectWordAroundPosition(frame(), selection.selection().visibleStart()); 1157 return true; 1158 } 1159 1160 void WebLocalFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent) 1161 { 1162 moveRangeSelection(base, extent); 1163 } 1164 1165 void WebLocalFrameImpl::selectRange(const WebRange& webRange) 1166 { 1167 if (RefPtrWillBeRawPtr<Range> range = static_cast<PassRefPtrWillBeRawPtr<Range> >(webRange)) 1168 frame()->selection().setSelectedRange(range.get(), VP_DEFAULT_AFFINITY, FrameSelection::NonDirectional, NotUserTriggered); 1169 } 1170 1171 void WebLocalFrameImpl::moveRangeSelection(const WebPoint& base, const WebPoint& extent) 1172 { 1173 VisiblePosition basePosition = visiblePositionForWindowPoint(base); 1174 VisiblePosition extentPosition = visiblePositionForWindowPoint(extent); 1175 VisibleSelection newSelection = VisibleSelection(basePosition, extentPosition); 1176 frame()->selection().setSelection(newSelection, CharacterGranularity); 1177 } 1178 1179 void WebLocalFrameImpl::moveCaretSelection(const WebPoint& point) 1180 { 1181 Element* editable = frame()->selection().rootEditableElement(); 1182 if (!editable) 1183 return; 1184 1185 VisiblePosition position = visiblePositionForWindowPoint(point); 1186 frame()->selection().moveTo(position, UserTriggered); 1187 } 1188 1189 bool WebLocalFrameImpl::setEditableSelectionOffsets(int start, int end) 1190 { 1191 return frame()->inputMethodController().setEditableSelectionOffsets(PlainTextRange(start, end)); 1192 } 1193 1194 bool WebLocalFrameImpl::setCompositionFromExistingText(int compositionStart, int compositionEnd, const WebVector<WebCompositionUnderline>& underlines) 1195 { 1196 if (!frame()->editor().canEdit()) 1197 return false; 1198 1199 InputMethodController& inputMethodController = frame()->inputMethodController(); 1200 inputMethodController.cancelComposition(); 1201 1202 if (compositionStart == compositionEnd) 1203 return true; 1204 1205 inputMethodController.setCompositionFromExistingText(CompositionUnderlineVectorBuilder(underlines), compositionStart, compositionEnd); 1206 1207 return true; 1208 } 1209 1210 void WebLocalFrameImpl::extendSelectionAndDelete(int before, int after) 1211 { 1212 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported()) { 1213 plugin->extendSelectionAndDelete(before, after); 1214 return; 1215 } 1216 frame()->inputMethodController().extendSelectionAndDelete(before, after); 1217 } 1218 1219 void WebLocalFrameImpl::setCaretVisible(bool visible) 1220 { 1221 frame()->selection().setCaretVisible(visible); 1222 } 1223 1224 VisiblePosition WebLocalFrameImpl::visiblePositionForWindowPoint(const WebPoint& point) 1225 { 1226 // FIXME(bokan): crbug.com/371902 - These scale/pinch transforms shouldn't 1227 // be ad hoc and explicit. 1228 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport(); 1229 FloatPoint unscaledPoint(point); 1230 unscaledPoint.scale(1 / view()->pageScaleFactor(), 1 / view()->pageScaleFactor()); 1231 unscaledPoint.moveBy(pinchViewport.visibleRect().location()); 1232 1233 HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping; 1234 HitTestResult result(frame()->view()->windowToContents(roundedIntPoint(unscaledPoint))); 1235 frame()->document()->renderView()->layer()->hitTest(request, result); 1236 1237 if (Node* node = result.innerNode()) 1238 return frame()->selection().selection().visiblePositionRespectingEditingBoundary(result.localPoint(), node); 1239 return VisiblePosition(); 1240 } 1241 1242 WebPlugin* WebLocalFrameImpl::focusedPluginIfInputMethodSupported() 1243 { 1244 WebPluginContainerImpl* container = WebLocalFrameImpl::pluginContainerFromNode(frame(), WebNode(frame()->document()->focusedElement())); 1245 if (container && container->supportsInputMethod()) 1246 return container->plugin(); 1247 return 0; 1248 } 1249 1250 int WebLocalFrameImpl::printBegin(const WebPrintParams& printParams, const WebNode& constrainToNode) 1251 { 1252 ASSERT(!frame()->document()->isFrameSet()); 1253 WebPluginContainerImpl* pluginContainer = 0; 1254 if (constrainToNode.isNull()) { 1255 // If this is a plugin document, check if the plugin supports its own 1256 // printing. If it does, we will delegate all printing to that. 1257 pluginContainer = pluginContainerFromFrame(frame()); 1258 } else { 1259 // We only support printing plugin nodes for now. 1260 pluginContainer = toWebPluginContainerImpl(constrainToNode.pluginContainer()); 1261 } 1262 1263 if (pluginContainer && pluginContainer->supportsPaginatedPrint()) 1264 m_printContext = adoptPtrWillBeNoop(new ChromePluginPrintContext(frame(), pluginContainer, printParams)); 1265 else 1266 m_printContext = adoptPtrWillBeNoop(new ChromePrintContext(frame())); 1267 1268 FloatRect rect(0, 0, static_cast<float>(printParams.printContentArea.width), static_cast<float>(printParams.printContentArea.height)); 1269 m_printContext->begin(rect.width(), rect.height()); 1270 float pageHeight; 1271 // We ignore the overlays calculation for now since they are generated in the 1272 // browser. pageHeight is actually an output parameter. 1273 m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight); 1274 1275 return static_cast<int>(m_printContext->pageCount()); 1276 } 1277 1278 float WebLocalFrameImpl::getPrintPageShrink(int page) 1279 { 1280 ASSERT(m_printContext && page >= 0); 1281 return m_printContext->getPageShrink(page); 1282 } 1283 1284 float WebLocalFrameImpl::printPage(int page, WebCanvas* canvas) 1285 { 1286 #if ENABLE(PRINTING) 1287 ASSERT(m_printContext && page >= 0 && frame() && frame()->document()); 1288 1289 GraphicsContext graphicsContext(canvas); 1290 graphicsContext.setPrinting(true); 1291 return m_printContext->spoolSinglePage(graphicsContext, page); 1292 #else 1293 return 0; 1294 #endif 1295 } 1296 1297 void WebLocalFrameImpl::printEnd() 1298 { 1299 ASSERT(m_printContext); 1300 m_printContext->end(); 1301 m_printContext.clear(); 1302 } 1303 1304 bool WebLocalFrameImpl::isPrintScalingDisabledForPlugin(const WebNode& node) 1305 { 1306 WebPluginContainerImpl* pluginContainer = node.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node.pluginContainer()); 1307 1308 if (!pluginContainer || !pluginContainer->supportsPaginatedPrint()) 1309 return false; 1310 1311 return pluginContainer->isPrintScalingDisabled(); 1312 } 1313 1314 int WebLocalFrameImpl::getPrintCopiesForPlugin(const WebNode& node) 1315 { 1316 WebPluginContainerImpl* pluginContainer = node.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node.pluginContainer()); 1317 1318 if (!pluginContainer || !pluginContainer->supportsPaginatedPrint()) 1319 return 1; 1320 1321 return pluginContainer->getCopiesToPrint(); 1322 } 1323 1324 bool WebLocalFrameImpl::hasCustomPageSizeStyle(int pageIndex) 1325 { 1326 return frame()->document()->styleForPage(pageIndex)->pageSizeType() != PAGE_SIZE_AUTO; 1327 } 1328 1329 bool WebLocalFrameImpl::isPageBoxVisible(int pageIndex) 1330 { 1331 return frame()->document()->isPageBoxVisible(pageIndex); 1332 } 1333 1334 void WebLocalFrameImpl::pageSizeAndMarginsInPixels(int pageIndex, WebSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft) 1335 { 1336 IntSize size = pageSize; 1337 frame()->document()->pageSizeAndMarginsInPixels(pageIndex, size, marginTop, marginRight, marginBottom, marginLeft); 1338 pageSize = size; 1339 } 1340 1341 WebString WebLocalFrameImpl::pageProperty(const WebString& propertyName, int pageIndex) 1342 { 1343 ASSERT(m_printContext); 1344 return m_printContext->pageProperty(frame(), propertyName.utf8().data(), pageIndex); 1345 } 1346 1347 bool WebLocalFrameImpl::find(int identifier, const WebString& searchText, const WebFindOptions& options, bool wrapWithinFrame, WebRect* selectionRect) 1348 { 1349 return ensureTextFinder().find(identifier, searchText, options, wrapWithinFrame, selectionRect); 1350 } 1351 1352 void WebLocalFrameImpl::stopFinding(bool clearSelection) 1353 { 1354 if (m_textFinder) { 1355 if (!clearSelection) 1356 setFindEndstateFocusAndSelection(); 1357 m_textFinder->stopFindingAndClearSelection(); 1358 } 1359 } 1360 1361 void WebLocalFrameImpl::scopeStringMatches(int identifier, const WebString& searchText, const WebFindOptions& options, bool reset) 1362 { 1363 ensureTextFinder().scopeStringMatches(identifier, searchText, options, reset); 1364 } 1365 1366 void WebLocalFrameImpl::cancelPendingScopingEffort() 1367 { 1368 if (m_textFinder) 1369 m_textFinder->cancelPendingScopingEffort(); 1370 } 1371 1372 void WebLocalFrameImpl::increaseMatchCount(int count, int identifier) 1373 { 1374 // This function should only be called on the mainframe. 1375 ASSERT(!parent()); 1376 ensureTextFinder().increaseMatchCount(identifier, count); 1377 } 1378 1379 void WebLocalFrameImpl::resetMatchCount() 1380 { 1381 ensureTextFinder().resetMatchCount(); 1382 } 1383 1384 void WebLocalFrameImpl::dispatchMessageEventWithOriginCheck(const WebSecurityOrigin& intendedTargetOrigin, const WebDOMEvent& event) 1385 { 1386 ASSERT(!event.isNull()); 1387 frame()->domWindow()->dispatchMessageEventWithOriginCheck(intendedTargetOrigin.get(), event, nullptr); 1388 } 1389 1390 int WebLocalFrameImpl::findMatchMarkersVersion() const 1391 { 1392 ASSERT(!parent()); 1393 1394 if (m_textFinder) 1395 return m_textFinder->findMatchMarkersVersion(); 1396 return 0; 1397 } 1398 1399 int WebLocalFrameImpl::selectNearestFindMatch(const WebFloatPoint& point, WebRect* selectionRect) 1400 { 1401 ASSERT(!parent()); 1402 return ensureTextFinder().selectNearestFindMatch(point, selectionRect); 1403 } 1404 1405 WebFloatRect WebLocalFrameImpl::activeFindMatchRect() 1406 { 1407 ASSERT(!parent()); 1408 1409 if (m_textFinder) 1410 return m_textFinder->activeFindMatchRect(); 1411 return WebFloatRect(); 1412 } 1413 1414 void WebLocalFrameImpl::findMatchRects(WebVector<WebFloatRect>& outputRects) 1415 { 1416 ASSERT(!parent()); 1417 ensureTextFinder().findMatchRects(outputRects); 1418 } 1419 1420 void WebLocalFrameImpl::setTickmarks(const WebVector<WebRect>& tickmarks) 1421 { 1422 if (frameView()) { 1423 Vector<IntRect> tickmarksConverted(tickmarks.size()); 1424 for (size_t i = 0; i < tickmarks.size(); ++i) 1425 tickmarksConverted[i] = tickmarks[i]; 1426 frameView()->setTickmarks(tickmarksConverted); 1427 invalidateScrollbar(); 1428 } 1429 } 1430 1431 WebString WebLocalFrameImpl::contentAsText(size_t maxChars) const 1432 { 1433 if (!frame()) 1434 return WebString(); 1435 StringBuilder text; 1436 frameContentAsPlainText(maxChars, frame(), text); 1437 return text.toString(); 1438 } 1439 1440 WebString WebLocalFrameImpl::contentAsMarkup() const 1441 { 1442 if (!frame()) 1443 return WebString(); 1444 return createMarkup(frame()->document()); 1445 } 1446 1447 WebString WebLocalFrameImpl::renderTreeAsText(RenderAsTextControls toShow) const 1448 { 1449 RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal; 1450 1451 if (toShow & RenderAsTextDebug) 1452 behavior |= RenderAsTextShowCompositedLayers | RenderAsTextShowAddresses | RenderAsTextShowIDAndClass | RenderAsTextShowLayerNesting; 1453 1454 if (toShow & RenderAsTextPrinting) 1455 behavior |= RenderAsTextPrintingMode; 1456 1457 return externalRepresentation(frame(), behavior); 1458 } 1459 1460 WebString WebLocalFrameImpl::markerTextForListItem(const WebElement& webElement) const 1461 { 1462 return blink::markerTextForListItem(const_cast<Element*>(webElement.constUnwrap<Element>())); 1463 } 1464 1465 void WebLocalFrameImpl::printPagesWithBoundaries(WebCanvas* canvas, const WebSize& pageSizeInPixels) 1466 { 1467 ASSERT(m_printContext); 1468 1469 GraphicsContext graphicsContext(canvas); 1470 graphicsContext.setPrinting(true); 1471 1472 m_printContext->spoolAllPagesWithBoundaries(graphicsContext, FloatSize(pageSizeInPixels.width, pageSizeInPixels.height)); 1473 } 1474 1475 WebRect WebLocalFrameImpl::selectionBoundsRect() const 1476 { 1477 return hasSelection() ? WebRect(IntRect(frame()->selection().bounds())) : WebRect(); 1478 } 1479 1480 bool WebLocalFrameImpl::selectionStartHasSpellingMarkerFor(int from, int length) const 1481 { 1482 if (!frame()) 1483 return false; 1484 return frame()->spellChecker().selectionStartHasSpellingMarkerFor(from, length); 1485 } 1486 1487 WebString WebLocalFrameImpl::layerTreeAsText(bool showDebugInfo) const 1488 { 1489 if (!frame()) 1490 return WebString(); 1491 1492 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesDebugInfo : LayerTreeNormal)); 1493 } 1494 1495 // WebLocalFrameImpl public --------------------------------------------------------- 1496 1497 WebLocalFrame* WebLocalFrame::create(WebFrameClient* client) 1498 { 1499 return WebLocalFrameImpl::create(client); 1500 } 1501 1502 WebLocalFrameImpl* WebLocalFrameImpl::create(WebFrameClient* client) 1503 { 1504 WebLocalFrameImpl* frame = new WebLocalFrameImpl(client); 1505 #if ENABLE(OILPAN) 1506 return frame; 1507 #else 1508 return adoptRef(frame).leakRef(); 1509 #endif 1510 } 1511 1512 WebLocalFrameImpl::WebLocalFrameImpl(WebFrameClient* client) 1513 : m_frameLoaderClientImpl(this) 1514 , m_client(client) 1515 , m_permissionClient(0) 1516 , m_inputEventsScaleFactorForEmulation(1) 1517 , m_userMediaClientImpl(this) 1518 , m_geolocationClientProxy(GeolocationClientProxy::create(client ? client->geolocationClient() : 0)) 1519 #if ENABLE(OILPAN) 1520 , m_selfKeepAlive(this) 1521 #endif 1522 { 1523 Platform::current()->incrementStatsCounter(webFrameActiveCount); 1524 frameCount++; 1525 } 1526 1527 WebLocalFrameImpl::~WebLocalFrameImpl() 1528 { 1529 Platform::current()->decrementStatsCounter(webFrameActiveCount); 1530 frameCount--; 1531 1532 cancelPendingScopingEffort(); 1533 } 1534 1535 void WebLocalFrameImpl::trace(Visitor* visitor) 1536 { 1537 #if ENABLE(OILPAN) 1538 visitor->trace(m_frame); 1539 visitor->trace(m_printContext); 1540 visitor->trace(m_geolocationClientProxy); 1541 1542 WebFrame::traceChildren(visitor, this); 1543 #endif 1544 } 1545 1546 void WebLocalFrameImpl::setCoreFrame(PassRefPtrWillBeRawPtr<LocalFrame> frame) 1547 { 1548 m_frame = frame; 1549 1550 // FIXME: we shouldn't add overhead to every frame by registering these objects when they're not used. 1551 if (m_frame) { 1552 OwnPtr<NotificationPresenterImpl> notificationPresenter = adoptPtr(new NotificationPresenterImpl()); 1553 if (m_client) 1554 notificationPresenter->initialize(m_client->notificationPresenter()); 1555 1556 provideNotification(*m_frame, notificationPresenter.release()); 1557 provideNotificationPermissionClientTo(*m_frame, NotificationPermissionClientImpl::create()); 1558 provideUserMediaTo(*m_frame, &m_userMediaClientImpl); 1559 provideGeolocationTo(*m_frame, m_geolocationClientProxy.get()); 1560 m_geolocationClientProxy->setController(GeolocationController::from(m_frame.get())); 1561 provideMIDITo(*m_frame, MIDIClientProxy::create(m_client ? m_client->webMIDIClient() : 0)); 1562 provideLocalFileSystemTo(*m_frame, LocalFileSystemClient::create()); 1563 1564 if (RuntimeEnabledFeatures::screenOrientationEnabled()) 1565 ScreenOrientationController::provideTo(*m_frame, m_client ? m_client->webScreenOrientationClient() : 0); 1566 } 1567 } 1568 1569 PassRefPtrWillBeRawPtr<LocalFrame> WebLocalFrameImpl::initializeCoreFrame(FrameHost* host, FrameOwner* owner, const AtomicString& name, const AtomicString& fallbackName) 1570 { 1571 RefPtrWillBeRawPtr<LocalFrame> frame = LocalFrame::create(&m_frameLoaderClientImpl, host, owner); 1572 setCoreFrame(frame); 1573 frame->tree().setName(name, fallbackName); 1574 // We must call init() after m_frame is assigned because it is referenced 1575 // during init(). Note that this may dispatch JS events; the frame may be 1576 // detached after init() returns. 1577 frame->init(); 1578 return frame; 1579 } 1580 1581 PassRefPtrWillBeRawPtr<LocalFrame> WebLocalFrameImpl::createChildFrame(const FrameLoadRequest& request, HTMLFrameOwnerElement* ownerElement) 1582 { 1583 ASSERT(m_client); 1584 WebLocalFrameImpl* webframeChild = toWebLocalFrameImpl(m_client->createChildFrame(this, request.frameName())); 1585 if (!webframeChild) 1586 return nullptr; 1587 1588 // FIXME: Using subResourceAttributeName as fallback is not a perfect 1589 // solution. subResourceAttributeName returns just one attribute name. The 1590 // element might not have the attribute, and there might be other attributes 1591 // which can identify the element. 1592 RefPtrWillBeRawPtr<LocalFrame> child = webframeChild->initializeCoreFrame(frame()->host(), ownerElement, request.frameName(), ownerElement->getAttribute(ownerElement->subResourceAttributeName())); 1593 // Initializing the core frame may cause the new child to be detached, since 1594 // it may dispatch a load event in the parent. 1595 if (!child->tree().parent()) 1596 return nullptr; 1597 1598 // If we're moving in the back/forward list, we might want to replace the content 1599 // of this child frame with whatever was there at that point. 1600 RefPtr<HistoryItem> childItem; 1601 if (isBackForwardLoadType(frame()->loader().loadType()) && !frame()->document()->loadEventFinished()) 1602 childItem = PassRefPtr<HistoryItem>(webframeChild->client()->historyItemForNewChildFrame(webframeChild)); 1603 1604 if (childItem) 1605 child->loader().loadHistoryItem(childItem.get()); 1606 else 1607 child->loader().load(FrameLoadRequest(0, request.resourceRequest(), "_self")); 1608 1609 // Note a synchronous navigation (about:blank) would have already processed 1610 // onload, so it is possible for the child frame to have already been 1611 // detached by script in the page. 1612 if (!child->tree().parent()) 1613 return nullptr; 1614 return child; 1615 } 1616 1617 void WebLocalFrameImpl::didChangeContentsSize(const IntSize& size) 1618 { 1619 // This is only possible on the main frame. 1620 if (m_textFinder && m_textFinder->totalMatchCount() > 0) { 1621 ASSERT(!parent()); 1622 m_textFinder->increaseMarkerVersion(); 1623 } 1624 } 1625 1626 void WebLocalFrameImpl::createFrameView() 1627 { 1628 TRACE_EVENT0("blink", "WebLocalFrameImpl::createFrameView"); 1629 1630 ASSERT(frame()); // If frame() doesn't exist, we probably didn't init properly. 1631 1632 WebViewImpl* webView = viewImpl(); 1633 bool isLocalRoot = frame()->isLocalRoot(); 1634 if (isLocalRoot) 1635 webView->suppressInvalidations(true); 1636 1637 frame()->createView(webView->size(), webView->baseBackgroundColor(), webView->isTransparent()); 1638 if (webView->shouldAutoResize() && isLocalRoot) 1639 frame()->view()->enableAutoSizeMode(webView->minAutoSize(), webView->maxAutoSize()); 1640 1641 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation, m_inputEventsScaleFactorForEmulation); 1642 1643 if (isLocalRoot) 1644 webView->suppressInvalidations(false); 1645 } 1646 1647 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame* frame) 1648 { 1649 if (!frame) 1650 return 0; 1651 return fromFrame(*frame); 1652 } 1653 1654 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame& frame) 1655 { 1656 FrameLoaderClient* client = frame.loader().client(); 1657 if (!client || !client->isFrameLoaderClientImpl()) 1658 return 0; 1659 return toFrameLoaderClientImpl(client)->webFrame(); 1660 } 1661 1662 WebLocalFrameImpl* WebLocalFrameImpl::fromFrameOwnerElement(Element* element) 1663 { 1664 // FIXME: Why do we check specifically for <iframe> and <frame> here? Why can't we get the WebLocalFrameImpl from an <object> element, for example. 1665 if (!isHTMLFrameElementBase(element)) 1666 return 0; 1667 return fromFrame(toLocalFrame(toHTMLFrameElementBase(element)->contentFrame())); 1668 } 1669 1670 WebViewImpl* WebLocalFrameImpl::viewImpl() const 1671 { 1672 if (!frame()) 1673 return 0; 1674 return WebViewImpl::fromPage(frame()->page()); 1675 } 1676 1677 WebDataSourceImpl* WebLocalFrameImpl::dataSourceImpl() const 1678 { 1679 return static_cast<WebDataSourceImpl*>(dataSource()); 1680 } 1681 1682 WebDataSourceImpl* WebLocalFrameImpl::provisionalDataSourceImpl() const 1683 { 1684 return static_cast<WebDataSourceImpl*>(provisionalDataSource()); 1685 } 1686 1687 void WebLocalFrameImpl::setFindEndstateFocusAndSelection() 1688 { 1689 WebLocalFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl(); 1690 1691 if (this != mainFrameImpl->activeMatchFrame()) 1692 return; 1693 1694 if (Range* activeMatch = m_textFinder->activeMatch()) { 1695 // If the user has set the selection since the match was found, we 1696 // don't focus anything. 1697 VisibleSelection selection(frame()->selection().selection()); 1698 if (!selection.isNone()) 1699 return; 1700 1701 // Need to clean out style and layout state before querying Element::isFocusable(). 1702 frame()->document()->updateLayoutIgnorePendingStylesheets(); 1703 1704 // Try to find the first focusable node up the chain, which will, for 1705 // example, focus links if we have found text within the link. 1706 Node* node = activeMatch->firstNode(); 1707 if (node && node->isInShadowTree()) { 1708 if (Node* host = node->shadowHost()) { 1709 if (isHTMLInputElement(*host) || isHTMLTextAreaElement(*host)) 1710 node = host; 1711 } 1712 } 1713 for (; node; node = node->parentNode()) { 1714 if (!node->isElementNode()) 1715 continue; 1716 Element* element = toElement(node); 1717 if (element->isFocusable()) { 1718 // Found a focusable parent node. Set the active match as the 1719 // selection and focus to the focusable node. 1720 frame()->selection().setSelection(VisibleSelection(activeMatch)); 1721 frame()->document()->setFocusedElement(element); 1722 return; 1723 } 1724 } 1725 1726 // Iterate over all the nodes in the range until we find a focusable node. 1727 // This, for example, sets focus to the first link if you search for 1728 // text and text that is within one or more links. 1729 node = activeMatch->firstNode(); 1730 for (; node && node != activeMatch->pastLastNode(); node = NodeTraversal::next(*node)) { 1731 if (!node->isElementNode()) 1732 continue; 1733 Element* element = toElement(node); 1734 if (element->isFocusable()) { 1735 frame()->document()->setFocusedElement(element); 1736 return; 1737 } 1738 } 1739 1740 // No node related to the active match was focusable, so set the 1741 // active match as the selection (so that when you end the Find session, 1742 // you'll have the last thing you found highlighted) and make sure that 1743 // we have nothing focused (otherwise you might have text selected but 1744 // a link focused, which is weird). 1745 frame()->selection().setSelection(VisibleSelection(activeMatch)); 1746 frame()->document()->setFocusedElement(nullptr); 1747 1748 // Finally clear the active match, for two reasons: 1749 // We just finished the find 'session' and we don't want future (potentially 1750 // unrelated) find 'sessions' operations to start at the same place. 1751 // The WebLocalFrameImpl could get reused and the activeMatch could end up pointing 1752 // to a document that is no longer valid. Keeping an invalid reference around 1753 // is just asking for trouble. 1754 m_textFinder->resetActiveMatch(); 1755 } 1756 } 1757 1758 void WebLocalFrameImpl::didFail(const ResourceError& error, bool wasProvisional) 1759 { 1760 if (!client()) 1761 return; 1762 WebURLError webError = error; 1763 if (wasProvisional) 1764 client()->didFailProvisionalLoad(this, webError); 1765 else 1766 client()->didFailLoad(this, webError); 1767 } 1768 1769 void WebLocalFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars) 1770 { 1771 frame()->view()->setCanHaveScrollbars(canHaveScrollbars); 1772 } 1773 1774 void WebLocalFrameImpl::setInputEventsTransformForEmulation(const IntSize& offset, float contentScaleFactor) 1775 { 1776 m_inputEventsOffsetForEmulation = offset; 1777 m_inputEventsScaleFactorForEmulation = contentScaleFactor; 1778 if (frame()->view()) 1779 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation, m_inputEventsScaleFactorForEmulation); 1780 } 1781 1782 void WebLocalFrameImpl::loadJavaScriptURL(const KURL& url) 1783 { 1784 // This is copied from ScriptController::executeScriptIfJavaScriptURL. 1785 // Unfortunately, we cannot just use that method since it is private, and 1786 // it also doesn't quite behave as we require it to for bookmarklets. The 1787 // key difference is that we need to suppress loading the string result 1788 // from evaluating the JS URL if executing the JS URL resulted in a 1789 // location change. We also allow a JS URL to be loaded even if scripts on 1790 // the page are otherwise disabled. 1791 1792 if (!frame()->document() || !frame()->page()) 1793 return; 1794 1795 RefPtrWillBeRawPtr<Document> ownerDocument(frame()->document()); 1796 1797 // Protect privileged pages against bookmarklets and other javascript manipulations. 1798 if (SchemeRegistry::shouldTreatURLSchemeAsNotAllowingJavascriptURLs(frame()->document()->url().protocol())) 1799 return; 1800 1801 String script = decodeURLEscapeSequences(url.string().substring(strlen("javascript:"))); 1802 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); 1803 v8::HandleScope handleScope(toIsolate(frame())); 1804 v8::Local<v8::Value> result = frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script)); 1805 if (result.IsEmpty() || !result->IsString()) 1806 return; 1807 String scriptResult = toCoreString(v8::Handle<v8::String>::Cast(result)); 1808 if (!frame()->navigationScheduler().locationChangePending()) 1809 frame()->loader().replaceDocumentWhileExecutingJavaScriptURL(scriptResult, ownerDocument.get()); 1810 } 1811 1812 void WebLocalFrameImpl::sendPings(const WebNode& linkNode, const WebURL& destinationURL) 1813 { 1814 ASSERT(frame()); 1815 const Node* node = linkNode.constUnwrap<Node>(); 1816 if (isHTMLAnchorElement(node)) 1817 toHTMLAnchorElement(node)->sendPings(destinationURL); 1818 } 1819 1820 bool WebLocalFrameImpl::isLoading() const 1821 { 1822 if (!frame() || !frame()->document()) 1823 return false; 1824 return frame()->loader().stateMachine()->isDisplayingInitialEmptyDocument() || !frame()->document()->loadEventFinished(); 1825 } 1826 1827 bool WebLocalFrameImpl::isResourceLoadInProgress() const 1828 { 1829 if (!frame() || !frame()->document()) 1830 return false; 1831 return frame()->document()->fetcher()->requestCount(); 1832 } 1833 1834 void WebLocalFrameImpl::addStyleSheetByURL(const WebString& url) 1835 { 1836 RefPtrWillBeRawPtr<Element> styleElement = frame()->document()->createElement(HTMLNames::linkTag, false); 1837 1838 styleElement->setAttribute(HTMLNames::typeAttr, "text/css"); 1839 styleElement->setAttribute(HTMLNames::relAttr, "stylesheet"); 1840 styleElement->setAttribute(HTMLNames::hrefAttr, url); 1841 1842 frame()->document()->head()->appendChild(styleElement.release(), IGNORE_EXCEPTION); 1843 } 1844 1845 void WebLocalFrameImpl::navigateToSandboxedMarkup(const WebData& markup) 1846 { 1847 ASSERT(document().securityOrigin().isUnique()); 1848 frame()->loader().forceSandboxFlags(SandboxAll); 1849 loadHTMLString(markup, document().url(), WebURL(), true); 1850 } 1851 1852 void WebLocalFrameImpl::sendOrientationChangeEvent() 1853 { 1854 if (!frame()) 1855 return; 1856 1857 // Screen Orientation API 1858 if (ScreenOrientationController::from(*frame())) 1859 ScreenOrientationController::from(*frame())->notifyOrientationChanged(); 1860 1861 // Legacy window.orientation API. 1862 if (RuntimeEnabledFeatures::orientationEventEnabled() && frame()->domWindow()) 1863 frame()->domWindow()->dispatchEvent(Event::create(EventTypeNames::orientationchange)); 1864 } 1865 1866 v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValueForTests(const WebScriptSource& source) 1867 { 1868 // FIXME: This fake UserGestureIndicator is required for a bunch of browser 1869 // tests to pass. We should update the tests to simulate input and get rid 1870 // of this. 1871 // http://code.google.com/p/chromium/issues/detail?id=86397 1872 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture); 1873 return executeScriptAndReturnValue(source); 1874 } 1875 1876 void WebLocalFrameImpl::willDetachParent() 1877 { 1878 // Do not expect string scoping results from any frames that got detached 1879 // in the middle of the operation. 1880 if (m_textFinder && m_textFinder->scopingInProgress()) { 1881 1882 // There is a possibility that the frame being detached was the only 1883 // pending one. We need to make sure final replies can be sent. 1884 m_textFinder->flushCurrentScoping(); 1885 1886 m_textFinder->cancelPendingScopingEffort(); 1887 } 1888 } 1889 1890 WebLocalFrameImpl* WebLocalFrameImpl::activeMatchFrame() const 1891 { 1892 ASSERT(!parent()); 1893 1894 if (m_textFinder) 1895 return m_textFinder->activeMatchFrame(); 1896 return 0; 1897 } 1898 1899 Range* WebLocalFrameImpl::activeMatch() const 1900 { 1901 if (m_textFinder) 1902 return m_textFinder->activeMatch(); 1903 return 0; 1904 } 1905 1906 TextFinder& WebLocalFrameImpl::ensureTextFinder() 1907 { 1908 if (!m_textFinder) 1909 m_textFinder = TextFinder::create(*this); 1910 1911 return *m_textFinder; 1912 } 1913 1914 void WebLocalFrameImpl::invalidateScrollbar() const 1915 { 1916 ASSERT(frame() && frame()->view()); 1917 FrameView* view = frame()->view(); 1918 // Invalidate the vertical scroll bar region for the view. 1919 Scrollbar* scrollbar = view->verticalScrollbar(); 1920 if (scrollbar) 1921 scrollbar->invalidate(); 1922 } 1923 1924 void WebLocalFrameImpl::invalidateAll() const 1925 { 1926 ASSERT(frame() && frame()->view()); 1927 FrameView* view = frame()->view(); 1928 view->invalidateRect(view->frameRect()); 1929 invalidateScrollbar(); 1930 } 1931 1932 } // namespace blink 1933