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