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