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