• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
frameContentAsPlainText(size_t maxChars,LocalFrame * frame,StringBuilder & output)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 
pluginContainerFromFrame(LocalFrame * frame)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 
pluginContainerFromNode(WebCore::LocalFrame * frame,const WebNode & node)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:
ChromePrintContext(LocalFrame * frame)294     ChromePrintContext(LocalFrame* frame)
295         : PrintContext(frame)
296         , m_printedPageWidth(0)
297     {
298     }
299 
~ChromePrintContext()300     virtual ~ChromePrintContext() { }
301 
begin(float width,float height)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 
end()309     virtual void end()
310     {
311         PrintContext::end();
312     }
313 
getPageShrink(int pageNumber) const314     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.
spoolPage(GraphicsContext & context,int pageNumber)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 
spoolAllPagesWithBoundaries(GraphicsContext & graphicsContext,const FloatSize & pageSizeInPixels)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 
computePageRects(const FloatRect & printRect,float headerHeight,float footerHeight,float userScaleFactor,float & outPageHeight)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 
pageCount() const393     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:
ChromePluginPrintContext(LocalFrame * frame,WebPluginContainerImpl * plugin,const WebPrintParams & printParams)408     ChromePluginPrintContext(LocalFrame* frame, WebPluginContainerImpl* plugin, const WebPrintParams& printParams)
409         : ChromePrintContext(frame), m_plugin(plugin), m_pageCount(0), m_printParams(printParams)
410     {
411     }
412 
~ChromePluginPrintContext()413     virtual ~ChromePluginPrintContext() { }
414 
begin(float width,float height)415     virtual void begin(float width, float height)
416     {
417     }
418 
end()419     virtual void end()
420     {
421         m_plugin->printEnd();
422     }
423 
getPageShrink(int pageNumber) const424     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 
computePageRects(const FloatRect & printRect,float headerHeight,float footerHeight,float userScaleFactor,float & outPageHeight)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 
pageCount() const436     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.
spoolPage(GraphicsContext & context,int pageNumber)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 
DataSourceForDocLoader(DocumentLoader * loader)458 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader)
459 {
460     return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0;
461 }
462 
463 // WebFrame -------------------------------------------------------------------
464 
instanceCount()465 int WebFrame::instanceCount()
466 {
467     return frameCount;
468 }
469 
frameForCurrentContext()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 
frameForContext(v8::Handle<v8::Context> context)478 WebLocalFrame* WebLocalFrame::frameForContext(v8::Handle<v8::Context> context)
479 {
480     return WebLocalFrameImpl::fromFrame(toFrameIfNotDetached(context));
481 }
482 
fromFrameOwnerElement(const WebElement & element)483 WebLocalFrame* WebLocalFrame::fromFrameOwnerElement(const WebElement& element)
484 {
485     return WebLocalFrameImpl::fromFrameOwnerElement(PassRefPtrWillBeRawPtr<Element>(element).get());
486 }
487 
isWebLocalFrame() const488 bool WebLocalFrameImpl::isWebLocalFrame() const
489 {
490     return true;
491 }
492 
toWebLocalFrame()493 WebLocalFrame* WebLocalFrameImpl::toWebLocalFrame()
494 {
495     return this;
496 }
497 
isWebRemoteFrame() const498 bool WebLocalFrameImpl::isWebRemoteFrame() const
499 {
500     return false;
501 }
502 
toWebRemoteFrame()503 WebRemoteFrame* WebLocalFrameImpl::toWebRemoteFrame()
504 {
505     ASSERT_NOT_REACHED();
506     return 0;
507 }
508 
close()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 
uniqueName() const524 WebString WebLocalFrameImpl::uniqueName() const
525 {
526     return frame()->tree().uniqueName();
527 }
528 
assignedName() const529 WebString WebLocalFrameImpl::assignedName() const
530 {
531     return frame()->tree().name();
532 }
533 
setName(const WebString & name)534 void WebLocalFrameImpl::setName(const WebString& name)
535 {
536     frame()->tree().setName(name);
537 }
538 
iconURLs(int iconTypesMask) const539 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 
setIsRemote(bool isRemote)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 
setRemoteWebLayer(WebLayer * webLayer)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 
setPermissionClient(WebPermissionClient * permissionClient)572 void WebLocalFrameImpl::setPermissionClient(WebPermissionClient* permissionClient)
573 {
574     m_permissionClient = permissionClient;
575 }
576 
setSharedWorkerRepositoryClient(WebSharedWorkerRepositoryClient * client)577 void WebLocalFrameImpl::setSharedWorkerRepositoryClient(WebSharedWorkerRepositoryClient* client)
578 {
579     m_sharedWorkerRepositoryClient = SharedWorkerRepositoryClientImpl::create(client);
580 }
581 
scrollOffset() const582 WebSize WebLocalFrameImpl::scrollOffset() const
583 {
584     FrameView* view = frameView();
585     if (!view)
586         return WebSize();
587     return view->scrollOffset();
588 }
589 
minimumScrollOffset() const590 WebSize WebLocalFrameImpl::minimumScrollOffset() const
591 {
592     FrameView* view = frameView();
593     if (!view)
594         return WebSize();
595     return toIntSize(view->minimumScrollPosition());
596 }
597 
maximumScrollOffset() const598 WebSize WebLocalFrameImpl::maximumScrollOffset() const
599 {
600     FrameView* view = frameView();
601     if (!view)
602         return WebSize();
603     return toIntSize(view->maximumScrollPosition());
604 }
605 
setScrollOffset(const WebSize & offset)606 void WebLocalFrameImpl::setScrollOffset(const WebSize& offset)
607 {
608     if (FrameView* view = frameView())
609         view->setScrollOffset(IntPoint(offset.width, offset.height));
610 }
611 
contentsSize() const612 WebSize WebLocalFrameImpl::contentsSize() const
613 {
614     return frame()->view()->contentsSize();
615 }
616 
hasVisibleContent() const617 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 
visibleContentRect() const626 WebRect WebLocalFrameImpl::visibleContentRect() const
627 {
628     return frame()->view()->visibleContentRect();
629 }
630 
hasHorizontalScrollbar() const631 bool WebLocalFrameImpl::hasHorizontalScrollbar() const
632 {
633     return frame() && frame()->view() && frame()->view()->horizontalScrollbar();
634 }
635 
hasVerticalScrollbar() const636 bool WebLocalFrameImpl::hasVerticalScrollbar() const
637 {
638     return frame() && frame()->view() && frame()->view()->verticalScrollbar();
639 }
640 
view() const641 WebView* WebLocalFrameImpl::view() const
642 {
643     return viewImpl();
644 }
645 
setOpener(WebFrame * opener)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 
document() const659 WebDocument WebLocalFrameImpl::document() const
660 {
661     if (!frame() || !frame()->document())
662         return WebDocument();
663     return WebDocument(frame()->document());
664 }
665 
performance() const666 WebPerformance WebLocalFrameImpl::performance() const
667 {
668     if (!frame())
669         return WebPerformance();
670     return WebPerformance(&frame()->domWindow()->performance());
671 }
672 
dispatchBeforeUnloadEvent()673 bool WebLocalFrameImpl::dispatchBeforeUnloadEvent()
674 {
675     if (!frame())
676         return true;
677     return frame()->loader().shouldClose();
678 }
679 
dispatchUnloadEvent()680 void WebLocalFrameImpl::dispatchUnloadEvent()
681 {
682     if (!frame())
683         return;
684     frame()->loader().closeURL();
685 }
686 
windowObject() const687 NPObject* WebLocalFrameImpl::windowObject() const
688 {
689     if (!frame())
690         return 0;
691     return frame()->script().windowScriptNPObject();
692 }
693 
bindToWindowObject(const WebString & name,NPObject * object)694 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object)
695 {
696     bindToWindowObject(name, object, 0);
697 }
698 
bindToWindowObject(const WebString & name,NPObject * object,void *)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 
executeScript(const WebScriptSource & source)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 
executeScriptInIsolatedWorld(int worldID,const WebScriptSource * sourcesIn,unsigned numSources,int extensionGroup)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 
setIsolatedWorldSecurityOrigin(int worldID,const WebSecurityOrigin & securityOrigin)730 void WebLocalFrameImpl::setIsolatedWorldSecurityOrigin(int worldID, const WebSecurityOrigin& securityOrigin)
731 {
732     ASSERT(frame());
733     DOMWrapperWorld::setIsolatedWorldSecurityOrigin(worldID, securityOrigin.get());
734 }
735 
setIsolatedWorldContentSecurityPolicy(int worldID,const WebString & policy)736 void WebLocalFrameImpl::setIsolatedWorldContentSecurityPolicy(int worldID, const WebString& policy)
737 {
738     ASSERT(frame());
739     DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(worldID, policy);
740 }
741 
addMessageToConsole(const WebConsoleMessage & message)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 
collectGarbage()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 
checkIfRunInsecureContent(const WebURL & url) const777 bool WebLocalFrameImpl::checkIfRunInsecureContent(const WebURL& url) const
778 {
779     ASSERT(frame());
780     return frame()->loader().mixedContentChecker()->canRunInsecureContent(frame()->document()->securityOrigin(), url);
781 }
782 
executeScriptAndReturnValue(const WebScriptSource & source)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 
executeScriptInIsolatedWorld(int worldID,const WebScriptSource * sourcesIn,unsigned numSources,int extensionGroup,WebVector<v8::Local<v8::Value>> * results)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 
callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function> function,v8::Handle<v8::Value> receiver,int argc,v8::Handle<v8::Value> argv[])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 
mainWorldScriptContext() const829 v8::Local<v8::Context> WebLocalFrameImpl::mainWorldScriptContext() const
830 {
831     return toV8Context(frame(), DOMWrapperWorld::mainWorld());
832 }
833 
reload(bool ignoreCache)834 void WebLocalFrameImpl::reload(bool ignoreCache)
835 {
836     ASSERT(frame());
837     frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload);
838 }
839 
reloadWithOverrideURL(const WebURL & overrideUrl,bool ignoreCache)840 void WebLocalFrameImpl::reloadWithOverrideURL(const WebURL& overrideUrl, bool ignoreCache)
841 {
842     ASSERT(frame());
843     frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload, overrideUrl);
844 }
845 
loadRequest(const WebURLRequest & request)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 
loadHistoryItem(const WebHistoryItem & item,WebHistoryLoadType loadType,WebURLRequest::CachePolicy cachePolicy)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 
loadData(const WebData & data,const WebString & mimeType,const WebString & textEncoding,const WebURL & baseURL,const WebURL & unreachableURL,bool replace)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 
loadHTMLString(const WebData & data,const WebURL & baseURL,const WebURL & unreachableURL,bool replace)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 
isLoading() const895 bool WebLocalFrameImpl::isLoading() const
896 {
897     if (!frame())
898         return false;
899     return frame()->loader().isLoading();
900 }
901 
stopLoading()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 
provisionalDataSource() const911 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 
dataSource() const923 WebDataSource* WebLocalFrameImpl::dataSource() const
924 {
925     ASSERT(frame());
926     return DataSourceForDocLoader(frame()->loader().documentLoader());
927 }
928 
enableViewSourceMode(bool enable)929 void WebLocalFrameImpl::enableViewSourceMode(bool enable)
930 {
931     if (frame())
932         frame()->setInViewSourceMode(enable);
933 }
934 
isViewSourceModeEnabled() const935 bool WebLocalFrameImpl::isViewSourceModeEnabled() const
936 {
937     if (!frame())
938         return false;
939     return frame()->inViewSourceMode();
940 }
941 
setReferrerForRequest(WebURLRequest & request,const WebURL & referrerURL)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 
dispatchWillSendRequest(WebURLRequest & request)951 void WebLocalFrameImpl::dispatchWillSendRequest(WebURLRequest& request)
952 {
953     ResourceResponse response;
954     frame()->loader().client()->dispatchWillSendRequest(0, 0, request.toMutableResourceRequest(), response);
955 }
956 
createAssociatedURLLoader(const WebURLLoaderOptions & options)957 WebURLLoader* WebLocalFrameImpl::createAssociatedURLLoader(const WebURLLoaderOptions& options)
958 {
959     return new AssociatedURLLoader(this, options);
960 }
961 
unloadListenerCount() const962 unsigned WebLocalFrameImpl::unloadListenerCount() const
963 {
964     return frame()->domWindow()->pendingUnloadEventListeners();
965 }
966 
replaceSelection(const WebString & text)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 
insertText(const WebString & text)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 
setMarkedText(const WebString & text,unsigned location,unsigned length)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 
unmarkText()988 void WebLocalFrameImpl::unmarkText()
989 {
990     frame()->inputMethodController().cancelComposition();
991 }
992 
hasMarkedText() const993 bool WebLocalFrameImpl::hasMarkedText() const
994 {
995     return frame()->inputMethodController().hasComposition();
996 }
997 
markedRange() const998 WebRange WebLocalFrameImpl::markedRange() const
999 {
1000     return frame()->inputMethodController().compositionRange();
1001 }
1002 
firstRectForCharacterRange(unsigned location,unsigned length,WebRect & rect) const1003 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 
characterIndexForPoint(const WebPoint & webPoint) const1019 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 
executeCommand(const WebString & name,const WebNode & node)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 
executeCommand(const WebString & name,const WebString & value,const WebNode & node)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 
isCommandEnabled(const WebString & name) const1106 bool WebLocalFrameImpl::isCommandEnabled(const WebString& name) const
1107 {
1108     ASSERT(frame());
1109     return frame()->editor().command(name).isEnabled();
1110 }
1111 
enableContinuousSpellChecking(bool enable)1112 void WebLocalFrameImpl::enableContinuousSpellChecking(bool enable)
1113 {
1114     if (enable == isContinuousSpellCheckingEnabled())
1115         return;
1116     frame()->spellChecker().toggleContinuousSpellChecking();
1117 }
1118 
isContinuousSpellCheckingEnabled() const1119 bool WebLocalFrameImpl::isContinuousSpellCheckingEnabled() const
1120 {
1121     return frame()->spellChecker().isContinuousSpellCheckingEnabled();
1122 }
1123 
requestTextChecking(const WebElement & webElement)1124 void WebLocalFrameImpl::requestTextChecking(const WebElement& webElement)
1125 {
1126     if (webElement.isNull())
1127         return;
1128     frame()->spellChecker().requestTextChecking(*webElement.constUnwrap<Element>());
1129 }
1130 
replaceMisspelledRange(const WebString & text)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 
removeSpellingMarkers()1149 void WebLocalFrameImpl::removeSpellingMarkers()
1150 {
1151     frame()->document()->markers().removeMarkers(DocumentMarker::MisspellingMarkers());
1152 }
1153 
hasSelection() const1154 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 
selectionRange() const1164 WebRange WebLocalFrameImpl::selectionRange() const
1165 {
1166     return frame()->selection().toNormalizedRange();
1167 }
1168 
selectionAsText() const1169 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 
selectionAsMarkup() const1187 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 
selectWordAroundPosition(LocalFrame * frame,VisiblePosition position)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 
selectWordAroundCaret()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 
selectRange(const WebPoint & base,const WebPoint & extent)1218 void WebLocalFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent)
1219 {
1220     moveRangeSelection(base, extent);
1221 }
1222 
selectRange(const WebRange & webRange)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 
moveRangeSelection(const WebPoint & base,const WebPoint & extent)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 
moveCaretSelection(const WebPoint & point)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 
setEditableSelectionOffsets(int start,int end)1247 bool WebLocalFrameImpl::setEditableSelectionOffsets(int start, int end)
1248 {
1249     return frame()->inputMethodController().setEditableSelectionOffsets(PlainTextRange(start, end));
1250 }
1251 
setCompositionFromExistingText(int compositionStart,int compositionEnd,const WebVector<WebCompositionUnderline> & underlines)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 
extendSelectionAndDelete(int before,int after)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 
setCaretVisible(bool visible)1277 void WebLocalFrameImpl::setCaretVisible(bool visible)
1278 {
1279     frame()->selection().setCaretVisible(visible);
1280 }
1281 
visiblePositionForWindowPoint(const WebPoint & point)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 
focusedPluginIfInputMethodSupported()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 
printBegin(const WebPrintParams & printParams,const WebNode & constrainToNode)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 
getPrintPageShrink(int page)1336 float WebLocalFrameImpl::getPrintPageShrink(int page)
1337 {
1338     ASSERT(m_printContext && page >= 0);
1339     return m_printContext->getPageShrink(page);
1340 }
1341 
printPage(int page,WebCanvas * canvas)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 
printEnd()1355 void WebLocalFrameImpl::printEnd()
1356 {
1357     ASSERT(m_printContext);
1358     m_printContext->end();
1359     m_printContext.clear();
1360 }
1361 
isPrintScalingDisabledForPlugin(const WebNode & node)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 
hasCustomPageSizeStyle(int pageIndex)1372 bool WebLocalFrameImpl::hasCustomPageSizeStyle(int pageIndex)
1373 {
1374     return frame()->document()->styleForPage(pageIndex)->pageSizeType() != PAGE_SIZE_AUTO;
1375 }
1376 
isPageBoxVisible(int pageIndex)1377 bool WebLocalFrameImpl::isPageBoxVisible(int pageIndex)
1378 {
1379     return frame()->document()->isPageBoxVisible(pageIndex);
1380 }
1381 
pageSizeAndMarginsInPixels(int pageIndex,WebSize & pageSize,int & marginTop,int & marginRight,int & marginBottom,int & marginLeft)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 
pageProperty(const WebString & propertyName,int pageIndex)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 
find(int identifier,const WebString & searchText,const WebFindOptions & options,bool wrapWithinFrame,WebRect * selectionRect)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 
stopFinding(bool clearSelection)1400 void WebLocalFrameImpl::stopFinding(bool clearSelection)
1401 {
1402     if (m_textFinder) {
1403         if (!clearSelection)
1404             setFindEndstateFocusAndSelection();
1405         m_textFinder->stopFindingAndClearSelection();
1406     }
1407 }
1408 
scopeStringMatches(int identifier,const WebString & searchText,const WebFindOptions & options,bool reset)1409 void WebLocalFrameImpl::scopeStringMatches(int identifier, const WebString& searchText, const WebFindOptions& options, bool reset)
1410 {
1411     ensureTextFinder().scopeStringMatches(identifier, searchText, options, reset);
1412 }
1413 
cancelPendingScopingEffort()1414 void WebLocalFrameImpl::cancelPendingScopingEffort()
1415 {
1416     if (m_textFinder)
1417         m_textFinder->cancelPendingScopingEffort();
1418 }
1419 
increaseMatchCount(int count,int identifier)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 
resetMatchCount()1427 void WebLocalFrameImpl::resetMatchCount()
1428 {
1429     ensureTextFinder().resetMatchCount();
1430 }
1431 
sendOrientationChangeEvent()1432 void WebLocalFrameImpl::sendOrientationChangeEvent()
1433 {
1434     if (frame())
1435         frame()->sendOrientationChangeEvent();
1436 }
1437 
dispatchMessageEventWithOriginCheck(const WebSecurityOrigin & intendedTargetOrigin,const WebDOMEvent & event)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 
findMatchMarkersVersion() const1444 int WebLocalFrameImpl::findMatchMarkersVersion() const
1445 {
1446     ASSERT(!parent());
1447 
1448     if (m_textFinder)
1449         return m_textFinder->findMatchMarkersVersion();
1450     return 0;
1451 }
1452 
selectNearestFindMatch(const WebFloatPoint & point,WebRect * selectionRect)1453 int WebLocalFrameImpl::selectNearestFindMatch(const WebFloatPoint& point, WebRect* selectionRect)
1454 {
1455     ASSERT(!parent());
1456     return ensureTextFinder().selectNearestFindMatch(point, selectionRect);
1457 }
1458 
activeFindMatchRect()1459 WebFloatRect WebLocalFrameImpl::activeFindMatchRect()
1460 {
1461     ASSERT(!parent());
1462 
1463     if (m_textFinder)
1464         return m_textFinder->activeFindMatchRect();
1465     return WebFloatRect();
1466 }
1467 
findMatchRects(WebVector<WebFloatRect> & outputRects)1468 void WebLocalFrameImpl::findMatchRects(WebVector<WebFloatRect>& outputRects)
1469 {
1470     ASSERT(!parent());
1471     ensureTextFinder().findMatchRects(outputRects);
1472 }
1473 
setTickmarks(const WebVector<WebRect> & tickmarks)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 
contentAsText(size_t maxChars) const1485 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 
contentAsMarkup() const1494 WebString WebLocalFrameImpl::contentAsMarkup() const
1495 {
1496     if (!frame())
1497         return WebString();
1498     return createFullMarkup(frame()->document());
1499 }
1500 
renderTreeAsText(RenderAsTextControls toShow) const1501 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 
markerTextForListItem(const WebElement & webElement) const1514 WebString WebLocalFrameImpl::markerTextForListItem(const WebElement& webElement) const
1515 {
1516     return WebCore::markerTextForListItem(const_cast<Element*>(webElement.constUnwrap<Element>()));
1517 }
1518 
printPagesWithBoundaries(WebCanvas * canvas,const WebSize & pageSizeInPixels)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 
selectionBoundsRect() const1529 WebRect WebLocalFrameImpl::selectionBoundsRect() const
1530 {
1531     return hasSelection() ? WebRect(IntRect(frame()->selection().bounds(false))) : WebRect();
1532 }
1533 
selectionStartHasSpellingMarkerFor(int from,int length) const1534 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 
layerTreeAsText(bool showDebugInfo) const1541 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 
create(WebFrameClient * client)1551 WebLocalFrame* WebLocalFrame::create(WebFrameClient* client)
1552 {
1553     return WebLocalFrameImpl::create(client);
1554 }
1555 
create(WebFrameClient * client)1556 WebLocalFrameImpl* WebLocalFrameImpl::create(WebFrameClient* client)
1557 {
1558     return adoptRef(new WebLocalFrameImpl(client)).leakRef();
1559 }
1560 
WebLocalFrameImpl(WebFrameClient * client)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 
~WebLocalFrameImpl()1573 WebLocalFrameImpl::~WebLocalFrameImpl()
1574 {
1575     blink::Platform::current()->decrementStatsCounter(webFrameActiveCount);
1576     frameCount--;
1577 
1578     cancelPendingScopingEffort();
1579 }
1580 
setWebCoreFrame(PassRefPtr<WebCore::LocalFrame> frame)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 
initializeAsMainFrame(WebCore::Page * page)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 
createChildFrame(const FrameLoadRequest & request,HTMLFrameOwnerElement * ownerElement)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 
didChangeContentsSize(const IntSize & size)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 
createFrameView()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 
fromFrame(LocalFrame * frame)1676 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame* frame)
1677 {
1678     if (!frame)
1679         return 0;
1680     return fromFrame(*frame);
1681 }
1682 
fromFrame(LocalFrame & frame)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 
fromFrameOwnerElement(Element * element)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 
viewImpl() const1699 WebViewImpl* WebLocalFrameImpl::viewImpl() const
1700 {
1701     if (!frame())
1702         return 0;
1703     return WebViewImpl::fromPage(frame()->page());
1704 }
1705 
dataSourceImpl() const1706 WebDataSourceImpl* WebLocalFrameImpl::dataSourceImpl() const
1707 {
1708     return static_cast<WebDataSourceImpl*>(dataSource());
1709 }
1710 
provisionalDataSourceImpl() const1711 WebDataSourceImpl* WebLocalFrameImpl::provisionalDataSourceImpl() const
1712 {
1713     return static_cast<WebDataSourceImpl*>(provisionalDataSource());
1714 }
1715 
setFindEndstateFocusAndSelection()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 
didFail(const ResourceError & error,bool wasProvisional)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 
setCanHaveScrollbars(bool canHaveScrollbars)1795 void WebLocalFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars)
1796 {
1797     frame()->view()->setCanHaveScrollbars(canHaveScrollbars);
1798 }
1799 
setInputEventsTransformForEmulation(const IntSize & offset,float contentScaleFactor)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 
loadJavaScriptURL(const KURL & url)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 
addStyleSheetByURL(const WebString & url)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 
willDetachParent()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 
activeMatchFrame() const1863 WebLocalFrameImpl* WebLocalFrameImpl::activeMatchFrame() const
1864 {
1865     ASSERT(!parent());
1866 
1867     if (m_textFinder)
1868         return m_textFinder->activeMatchFrame();
1869     return 0;
1870 }
1871 
activeMatch() const1872 WebCore::Range* WebLocalFrameImpl::activeMatch() const
1873 {
1874     if (m_textFinder)
1875         return m_textFinder->activeMatch();
1876     return 0;
1877 }
1878 
ensureTextFinder()1879 TextFinder& WebLocalFrameImpl::ensureTextFinder()
1880 {
1881     if (!m_textFinder)
1882         m_textFinder = TextFinder::create(*this);
1883 
1884     return *m_textFinder;
1885 }
1886 
invalidateScrollbar() const1887 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 
invalidateAll() const1897 void WebLocalFrameImpl::invalidateAll() const
1898 {
1899     ASSERT(frame() && frame()->view());
1900     FrameView* view = frame()->view();
1901     view->invalidateRect(view->frameRect());
1902     invalidateScrollbar();
1903 }
1904 
initializeAsChildFrame(FrameHost * host,FrameOwner * owner,const AtomicString & name,const AtomicString & fallbackName)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