Home | History | Annotate | Download | only in web
      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