2 * Copyright (C) 2009 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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
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.
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.
31 // How ownership works
32 // -------------------
34 // Big oh represents a refcounted relationship: owner O--- ownee
36 // WebView (for the toplevel frame only)
41 // Page O------- LocalFrame (m_mainFrame) O-------O FrameView
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.
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.
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.
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.
67 // How frames are destroyed
68 // ------------------------
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.
73 // When frame content is replaced, all subframes are destroyed. This happens
74 // in Frame::detachChildren for each subframe in a pre-order depth-first
75 // traversal. Note that child node order may not match DOM node order!
76 // detachChildren() (virtually) calls Frame::detach(), which again calls
77 // FrameLoaderClient::detached(). This triggers WebFrame to clear its reference to
78 // LocalFrame. FrameLoaderClient::detached() also notifies the embedder via WebFrameClient
79 // that the frame is detached. Most embedders will invoke close() on the WebFrame
80 // at this point, triggering its deletion unless something else is still retaining a reference.
82 // The client is expected to be set whenever the WebLocalFrameImpl is attached to
86 #include "web/WebLocalFrameImpl.h"
88 #include "bindings/core/v8/BindingSecurity.h"
89 #include "bindings/core/v8/DOMWrapperWorld.h"
90 #include "bindings/core/v8/ExceptionState.h"
91 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
92 #include "bindings/core/v8/ScriptController.h"
93 #include "bindings/core/v8/ScriptSourceCode.h"
94 #include "bindings/core/v8/ScriptValue.h"
95 #include "bindings/core/v8/V8Binding.h"
96 #include "bindings/core/v8/V8GCController.h"
97 #include "bindings/core/v8/V8PerIsolateData.h"
98 #include "core/HTMLNames.h"
99 #include "core/dom/Document.h"
100 #include "core/dom/IconURL.h"
101 #include "core/dom/MessagePort.h"
102 #include "core/dom/Node.h"
103 #include "core/dom/NodeTraversal.h"
104 #include "core/dom/SuspendableTask.h"
105 #include "core/dom/shadow/ShadowRoot.h"
106 #include "core/editing/EditingUtilities.h"
107 #include "core/editing/Editor.h"
108 #include "core/editing/FrameSelection.h"
109 #include "core/editing/InputMethodController.h"
110 #include "core/editing/PlainTextRange.h"
111 #include "core/editing/TextAffinity.h"
112 #include "core/editing/iterators/TextIterator.h"
113 #include "core/editing/serializers/Serialization.h"
114 #include "core/editing/spellcheck/SpellChecker.h"
115 #include "core/fetch/ResourceFetcher.h"
116 #include "core/fetch/SubstituteData.h"
117 #include "core/frame/Console.h"
118 #include "core/frame/LocalDOMWindow.h"
119 #include "core/frame/FrameHost.h"
120 #include "core/frame/FrameView.h"
121 #include "core/frame/Settings.h"
122 #include "core/html/HTMLAnchorElement.h"
123 #include "core/html/HTMLCollection.h"
124 #include "core/html/HTMLFormElement.h"
125 #include "core/html/HTMLFrameElementBase.h"
126 #include "core/html/HTMLFrameOwnerElement.h"
127 #include "core/html/HTMLHeadElement.h"
128 #include "core/html/HTMLImageElement.h"
129 #include "core/html/HTMLInputElement.h"
130 #include "core/html/HTMLLinkElement.h"
131 #include "core/html/PluginDocument.h"
132 #include "core/input/EventHandler.h"
133 #include "core/inspector/ConsoleMessage.h"
134 #include "core/inspector/ScriptCallStack.h"
135 #include "core/layout/HitTestResult.h"
136 #include "core/layout/LayoutBox.h"
137 #include "core/layout/LayoutObject.h"
138 #include "core/layout/LayoutPart.h"
139 #include "core/layout/LayoutTreeAsText.h"
140 #include "core/layout/LayoutView.h"
141 #include "core/style/StyleInheritedData.h"
142 #include "core/loader/DocumentLoader.h"
143 #include "core/loader/FrameLoadRequest.h"
144 #include "core/loader/FrameLoader.h"
145 #include "core/loader/HistoryItem.h"
146 #include "core/loader/MixedContentChecker.h"
147 #include "core/loader/NavigationScheduler.h"
148 #include "core/page/FocusController.h"
149 #include "core/page/FrameTree.h"
150 #include "core/page/Page.h"
151 #include "core/page/PrintContext.h"
152 #include "core/paint/DeprecatedPaintLayer.h"
153 #include "core/paint/ScopeRecorder.h"
154 #include "core/paint/TransformRecorder.h"
155 #include "core/timing/DOMWindowPerformance.h"
156 #include "core/timing/Performance.h"
157 #include "modules/app_banner/AppBannerController.h"
158 #include "modules/bluetooth/BluetoothSupplement.h"
159 #include "modules/geolocation/GeolocationController.h"
160 #include "modules/notifications/NotificationPermissionClient.h"
161 #include "modules/permissions/PermissionController.h"
162 #include "modules/presentation/PresentationController.h"
163 #include "modules/push_messaging/PushController.h"
164 #include "modules/screen_orientation/ScreenOrientationController.h"
165 #include "modules/vr/VRController.h"
166 #include "modules/wake_lock/ScreenWakeLock.h"
167 #include "modules/webusb/USBController.h"
168 #include "platform/ScriptForbiddenScope.h"
169 #include "platform/TraceEvent.h"
170 #include "platform/UserGestureIndicator.h"
171 #include "platform/clipboard/ClipboardUtilities.h"
172 #include "platform/fonts/FontCache.h"
173 #include "platform/graphics/GraphicsContext.h"
174 #include "platform/graphics/GraphicsLayerClient.h"
175 #include "platform/graphics/paint/ClipRecorder.h"
176 #include "platform/graphics/paint/DrawingRecorder.h"
177 #include "platform/graphics/paint/SkPictureBuilder.h"
178 #include "platform/graphics/skia/SkiaUtils.h"
179 #include "platform/heap/Handle.h"
180 #include "platform/network/ResourceRequest.h"
181 #include "platform/scroll/ScrollTypes.h"
182 #include "platform/scroll/ScrollbarTheme.h"
183 #include "platform/weborigin/KURL.h"
184 #include "platform/weborigin/SchemeRegistry.h"
185 #include "platform/weborigin/SecurityPolicy.h"
186 #include "public/platform/Platform.h"
187 #include "public/platform/WebFloatPoint.h"
188 #include "public/platform/WebFloatRect.h"
189 #include "public/platform/WebLayer.h"
190 #include "public/platform/WebPoint.h"
191 #include "public/platform/WebRect.h"
192 #include "public/platform/WebSecurityOrigin.h"
193 #include "public/platform/WebSize.h"
194 #include "public/platform/WebSuspendableTask.h"
195 #include "public/platform/WebURLError.h"
196 #include "public/platform/WebVector.h"
197 #include "public/web/WebAutofillClient.h"
198 #include "public/web/WebConsoleMessage.h"
199 #include "public/web/WebDOMEvent.h"
200 #include "public/web/WebDocument.h"
201 #include "public/web/WebFindOptions.h"
202 #include "public/web/WebFormElement.h"
203 #include "public/web/WebFrameClient.h"
204 #include "public/web/WebHistoryItem.h"
205 #include "public/web/WebIconURL.h"
206 #include "public/web/WebInputElement.h"
207 #include "public/web/WebKit.h"
208 #include "public/web/WebNode.h"
209 #include "public/web/WebPerformance.h"
210 #include "public/web/WebPlugin.h"
211 #include "public/web/WebPrintParams.h"
212 #include "public/web/WebPrintPresetOptions.h"
213 #include "public/web/WebRange.h"
214 #include "public/web/WebScriptSource.h"
215 #include "public/web/WebSerializedScriptValue.h"
216 #include "public/web/WebTestInterfaceFactory.h"
217 #include "public/web/WebTreeScopeType.h"
218 #include "skia/ext/platform_device.h"
219 #include "web/AssociatedURLLoader.h"
220 #include "web/CompositionUnderlineVectorBuilder.h"
221 #include "web/FindInPageCoordinates.h"
222 #include "web/GeolocationClientProxy.h"
223 #include "web/LocalFileSystemClient.h"
224 #include "web/MIDIClientProxy.h"
225 #include "web/NavigatorContentUtilsClientImpl.h"
226 #include "web/NotificationPermissionClientImpl.h"
227 #include "web/RemoteBridgeFrameOwner.h"
228 #include "web/SharedWorkerRepositoryClientImpl.h"
229 #include "web/SuspendableScriptExecutor.h"
230 #include "web/TextFinder.h"
231 #include "web/WebDataSourceImpl.h"
232 #include "web/WebDevToolsAgentImpl.h"
233 #include "web/WebFrameWidgetImpl.h"
234 #include "web/WebPluginContainerImpl.h"
235 #include "web/WebRemoteFrameImpl.h"
236 #include "web/WebViewImpl.h"
237 #include "wtf/CurrentTime.h"
238 #include "wtf/HashMap.h"
243 static int frameCount
= 0;
245 // Key for a StatsCounter tracking how many WebFrames are active.
246 static const char webFrameActiveCount
[] = "WebFrameActiveCount";
248 static void frameContentAsPlainText(size_t maxChars
, LocalFrame
* frame
, StringBuilder
& output
)
250 Document
* document
= frame
->document();
257 // Select the document body.
258 if (document
->body()) {
259 const EphemeralRange range
= EphemeralRange::rangeOfContents(*document
->body());
261 // The text iterator will walk nodes giving us text. This is similar to
262 // the plainText() function in core/editing/TextIterator.h, but we implement the maximum
263 // size and also copy the results directly into a wstring, avoiding the
264 // string conversion.
265 for (TextIterator
it(range
.startPosition(), range
.endPosition()); !it
.atEnd(); it
.advance()) {
266 it
.text().appendTextToStringBuilder(output
, 0, maxChars
- output
.length());
267 if (output
.length() >= maxChars
)
268 return; // Filled up the buffer.
272 // The separator between frames when the frames are converted to plain text.
273 const LChar frameSeparator
[] = { '\n', '\n' };
274 const size_t frameSeparatorLength
= WTF_ARRAY_LENGTH(frameSeparator
);
276 // Recursively walk the children.
277 const FrameTree
& frameTree
= frame
->tree();
278 for (Frame
* curChild
= frameTree
.firstChild(); curChild
; curChild
= curChild
->tree().nextSibling()) {
279 if (!curChild
->isLocalFrame())
281 LocalFrame
* curLocalChild
= toLocalFrame(curChild
);
282 // Ignore the text of non-visible frames.
283 LayoutView
* contentLayoutObject
= curLocalChild
->contentLayoutObject();
284 LayoutPart
* ownerLayoutObject
= curLocalChild
->ownerLayoutObject();
285 if (!contentLayoutObject
|| !contentLayoutObject
->size().width() || !contentLayoutObject
->size().height()
286 || (contentLayoutObject
->location().x() + contentLayoutObject
->size().width() <= 0) || (contentLayoutObject
->location().y() + contentLayoutObject
->size().height() <= 0)
287 || (ownerLayoutObject
&& ownerLayoutObject
->style() && ownerLayoutObject
->style()->visibility() != VISIBLE
)) {
291 // Make sure the frame separator won't fill up the buffer, and give up if
292 // it will. The danger is if the separator will make the buffer longer than
293 // maxChars. This will cause the computation above:
294 // maxChars - output->size()
295 // to be a negative number which will crash when the subframe is added.
296 if (output
.length() >= maxChars
- frameSeparatorLength
)
299 output
.append(frameSeparator
, frameSeparatorLength
);
300 frameContentAsPlainText(maxChars
, curLocalChild
, output
);
301 if (output
.length() >= maxChars
)
302 return; // Filled up the buffer.
306 static WillBeHeapVector
<ScriptSourceCode
> createSourcesVector(const WebScriptSource
* sourcesIn
, unsigned numSources
)
308 WillBeHeapVector
<ScriptSourceCode
> sources
;
309 sources
.append(sourcesIn
, numSources
);
313 WebPluginContainerImpl
* WebLocalFrameImpl::pluginContainerFromFrame(LocalFrame
* frame
)
317 if (!frame
->document() || !frame
->document()->isPluginDocument())
319 PluginDocument
* pluginDocument
= toPluginDocument(frame
->document());
320 return toWebPluginContainerImpl(pluginDocument
->pluginWidget());
323 WebPluginContainerImpl
* WebLocalFrameImpl::pluginContainerFromNode(LocalFrame
* frame
, const WebNode
& node
)
325 WebPluginContainerImpl
* pluginContainer
= pluginContainerFromFrame(frame
);
327 return pluginContainer
;
328 return toWebPluginContainerImpl(node
.pluginContainer());
331 // Simple class to override some of PrintContext behavior. Some of the methods
332 // made virtual so that they can be overridden by ChromePluginPrintContext.
333 class ChromePrintContext
: public PrintContext
{
334 WTF_MAKE_NONCOPYABLE(ChromePrintContext
);
336 ChromePrintContext(LocalFrame
* frame
)
337 : PrintContext(frame
)
338 , m_printedPageWidth(0)
342 ~ChromePrintContext() override
{}
344 virtual void begin(float width
, float height
)
346 ASSERT(!m_printedPageWidth
);
347 m_printedPageWidth
= width
;
348 PrintContext::begin(m_printedPageWidth
, height
);
351 virtual float getPageShrink(int pageNumber
) const
353 IntRect pageRect
= m_pageRects
[pageNumber
];
354 return m_printedPageWidth
/ pageRect
.width();
357 float spoolSinglePage(WebCanvas
* canvas
, int pageNumber
)
359 dispatchEventsForPrintingOnAllFrames();
360 if (!frame()->document() || !frame()->document()->layoutView())
363 frame()->view()->updateAllLifecyclePhases();
364 if (!frame()->document() || !frame()->document()->layoutView())
367 IntRect pageRect
= m_pageRects
[pageNumber
];
368 SkPictureBuilder
pictureBuilder(pageRect
, &skia::getMetaData(*canvas
));
369 pictureBuilder
.context().setPrinting(true);
371 float scale
= spoolPage(pictureBuilder
.context(), pageNumber
);
372 pictureBuilder
.endRecording()->playback(canvas
);
373 outputLinkedDestinations(canvas
, pageRect
);
377 void spoolAllPagesWithBoundaries(WebCanvas
* canvas
, const FloatSize
& pageSizeInPixels
)
379 dispatchEventsForPrintingOnAllFrames();
380 if (!frame()->document() || !frame()->document()->layoutView())
383 frame()->view()->updateAllLifecyclePhases();
384 if (!frame()->document() || !frame()->document()->layoutView())
388 computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels
), 0, 0, 1, pageHeight
);
390 const float pageWidth
= pageSizeInPixels
.width();
391 size_t numPages
= pageRects().size();
392 int totalHeight
= numPages
* (pageSizeInPixels
.height() + 1) - 1;
393 IntRect
allPagesRect(0, 0, pageWidth
, totalHeight
);
395 SkPictureBuilder
pictureBuilder(allPagesRect
, &skia::getMetaData(*canvas
));
396 pictureBuilder
.context().setPrinting(true);
398 GraphicsContext
& context
= pictureBuilder
.context();
400 // Fill the whole background by white.
401 if (!DrawingRecorder::useCachedDrawingIfPossible(context
, *this, DisplayItem::PrintedContentBackground
)) {
402 DrawingRecorder
backgroundRecorder(context
, *this, DisplayItem::PrintedContentBackground
, allPagesRect
);
403 context
.fillRect(FloatRect(0, 0, pageWidth
, totalHeight
), Color::white
);
406 int currentHeight
= 0;
407 for (size_t pageIndex
= 0; pageIndex
< numPages
; pageIndex
++) {
408 ScopeRecorder
scopeRecorder(context
);
409 // Draw a line for a page boundary if this isn't the first page.
410 if (pageIndex
> 0 && !DrawingRecorder::useCachedDrawingIfPossible(context
, *this, DisplayItem::PrintedContentLineBoundary
)) {
411 DrawingRecorder
lineBoundaryRecorder(context
, *this, DisplayItem::PrintedContentLineBoundary
, allPagesRect
);
413 context
.setStrokeColor(Color(0, 0, 255));
414 context
.setFillColor(Color(0, 0, 255));
415 context
.drawLine(IntPoint(0, currentHeight
), IntPoint(pageWidth
, currentHeight
));
419 AffineTransform transform
;
420 transform
.translate(0, currentHeight
);
421 #if OS(WIN) || OS(MACOSX)
422 // Account for the disabling of scaling in spoolPage. In the context
423 // of spoolAllPagesWithBoundaries the scale HAS NOT been pre-applied.
424 float scale
= getPageShrink(pageIndex
);
425 transform
.scale(scale
, scale
);
427 TransformRecorder
transformRecorder(context
, *this, transform
);
428 spoolPage(context
, pageIndex
);
430 currentHeight
+= pageSizeInPixels
.height() + 1;
432 pictureBuilder
.endRecording()->playback(canvas
);
433 outputLinkedDestinations(canvas
, allPagesRect
);
436 DisplayItemClient
displayItemClient() const { return toDisplayItemClient(this); }
438 String
debugName() const { return "ChromePrintContext"; }
441 // Spools the printed page, a subrect of frame(). Skip the scale step.
442 // NativeTheme doesn't play well with scaling. Scaling is done browser side
443 // instead. Returns the scale to be applied.
444 // On Linux, we don't have the problem with NativeTheme, hence we let WebKit
445 // do the scaling and ignore the return value.
446 virtual float spoolPage(GraphicsContext
& context
, int pageNumber
)
448 IntRect pageRect
= m_pageRects
[pageNumber
];
449 float scale
= m_printedPageWidth
/ pageRect
.width();
451 AffineTransform transform
;
452 #if OS(POSIX) && !OS(MACOSX)
453 transform
.scale(scale
);
455 transform
.translate(static_cast<float>(-pageRect
.x()), static_cast<float>(-pageRect
.y()));
456 TransformRecorder
transformRecorder(context
, *this, transform
);
458 ClipRecorder
clipRecorder(context
, *this, DisplayItem::ClipPrintedPage
, LayoutRect(pageRect
));
460 frame()->view()->paintContents(&context
, GlobalPaintNormalPhase
, pageRect
);
466 void dispatchEventsForPrintingOnAllFrames()
468 WillBeHeapVector
<RefPtrWillBeMember
<Document
>> documents
;
469 for (Frame
* currentFrame
= frame(); currentFrame
; currentFrame
= currentFrame
->tree().traverseNext(frame())) {
470 if (currentFrame
->isLocalFrame())
471 documents
.append(toLocalFrame(currentFrame
)->document());
474 for (auto& doc
: documents
)
475 doc
->dispatchEventsForPrinting();
478 // Set when printing.
479 float m_printedPageWidth
;
482 // Simple class to override some of PrintContext behavior. This is used when
483 // the frame hosts a plugin that supports custom printing. In this case, we
484 // want to delegate all printing related calls to the plugin.
485 class ChromePluginPrintContext final
: public ChromePrintContext
{
487 ChromePluginPrintContext(LocalFrame
* frame
, WebPluginContainerImpl
* plugin
, const WebPrintParams
& printParams
)
488 : ChromePrintContext(frame
), m_plugin(plugin
), m_printParams(printParams
)
492 ~ChromePluginPrintContext() override
{}
494 DEFINE_INLINE_VIRTUAL_TRACE()
496 visitor
->trace(m_plugin
);
497 ChromePrintContext::trace(visitor
);
500 void begin(float width
, float height
) override
506 m_plugin
->printEnd();
509 float getPageShrink(int pageNumber
) const override
511 // We don't shrink the page (maybe we should ask the widget ??)
515 void computePageRects(const FloatRect
& printRect
, float headerHeight
, float footerHeight
, float userScaleFactor
, float& outPageHeight
) override
517 m_printParams
.printContentArea
= IntRect(printRect
);
518 m_pageRects
.fill(IntRect(printRect
), m_plugin
->printBegin(m_printParams
));
521 void computePageRectsWithPageSize(const FloatSize
& pageSizeInPixels
) override
523 ASSERT_NOT_REACHED();
527 // Spools the printed page, a subrect of frame(). Skip the scale step.
528 // NativeTheme doesn't play well with scaling. Scaling is done browser side
529 // instead. Returns the scale to be applied.
530 float spoolPage(GraphicsContext
& context
, int pageNumber
) override
532 IntRect pageRect
= m_pageRects
[pageNumber
];
533 m_plugin
->printPage(pageNumber
, &context
, pageRect
);
539 // Set when printing.
540 RawPtrWillBeMember
<WebPluginContainerImpl
> m_plugin
;
541 WebPrintParams m_printParams
;
544 static WebDataSource
* DataSourceForDocLoader(DocumentLoader
* loader
)
546 return loader
? WebDataSourceImpl::fromDocumentLoader(loader
) : 0;
549 // WebSuspendableTaskWrapper --------------------------------------------------
551 class WebSuspendableTaskWrapper
: public SuspendableTask
{
553 static PassOwnPtr
<WebSuspendableTaskWrapper
> create(PassOwnPtr
<WebSuspendableTask
> task
)
555 return adoptPtr(new WebSuspendableTaskWrapper(task
));
563 void contextDestroyed() override
565 m_task
->contextDestroyed();
569 explicit WebSuspendableTaskWrapper(PassOwnPtr
<WebSuspendableTask
> task
)
574 OwnPtr
<WebSuspendableTask
> m_task
;
577 // WebFrame -------------------------------------------------------------------
579 int WebFrame::instanceCount()
584 WebLocalFrame
* WebLocalFrame::frameForCurrentContext()
586 v8::Local
<v8::Context
> context
= v8::Isolate::GetCurrent()->GetCurrentContext();
587 if (context
.IsEmpty())
589 return frameForContext(context
);
592 WebLocalFrame
* WebLocalFrame::frameForContext(v8::Local
<v8::Context
> context
)
594 return WebLocalFrameImpl::fromFrame(toLocalFrame(toFrameIfNotDetached(context
)));
597 WebLocalFrame
* WebLocalFrame::fromFrameOwnerElement(const WebElement
& element
)
599 return WebLocalFrameImpl::fromFrameOwnerElement(PassRefPtrWillBeRawPtr
<Element
>(element
).get());
602 bool WebLocalFrameImpl::isWebLocalFrame() const
607 WebLocalFrame
* WebLocalFrameImpl::toWebLocalFrame()
612 bool WebLocalFrameImpl::isWebRemoteFrame() const
617 WebRemoteFrame
* WebLocalFrameImpl::toWebRemoteFrame()
619 ASSERT_NOT_REACHED();
623 void WebLocalFrameImpl::close()
627 if (m_devToolsAgent
) {
628 m_devToolsAgent
->dispose();
629 m_devToolsAgent
.clear();
633 m_selfKeepAlive
.clear();
635 deref(); // Balances ref() acquired in WebFrame::create
639 WebString
WebLocalFrameImpl::uniqueName() const
641 return frame()->tree().uniqueName();
644 WebString
WebLocalFrameImpl::assignedName() const
646 return frame()->tree().name();
649 void WebLocalFrameImpl::setName(const WebString
& name
)
651 frame()->tree().setName(name
);
654 WebVector
<WebIconURL
> WebLocalFrameImpl::iconURLs(int iconTypesMask
) const
656 // The URL to the icon may be in the header. As such, only
657 // ask the loader for the icon if it's finished loading.
658 if (frame()->document()->loadEventFinished())
659 return frame()->document()->iconURLs(iconTypesMask
);
660 return WebVector
<WebIconURL
>();
663 void WebLocalFrameImpl::setRemoteWebLayer(WebLayer
* webLayer
)
665 ASSERT_NOT_REACHED();
668 void WebLocalFrameImpl::setContentSettingsClient(WebContentSettingsClient
* contentSettingsClient
)
670 m_contentSettingsClient
= contentSettingsClient
;
673 void WebLocalFrameImpl::setSharedWorkerRepositoryClient(WebSharedWorkerRepositoryClient
* client
)
675 m_sharedWorkerRepositoryClient
= SharedWorkerRepositoryClientImpl::create(client
);
678 ScrollableArea
* WebLocalFrameImpl::layoutViewportScrollableArea() const
680 if (FrameView
* view
= frameView())
681 return view
->layoutViewportScrollableArea();
685 WebSize
WebLocalFrameImpl::scrollOffset() const
687 if (ScrollableArea
* scrollableArea
= layoutViewportScrollableArea())
688 return toIntSize(scrollableArea
->scrollPosition());
692 void WebLocalFrameImpl::setScrollOffset(const WebSize
& offset
)
694 if (ScrollableArea
* scrollableArea
= layoutViewportScrollableArea())
695 scrollableArea
->setScrollPosition(IntPoint(offset
.width
, offset
.height
), ProgrammaticScroll
);
698 WebSize
WebLocalFrameImpl::contentsSize() const
700 if (FrameView
* view
= frameView())
701 return view
->contentsSize();
705 bool WebLocalFrameImpl::hasVisibleContent() const
707 if (LayoutPart
* layoutObject
= frame()->ownerLayoutObject()) {
708 if (layoutObject
->style()->visibility() != VISIBLE
)
712 if (FrameView
* view
= frameView())
713 return view
->visibleWidth() > 0 && view
->visibleHeight() > 0;
717 WebRect
WebLocalFrameImpl::visibleContentRect() const
719 if (FrameView
* view
= frameView())
720 return view
->visibleContentRect();
724 bool WebLocalFrameImpl::hasHorizontalScrollbar() const
726 return frame() && frame()->view() && frame()->view()->horizontalScrollbar();
729 bool WebLocalFrameImpl::hasVerticalScrollbar() const
731 return frame() && frame()->view() && frame()->view()->verticalScrollbar();
734 WebView
* WebLocalFrameImpl::view() const
739 void WebLocalFrameImpl::setOpener(WebFrame
* opener
)
741 WebFrame::setOpener(opener
);
743 // TODO(alexmos,dcheng): This should ASSERT(m_frame) once we no longer have
744 // provisional local frames.
745 if (m_frame
&& m_frame
->document())
746 m_frame
->document()->initSecurityContext();
749 WebDocument
WebLocalFrameImpl::document() const
751 if (!frame() || !frame()->document())
752 return WebDocument();
753 return WebDocument(frame()->document());
756 WebPerformance
WebLocalFrameImpl::performance() const
759 return WebPerformance();
760 return WebPerformance(DOMWindowPerformance::performance(*(frame()->domWindow())));
763 bool WebLocalFrameImpl::dispatchBeforeUnloadEvent()
767 return frame()->loader().shouldClose();
770 void WebLocalFrameImpl::dispatchUnloadEvent()
774 frame()->loader().dispatchUnloadEvent();
777 NPObject
* WebLocalFrameImpl::windowObject() const
779 if (!frame() || ScriptForbiddenScope::isScriptForbidden())
781 return frame()->script().windowScriptNPObject();
784 void WebLocalFrameImpl::bindToWindowObject(const WebString
& name
, NPObject
* object
)
786 bindToWindowObject(name
, object
, 0);
789 void WebLocalFrameImpl::bindToWindowObject(const WebString
& name
, NPObject
* object
, void*)
791 if (!frame() || !frame()->script().canExecuteScripts(NotAboutToExecuteScript
))
793 frame()->script().bindToWindowObject(frame(), String(name
), object
);
796 void WebLocalFrameImpl::executeScript(const WebScriptSource
& source
)
799 TextPosition
position(OrdinalNumber::fromOneBasedInt(source
.startLine
), OrdinalNumber::first());
800 v8::HandleScope
handleScope(toIsolate(frame()));
801 frame()->script().executeScriptInMainWorld(ScriptSourceCode(source
.code
, source
.url
, position
));
804 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID
, const WebScriptSource
* sourcesIn
, unsigned numSources
, int extensionGroup
)
807 RELEASE_ASSERT(worldID
> 0);
808 RELEASE_ASSERT(worldID
< EmbedderWorldIdLimit
);
810 WillBeHeapVector
<ScriptSourceCode
> sources
= createSourcesVector(sourcesIn
, numSources
);
811 v8::HandleScope
handleScope(toIsolate(frame()));
812 frame()->script().executeScriptInIsolatedWorld(worldID
, sources
, extensionGroup
, 0);
815 void WebLocalFrameImpl::setIsolatedWorldSecurityOrigin(int worldID
, const WebSecurityOrigin
& securityOrigin
)
818 DOMWrapperWorld::setIsolatedWorldSecurityOrigin(worldID
, securityOrigin
.get());
821 void WebLocalFrameImpl::setIsolatedWorldContentSecurityPolicy(int worldID
, const WebString
& policy
)
824 DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(worldID
, policy
);
827 void WebLocalFrameImpl::setIsolatedWorldHumanReadableName(int worldID
, const WebString
& humanReadableName
)
830 DOMWrapperWorld::setIsolatedWorldHumanReadableName(worldID
, humanReadableName
);
833 void WebLocalFrameImpl::addMessageToConsole(const WebConsoleMessage
& message
)
837 MessageLevel webCoreMessageLevel
;
838 switch (message
.level
) {
839 case WebConsoleMessage::LevelDebug
:
840 webCoreMessageLevel
= DebugMessageLevel
;
842 case WebConsoleMessage::LevelLog
:
843 webCoreMessageLevel
= LogMessageLevel
;
845 case WebConsoleMessage::LevelWarning
:
846 webCoreMessageLevel
= WarningMessageLevel
;
848 case WebConsoleMessage::LevelError
:
849 webCoreMessageLevel
= ErrorMessageLevel
;
852 ASSERT_NOT_REACHED();
856 frame()->document()->addConsoleMessage(ConsoleMessage::create(OtherMessageSource
, webCoreMessageLevel
, message
.text
));
859 void WebLocalFrameImpl::collectGarbage()
863 if (!frame()->settings()->scriptEnabled())
865 V8GCController::collectGarbage(v8::Isolate::GetCurrent());
868 bool WebLocalFrameImpl::checkIfRunInsecureContent(const WebURL
& url
) const
872 // This is only called (eventually, through proxies and delegates and IPC) from
873 // PluginURLFetcher::OnReceivedRedirect for redirects of NPAPI resources.
875 // FIXME: Remove this method entirely once we smother NPAPI.
876 return !MixedContentChecker::shouldBlockFetch(frame(), WebURLRequest::RequestContextObject
, WebURLRequest::FrameTypeNested
, url
);
879 v8::Local
<v8::Value
> WebLocalFrameImpl::executeScriptAndReturnValue(const WebScriptSource
& source
)
883 TextPosition
position(OrdinalNumber::fromOneBasedInt(source
.startLine
), OrdinalNumber::first());
884 return frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source
.code
, source
.url
, position
));
887 void WebLocalFrameImpl::requestExecuteScriptAndReturnValue(const WebScriptSource
& source
, bool userGesture
, WebScriptExecutionCallback
* callback
)
891 SuspendableScriptExecutor::createAndRun(frame(), 0, createSourcesVector(&source
, 1), 0, userGesture
, callback
);
894 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID
, const WebScriptSource
* sourcesIn
, unsigned numSources
, int extensionGroup
, WebVector
<v8::Local
<v8::Value
>>* results
)
897 RELEASE_ASSERT(worldID
> 0);
898 RELEASE_ASSERT(worldID
< EmbedderWorldIdLimit
);
900 WillBeHeapVector
<ScriptSourceCode
> sources
= createSourcesVector(sourcesIn
, numSources
);
903 Vector
<v8::Local
<v8::Value
>> scriptResults
;
904 frame()->script().executeScriptInIsolatedWorld(worldID
, sources
, extensionGroup
, &scriptResults
);
905 WebVector
<v8::Local
<v8::Value
>> v8Results(scriptResults
.size());
906 for (unsigned i
= 0; i
< scriptResults
.size(); i
++)
907 v8Results
[i
] = v8::Local
<v8::Value
>::New(toIsolate(frame()), scriptResults
[i
]);
908 results
->swap(v8Results
);
910 v8::HandleScope
handleScope(toIsolate(frame()));
911 frame()->script().executeScriptInIsolatedWorld(worldID
, sources
, extensionGroup
, 0);
915 void WebLocalFrameImpl::requestExecuteScriptInIsolatedWorld(int worldID
, const WebScriptSource
* sourcesIn
, unsigned numSources
, int extensionGroup
, bool userGesture
, WebScriptExecutionCallback
* callback
)
918 RELEASE_ASSERT(worldID
> 0);
919 RELEASE_ASSERT(worldID
< EmbedderWorldIdLimit
);
921 SuspendableScriptExecutor::createAndRun(frame(), worldID
, createSourcesVector(sourcesIn
, numSources
), extensionGroup
, userGesture
, callback
);
924 // TODO(bashi): Consider returning MaybeLocal.
925 v8::Local
<v8::Value
> WebLocalFrameImpl::callFunctionEvenIfScriptDisabled(v8::Local
<v8::Function
> function
, v8::Local
<v8::Value
> receiver
, int argc
, v8::Local
<v8::Value
> argv
[])
928 v8::Local
<v8::Value
> result
;
929 if (!frame()->script().callFunction(function
, receiver
, argc
, static_cast<v8::Local
<v8::Value
>*>(argv
)).ToLocal(&result
))
930 return v8::Local
<v8::Value
>();
934 v8::Local
<v8::Context
> WebLocalFrameImpl::mainWorldScriptContext() const
936 ScriptState
* scriptState
= ScriptState::forMainWorld(frame());
937 ASSERT(scriptState
->contextIsValid());
938 return scriptState
->context();
941 bool WebFrame::scriptCanAccess(WebFrame
* target
)
943 return BindingSecurity::shouldAllowAccessToFrame(mainThreadIsolate(), toCoreFrame(target
), DoNotReportSecurityError
);
946 void WebLocalFrameImpl::reload(bool ignoreCache
)
948 // TODO(clamy): Remove this function once RenderFrame calls load for all
950 reloadWithOverrideURL(KURL(), ignoreCache
);
953 void WebLocalFrameImpl::reloadWithOverrideURL(const WebURL
& overrideUrl
, bool ignoreCache
)
955 // TODO(clamy): Remove this function once RenderFrame calls load for all
958 WebFrameLoadType loadType
= ignoreCache
?
959 WebFrameLoadType::ReloadFromOrigin
: WebFrameLoadType::Reload
;
960 WebURLRequest request
= requestForReload(loadType
, overrideUrl
);
961 if (request
.isNull())
963 load(request
, loadType
, WebHistoryItem(), WebHistoryDifferentDocumentLoad
);
966 void WebLocalFrameImpl::reloadImage(const WebNode
& webNode
)
968 const Node
* node
= webNode
.constUnwrap
<Node
>();
969 if (isHTMLImageElement(*node
)) {
970 const HTMLImageElement
& imageElement
= toHTMLImageElement(*node
);
971 imageElement
.forceReload();
975 void WebLocalFrameImpl::loadRequest(const WebURLRequest
& request
)
977 // TODO(clamy): Remove this function once RenderFrame calls load for all
979 load(request
, WebFrameLoadType::Standard
, WebHistoryItem(), WebHistoryDifferentDocumentLoad
);
982 void WebLocalFrameImpl::loadHistoryItem(const WebHistoryItem
& item
, WebHistoryLoadType loadType
,
983 WebURLRequest::CachePolicy cachePolicy
)
985 // TODO(clamy): Remove this function once RenderFrame calls load for all
987 WebURLRequest request
= requestFromHistoryItem(item
, cachePolicy
);
988 load(request
, WebFrameLoadType::BackForward
, item
, loadType
);
991 void WebLocalFrameImpl::loadData(const WebData
& data
, const WebString
& mimeType
, const WebString
& textEncoding
, const WebURL
& baseURL
, const WebURL
& unreachableURL
, bool replace
)
995 // If we are loading substitute data to replace an existing load, then
996 // inherit all of the properties of that original request. This way,
997 // reload will re-attempt the original request. It is essential that
998 // we only do this when there is an unreachableURL since a non-empty
999 // unreachableURL informs FrameLoader::reload to load unreachableURL
1000 // instead of the currently loaded URL.
1001 ResourceRequest request
;
1002 if (replace
&& !unreachableURL
.isEmpty() && frame()->loader().provisionalDocumentLoader())
1003 request
= frame()->loader().provisionalDocumentLoader()->originalRequest();
1004 request
.setURL(baseURL
);
1005 request
.setCheckForBrowserSideNavigation(false);
1007 FrameLoadRequest
frameRequest(0, request
, SubstituteData(data
, mimeType
, textEncoding
, unreachableURL
));
1008 ASSERT(frameRequest
.substituteData().isValid());
1009 frameRequest
.setReplacesCurrentItem(replace
);
1010 frame()->loader().load(frameRequest
);
1013 void WebLocalFrameImpl::loadHTMLString(const WebData
& data
, const WebURL
& baseURL
, const WebURL
& unreachableURL
, bool replace
)
1016 loadData(data
, WebString::fromUTF8("text/html"), WebString::fromUTF8("UTF-8"), baseURL
, unreachableURL
, replace
);
1019 void WebLocalFrameImpl::stopLoading()
1023 // FIXME: Figure out what we should really do here. It seems like a bug
1024 // that FrameLoader::stopLoading doesn't call stopAllLoaders.
1025 frame()->loader().stopAllLoaders();
1028 WebDataSource
* WebLocalFrameImpl::provisionalDataSource() const
1032 // We regard the policy document loader as still provisional.
1033 DocumentLoader
* documentLoader
= frame()->loader().provisionalDocumentLoader();
1034 if (!documentLoader
)
1035 documentLoader
= frame()->loader().policyDocumentLoader();
1037 return DataSourceForDocLoader(documentLoader
);
1040 WebDataSource
* WebLocalFrameImpl::dataSource() const
1043 return DataSourceForDocLoader(frame()->loader().documentLoader());
1046 void WebLocalFrameImpl::enableViewSourceMode(bool enable
)
1049 frame()->setInViewSourceMode(enable
);
1052 bool WebLocalFrameImpl::isViewSourceModeEnabled() const
1056 return frame()->inViewSourceMode();
1059 void WebLocalFrameImpl::setReferrerForRequest(WebURLRequest
& request
, const WebURL
& referrerURL
)
1061 String referrer
= referrerURL
.isEmpty() ? frame()->document()->outgoingReferrer() : String(referrerURL
.spec().utf16());
1062 request
.toMutableResourceRequest().setHTTPReferrer(SecurityPolicy::generateReferrer(frame()->document()->referrerPolicy(), request
.url(), referrer
));
1065 void WebLocalFrameImpl::dispatchWillSendRequest(WebURLRequest
& request
)
1067 ResourceResponse response
;
1068 frame()->loader().client()->dispatchWillSendRequest(0, 0, request
.toMutableResourceRequest(), response
);
1071 WebURLLoader
* WebLocalFrameImpl::createAssociatedURLLoader(const WebURLLoaderOptions
& options
)
1073 return new AssociatedURLLoader(this, options
);
1076 unsigned WebLocalFrameImpl::unloadListenerCount() const
1078 return frame()->localDOMWindow()->pendingUnloadEventListeners();
1081 void WebLocalFrameImpl::replaceSelection(const WebString
& text
)
1083 bool selectReplacement
= false;
1084 bool smartReplace
= true;
1085 frame()->editor().replaceSelectionWithText(text
, selectReplacement
, smartReplace
);
1088 void WebLocalFrameImpl::insertText(const WebString
& text
)
1090 if (frame()->inputMethodController().hasComposition())
1091 frame()->inputMethodController().confirmComposition(text
);
1093 frame()->editor().insertText(text
, 0);
1096 void WebLocalFrameImpl::setMarkedText(const WebString
& text
, unsigned location
, unsigned length
)
1098 Vector
<CompositionUnderline
> decorations
;
1099 frame()->inputMethodController().setComposition(text
, decorations
, location
, length
);
1102 void WebLocalFrameImpl::unmarkText()
1104 frame()->inputMethodController().cancelComposition();
1107 bool WebLocalFrameImpl::hasMarkedText() const
1109 return frame()->inputMethodController().hasComposition();
1112 WebRange
WebLocalFrameImpl::markedRange() const
1114 return frame()->inputMethodController().compositionRange();
1117 bool WebLocalFrameImpl::firstRectForCharacterRange(unsigned location
, unsigned length
, WebRect
& rectInViewport
) const
1119 if ((location
+ length
< location
) && (location
+ length
))
1122 Element
* editable
= frame()->selection().rootEditableElementOrDocumentElement();
1125 const EphemeralRange range
= PlainTextRange(location
, location
+ length
).createRange(*editable
);
1128 IntRect intRect
= frame()->editor().firstRectForRange(range
);
1129 rectInViewport
= WebRect(intRect
);
1130 rectInViewport
= frame()->view()->contentsToViewport(rectInViewport
);
1134 size_t WebLocalFrameImpl::characterIndexForPoint(const WebPoint
& pointInViewport
) const
1139 IntPoint point
= frame()->view()->viewportToContents(pointInViewport
);
1140 HitTestResult result
= frame()->eventHandler().hitTestResultAtPoint(point
, HitTestRequest::ReadOnly
| HitTestRequest::Active
);
1141 const EphemeralRange range
= frame()->rangeForPoint(result
.roundedPointInInnerNodeFrame());
1144 Element
* editable
= frame()->selection().rootEditableElementOrDocumentElement();
1146 return PlainTextRange::create(*editable
, range
).start();
1149 bool WebLocalFrameImpl::executeCommand(const WebString
& name
, const WebNode
& node
)
1153 if (name
.length() <= 2)
1156 // Since we don't have NSControl, we will convert the format of command
1157 // string and call the function on Editor directly.
1158 String command
= name
;
1160 // Make sure the first letter is upper case.
1161 command
.replace(0, 1, command
.substring(0, 1).upper());
1163 // Remove the trailing ':' if existing.
1164 if (command
[command
.length() - 1] == UChar(':'))
1165 command
= command
.substring(0, command
.length() - 1);
1167 WebPluginContainerImpl
* pluginContainer
= pluginContainerFromNode(frame(), node
);
1168 if (pluginContainer
&& pluginContainer
->executeEditCommand(name
))
1171 return frame()->editor().executeCommand(command
);
1174 bool WebLocalFrameImpl::executeCommand(const WebString
& name
, const WebString
& value
, const WebNode
& node
)
1178 WebPluginContainerImpl
* pluginContainer
= pluginContainerFromNode(frame(), node
);
1179 if (pluginContainer
&& pluginContainer
->executeEditCommand(name
, value
))
1182 return frame()->editor().executeCommand(name
, value
);
1185 bool WebLocalFrameImpl::isCommandEnabled(const WebString
& name
) const
1188 return frame()->editor().command(name
).isEnabled();
1191 void WebLocalFrameImpl::enableContinuousSpellChecking(bool enable
)
1193 if (enable
== isContinuousSpellCheckingEnabled())
1195 frame()->spellChecker().toggleContinuousSpellChecking();
1198 bool WebLocalFrameImpl::isContinuousSpellCheckingEnabled() const
1200 return frame()->spellChecker().isContinuousSpellCheckingEnabled();
1203 void WebLocalFrameImpl::requestTextChecking(const WebElement
& webElement
)
1205 if (webElement
.isNull())
1207 frame()->spellChecker().requestTextChecking(*webElement
.constUnwrap
<Element
>());
1210 void WebLocalFrameImpl::replaceMisspelledRange(const WebString
& text
)
1212 // 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.
1213 if (pluginContainerFromFrame(frame()))
1215 frame()->spellChecker().replaceMisspelledRange(text
);
1218 void WebLocalFrameImpl::removeSpellingMarkers()
1220 frame()->spellChecker().removeSpellingMarkers();
1223 bool WebLocalFrameImpl::hasSelection() const
1225 WebPluginContainerImpl
* pluginContainer
= pluginContainerFromFrame(frame());
1226 if (pluginContainer
)
1227 return pluginContainer
->plugin()->hasSelection();
1229 // frame()->selection()->isNone() never returns true.
1230 return frame()->selection().start() != frame()->selection().end();
1233 WebRange
WebLocalFrameImpl::selectionRange() const
1235 return createRange(frame()->selection().selection().toNormalizedEphemeralRange());
1238 WebString
WebLocalFrameImpl::selectionAsText() const
1240 WebPluginContainerImpl
* pluginContainer
= pluginContainerFromFrame(frame());
1241 if (pluginContainer
)
1242 return pluginContainer
->plugin()->selectionAsText();
1244 const EphemeralRange range
= frame()->selection().selection().toNormalizedEphemeralRange();
1248 String text
= plainText(range
, TextIteratorEmitsObjectReplacementCharacter
);
1250 replaceNewlinesWithWindowsStyleNewlines(text
);
1252 replaceNBSPWithSpace(text
);
1256 WebString
WebLocalFrameImpl::selectionAsMarkup() const
1258 WebPluginContainerImpl
* pluginContainer
= pluginContainerFromFrame(frame());
1259 if (pluginContainer
)
1260 return pluginContainer
->plugin()->selectionAsMarkup();
1262 const EphemeralRange range
= frame()->selection().selection().toNormalizedEphemeralRange();
1266 return createMarkup(range
.startPosition(), range
.endPosition(), AnnotateForInterchange
, ConvertBlocksToInlines::NotConvert
, ResolveNonLocalURLs
);
1269 void WebLocalFrameImpl::selectWordAroundPosition(LocalFrame
* frame
, VisiblePosition position
)
1271 TRACE_EVENT0("blink", "WebLocalFrameImpl::selectWordAroundPosition");
1272 frame
->selection().selectWordAroundPosition(position
);
1275 bool WebLocalFrameImpl::selectWordAroundCaret()
1277 TRACE_EVENT0("blink", "WebLocalFrameImpl::selectWordAroundCaret");
1278 FrameSelection
& selection
= frame()->selection();
1279 if (selection
.isNone() || selection
.isRange())
1281 return frame()->selection().selectWordAroundPosition(selection
.selection().visibleStart());
1284 void WebLocalFrameImpl::selectRange(const WebPoint
& baseInViewport
, const WebPoint
& extentInViewport
)
1286 moveRangeSelection(baseInViewport
, extentInViewport
);
1289 void WebLocalFrameImpl::selectRange(const WebRange
& webRange
)
1291 TRACE_EVENT0("blink", "WebLocalFrameImpl::selectRange");
1292 if (RefPtrWillBeRawPtr
<Range
> range
= static_cast<PassRefPtrWillBeRawPtr
<Range
>>(webRange
))
1293 frame()->selection().setSelectedRange(range
.get(), VP_DEFAULT_AFFINITY
, SelectionDirectionalMode::NonDirectional
, NotUserTriggered
);
1296 void WebLocalFrameImpl::moveRangeSelectionExtent(const WebPoint
& point
)
1298 TRACE_EVENT0("blink", "WebLocalFrameImpl::moveRangeSelectionExtent");
1299 frame()->selection().moveRangeSelectionExtent(frame()->view()->viewportToContents(point
));
1302 void WebLocalFrameImpl::moveRangeSelection(const WebPoint
& baseInViewport
, const WebPoint
& extentInViewport
, WebFrame::TextGranularity granularity
)
1304 TRACE_EVENT0("blink", "WebLocalFrameImpl::moveRangeSelection");
1305 blink::TextGranularity blinkGranularity
= blink::CharacterGranularity
;
1306 if (granularity
== WebFrame::WordGranularity
)
1307 blinkGranularity
= blink::WordGranularity
;
1308 frame()->selection().moveRangeSelection(
1309 visiblePositionForViewportPoint(baseInViewport
),
1310 visiblePositionForViewportPoint(extentInViewport
),
1314 void WebLocalFrameImpl::moveCaretSelection(const WebPoint
& pointInViewport
)
1316 TRACE_EVENT0("blink", "WebLocalFrameImpl::moveCaretSelection");
1317 Element
* editable
= frame()->selection().rootEditableElement();
1321 VisiblePosition position
= visiblePositionForViewportPoint(pointInViewport
);
1322 frame()->selection().moveTo(position
, UserTriggered
);
1325 bool WebLocalFrameImpl::setEditableSelectionOffsets(int start
, int end
)
1327 TRACE_EVENT0("blink", "WebLocalFrameImpl::setEditableSelectionOffsets");
1328 return frame()->inputMethodController().setEditableSelectionOffsets(PlainTextRange(start
, end
));
1331 bool WebLocalFrameImpl::setCompositionFromExistingText(int compositionStart
, int compositionEnd
, const WebVector
<WebCompositionUnderline
>& underlines
)
1333 TRACE_EVENT0("blink", "WebLocalFrameImpl::setCompositionFromExistingText");
1334 if (!frame()->editor().canEdit())
1337 InputMethodController
& inputMethodController
= frame()->inputMethodController();
1338 inputMethodController
.cancelComposition();
1340 if (compositionStart
== compositionEnd
)
1343 inputMethodController
.setCompositionFromExistingText(CompositionUnderlineVectorBuilder(underlines
), compositionStart
, compositionEnd
);
1348 void WebLocalFrameImpl::extendSelectionAndDelete(int before
, int after
)
1350 TRACE_EVENT0("blink", "WebLocalFrameImpl::extendSelectionAndDelete");
1351 if (WebPlugin
* plugin
= focusedPluginIfInputMethodSupported()) {
1352 plugin
->extendSelectionAndDelete(before
, after
);
1355 frame()->inputMethodController().extendSelectionAndDelete(before
, after
);
1358 void WebLocalFrameImpl::setCaretVisible(bool visible
)
1360 frame()->selection().setCaretVisible(visible
);
1363 VisiblePosition
WebLocalFrameImpl::visiblePositionForViewportPoint(const WebPoint
& pointInViewport
)
1365 return visiblePositionForContentsPoint(frame()->view()->viewportToContents(pointInViewport
), frame());
1368 WebPlugin
* WebLocalFrameImpl::focusedPluginIfInputMethodSupported()
1370 WebPluginContainerImpl
* container
= WebLocalFrameImpl::pluginContainerFromNode(frame(), WebNode(frame()->document()->focusedElement()));
1371 if (container
&& container
->supportsInputMethod())
1372 return container
->plugin();
1376 int WebLocalFrameImpl::printBegin(const WebPrintParams
& printParams
, const WebNode
& constrainToNode
)
1378 ASSERT(!frame()->document()->isFrameSet());
1379 WebPluginContainerImpl
* pluginContainer
= nullptr;
1380 if (constrainToNode
.isNull()) {
1381 // If this is a plugin document, check if the plugin supports its own
1382 // printing. If it does, we will delegate all printing to that.
1383 pluginContainer
= pluginContainerFromFrame(frame());
1385 // We only support printing plugin nodes for now.
1386 pluginContainer
= toWebPluginContainerImpl(constrainToNode
.pluginContainer());
1389 if (pluginContainer
&& pluginContainer
->supportsPaginatedPrint())
1390 m_printContext
= adoptPtrWillBeNoop(new ChromePluginPrintContext(frame(), pluginContainer
, printParams
));
1392 m_printContext
= adoptPtrWillBeNoop(new ChromePrintContext(frame()));
1394 FloatRect
rect(0, 0, static_cast<float>(printParams
.printContentArea
.width
), static_cast<float>(printParams
.printContentArea
.height
));
1395 m_printContext
->begin(rect
.width(), rect
.height());
1397 // We ignore the overlays calculation for now since they are generated in the
1398 // browser. pageHeight is actually an output parameter.
1399 m_printContext
->computePageRects(rect
, 0, 0, 1.0, pageHeight
);
1401 return static_cast<int>(m_printContext
->pageCount());
1404 float WebLocalFrameImpl::getPrintPageShrink(int page
)
1406 ASSERT(m_printContext
&& page
>= 0);
1407 return m_printContext
->getPageShrink(page
);
1410 float WebLocalFrameImpl::printPage(int page
, WebCanvas
* canvas
)
1412 #if ENABLE(PRINTING)
1414 ASSERT(m_printContext
&& page
>= 0 && frame() && frame()->document());
1416 return m_printContext
->spoolSinglePage(canvas
, page
);
1422 void WebLocalFrameImpl::printEnd()
1424 ASSERT(m_printContext
);
1425 m_printContext
->end();
1426 m_printContext
.clear();
1429 bool WebLocalFrameImpl::isPrintScalingDisabledForPlugin(const WebNode
& node
)
1431 WebPluginContainerImpl
* pluginContainer
= node
.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node
.pluginContainer());
1433 if (!pluginContainer
|| !pluginContainer
->supportsPaginatedPrint())
1436 return pluginContainer
->isPrintScalingDisabled();
1439 bool WebLocalFrameImpl::getPrintPresetOptionsForPlugin(const WebNode
& node
, WebPrintPresetOptions
* presetOptions
)
1441 WebPluginContainerImpl
* pluginContainer
= node
.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node
.pluginContainer());
1443 if (!pluginContainer
|| !pluginContainer
->supportsPaginatedPrint())
1446 return pluginContainer
->getPrintPresetOptionsFromDocument(presetOptions
);
1449 bool WebLocalFrameImpl::hasCustomPageSizeStyle(int pageIndex
)
1451 return frame()->document()->styleForPage(pageIndex
)->pageSizeType() != PAGE_SIZE_AUTO
;
1454 bool WebLocalFrameImpl::isPageBoxVisible(int pageIndex
)
1456 return frame()->document()->isPageBoxVisible(pageIndex
);
1459 void WebLocalFrameImpl::pageSizeAndMarginsInPixels(int pageIndex
, WebSize
& pageSize
, int& marginTop
, int& marginRight
, int& marginBottom
, int& marginLeft
)
1461 IntSize size
= pageSize
;
1462 frame()->document()->pageSizeAndMarginsInPixels(pageIndex
, size
, marginTop
, marginRight
, marginBottom
, marginLeft
);
1466 WebString
WebLocalFrameImpl::pageProperty(const WebString
& propertyName
, int pageIndex
)
1468 ASSERT(m_printContext
);
1469 return m_printContext
->pageProperty(frame(), propertyName
.utf8().data(), pageIndex
);
1472 bool WebLocalFrameImpl::find(int identifier
, const WebString
& searchText
, const WebFindOptions
& options
, bool wrapWithinFrame
, WebRect
* selectionRect
)
1474 return ensureTextFinder().find(identifier
, searchText
, options
, wrapWithinFrame
, selectionRect
);
1477 void WebLocalFrameImpl::stopFinding(bool clearSelection
)
1480 if (!clearSelection
)
1481 setFindEndstateFocusAndSelection();
1482 m_textFinder
->stopFindingAndClearSelection();
1486 void WebLocalFrameImpl::scopeStringMatches(int identifier
, const WebString
& searchText
, const WebFindOptions
& options
, bool reset
)
1488 ensureTextFinder().scopeStringMatches(identifier
, searchText
, options
, reset
);
1491 void WebLocalFrameImpl::cancelPendingScopingEffort()
1494 m_textFinder
->cancelPendingScopingEffort();
1497 void WebLocalFrameImpl::increaseMatchCount(int count
, int identifier
)
1499 // This function should only be called on the mainframe.
1501 ensureTextFinder().increaseMatchCount(identifier
, count
);
1504 void WebLocalFrameImpl::resetMatchCount()
1506 ensureTextFinder().resetMatchCount();
1509 void WebLocalFrameImpl::dispatchMessageEventWithOriginCheck(const WebSecurityOrigin
& intendedTargetOrigin
, const WebDOMEvent
& event
)
1511 ASSERT(!event
.isNull());
1512 frame()->localDOMWindow()->dispatchMessageEventWithOriginCheck(intendedTargetOrigin
.get(), event
, nullptr);
1515 int WebLocalFrameImpl::findMatchMarkersVersion() const
1520 return m_textFinder
->findMatchMarkersVersion();
1524 int WebLocalFrameImpl::selectNearestFindMatch(const WebFloatPoint
& point
, WebRect
* selectionRect
)
1527 return ensureTextFinder().selectNearestFindMatch(point
, selectionRect
);
1530 WebFloatRect
WebLocalFrameImpl::activeFindMatchRect()
1535 return m_textFinder
->activeFindMatchRect();
1536 return WebFloatRect();
1539 void WebLocalFrameImpl::findMatchRects(WebVector
<WebFloatRect
>& outputRects
)
1542 ensureTextFinder().findMatchRects(outputRects
);
1545 void WebLocalFrameImpl::setTickmarks(const WebVector
<WebRect
>& tickmarks
)
1548 Vector
<IntRect
> tickmarksConverted(tickmarks
.size());
1549 for (size_t i
= 0; i
< tickmarks
.size(); ++i
)
1550 tickmarksConverted
[i
] = tickmarks
[i
];
1551 frameView()->setTickmarks(tickmarksConverted
);
1555 WebString
WebLocalFrameImpl::contentAsText(size_t maxChars
) const
1560 frameContentAsPlainText(maxChars
, frame(), text
);
1561 return text
.toString();
1564 WebString
WebLocalFrameImpl::contentAsMarkup() const
1568 return createMarkup(frame()->document());
1571 WebString
WebLocalFrameImpl::layoutTreeAsText(LayoutAsTextControls toShow
) const
1573 LayoutAsTextBehavior behavior
= LayoutAsTextShowAllLayers
;
1575 if (toShow
& LayoutAsTextWithLineTrees
)
1576 behavior
|= LayoutAsTextShowLineTrees
;
1578 if (toShow
& LayoutAsTextDebug
)
1579 behavior
|= LayoutAsTextShowCompositedLayers
| LayoutAsTextShowAddresses
| LayoutAsTextShowIDAndClass
| LayoutAsTextShowLayerNesting
;
1581 if (toShow
& LayoutAsTextPrinting
)
1582 behavior
|= LayoutAsTextPrintingMode
;
1584 return externalRepresentation(frame(), behavior
);
1587 void WebLocalFrameImpl::registerTestInterface(const WebString
& name
, WebTestInterfaceFactory
* factory
)
1589 m_testInterfaces
.set(name
, adoptPtr(factory
));
1592 v8::Local
<v8::Value
> WebLocalFrameImpl::createTestInterface(const AtomicString
& name
)
1594 if (WebTestInterfaceFactory
* factory
= m_testInterfaces
.get(name
)) {
1595 ScriptState
* scriptState
= ScriptState::forMainWorld(frame());
1596 ASSERT(scriptState
->contextIsValid());
1597 v8::EscapableHandleScope
handleScope(scriptState
->isolate());
1598 ScriptState::Scope
scope(scriptState
);
1599 return handleScope
.Escape(factory
->createInstance(scriptState
->context()));
1601 return v8::Local
<v8::Value
>();
1604 WebString
WebLocalFrameImpl::markerTextForListItem(const WebElement
& webElement
) const
1606 return blink::markerTextForListItem(const_cast<Element
*>(webElement
.constUnwrap
<Element
>()));
1609 void WebLocalFrameImpl::printPagesWithBoundaries(WebCanvas
* canvas
, const WebSize
& pageSizeInPixels
)
1611 ASSERT(m_printContext
);
1613 m_printContext
->spoolAllPagesWithBoundaries(canvas
, FloatSize(pageSizeInPixels
.width
, pageSizeInPixels
.height
));
1616 WebRect
WebLocalFrameImpl::selectionBoundsRect() const
1618 return hasSelection() ? WebRect(IntRect(frame()->selection().bounds())) : WebRect();
1621 bool WebLocalFrameImpl::selectionStartHasSpellingMarkerFor(int from
, int length
) const
1625 return frame()->spellChecker().selectionStartHasSpellingMarkerFor(from
, length
);
1628 WebString
WebLocalFrameImpl::layerTreeAsText(bool showDebugInfo
) const
1633 return WebString(frame()->layerTreeAsText(showDebugInfo
? LayerTreeIncludesDebugInfo
: LayerTreeNormal
));
1636 // WebLocalFrameImpl public ---------------------------------------------------------
1638 WebLocalFrame
* WebLocalFrame::create(WebTreeScopeType scope
, WebFrameClient
* client
)
1640 return WebLocalFrameImpl::create(scope
, client
);
1643 WebLocalFrameImpl
* WebLocalFrameImpl::create(WebTreeScopeType scope
, WebFrameClient
* client
)
1645 WebLocalFrameImpl
* frame
= new WebLocalFrameImpl(scope
, client
);
1649 return adoptRef(frame
).leakRef();
1653 WebLocalFrameImpl::WebLocalFrameImpl(WebTreeScopeType scope
, WebFrameClient
* client
)
1654 : WebLocalFrame(scope
)
1655 , m_frameLoaderClientImpl(FrameLoaderClientImpl::create(this))
1658 , m_autofillClient(0)
1659 , m_contentSettingsClient(0)
1660 , m_inputEventsScaleFactorForEmulation(1)
1661 , m_userMediaClientImpl(this)
1662 , m_geolocationClientProxy(GeolocationClientProxy::create(client
? client
->geolocationClient() : 0))
1663 , m_webDevToolsFrontend(0)
1665 , m_selfKeepAlive(this)
1668 Platform::current()->incrementStatsCounter(webFrameActiveCount
);
1672 WebLocalFrameImpl::~WebLocalFrameImpl()
1674 // The widget for the frame, if any, must have already been closed.
1675 ASSERT(!m_frameWidget
);
1676 Platform::current()->decrementStatsCounter(webFrameActiveCount
);
1680 cancelPendingScopingEffort();
1685 DEFINE_TRACE(WebLocalFrameImpl
)
1687 visitor
->trace(m_frameLoaderClientImpl
);
1688 visitor
->trace(m_frame
);
1689 visitor
->trace(m_devToolsAgent
);
1690 visitor
->trace(m_textFinder
);
1691 visitor
->trace(m_printContext
);
1692 visitor
->trace(m_geolocationClientProxy
);
1693 visitor
->template registerWeakMembers
<WebFrame
, &WebFrame::clearWeakFrames
>(this);
1694 WebFrame::traceFrames(visitor
, this);
1698 void WebLocalFrameImpl::setCoreFrame(PassRefPtrWillBeRawPtr
<LocalFrame
> frame
)
1702 // FIXME: we shouldn't add overhead to every frame by registering these objects when they're not used.
1705 providePushControllerTo(*m_frame
, m_client
->pushClient());
1707 provideNotificationPermissionClientTo(*m_frame
, NotificationPermissionClientImpl::create());
1708 provideUserMediaTo(*m_frame
, &m_userMediaClientImpl
);
1709 provideGeolocationTo(*m_frame
, m_geolocationClientProxy
.get());
1710 m_geolocationClientProxy
->setController(GeolocationController::from(m_frame
.get()));
1711 provideMIDITo(*m_frame
, MIDIClientProxy::create(m_client
? m_client
->webMIDIClient() : nullptr));
1712 provideLocalFileSystemTo(*m_frame
, LocalFileSystemClient::create());
1713 provideNavigatorContentUtilsTo(*m_frame
, NavigatorContentUtilsClientImpl::create(this));
1715 if (RuntimeEnabledFeatures::webBluetoothEnabled())
1716 BluetoothSupplement::provideTo(*m_frame
, m_client
? m_client
->bluetooth() : nullptr);
1717 if (RuntimeEnabledFeatures::screenOrientationEnabled())
1718 ScreenOrientationController::provideTo(*m_frame
, m_client
? m_client
->webScreenOrientationClient() : nullptr);
1719 if (RuntimeEnabledFeatures::presentationEnabled())
1720 PresentationController::provideTo(*m_frame
, m_client
? m_client
->presentationClient() : nullptr);
1721 if (RuntimeEnabledFeatures::permissionsEnabled())
1722 PermissionController::provideTo(*m_frame
, m_client
? m_client
->permissionClient() : nullptr);
1723 if (RuntimeEnabledFeatures::webUSBEnabled())
1724 USBController::provideTo(*m_frame
, m_client
? m_client
->usbClient() : nullptr);
1725 if (RuntimeEnabledFeatures::webVREnabled())
1726 VRController::provideTo(*m_frame
, m_client
? m_client
->webVRClient() : nullptr);
1727 if (RuntimeEnabledFeatures::wakeLockEnabled())
1728 ScreenWakeLock::provideTo(*m_frame
, m_client
? m_client
->wakeLockClient() : nullptr);
1732 PassRefPtrWillBeRawPtr
<LocalFrame
> WebLocalFrameImpl::initializeCoreFrame(FrameHost
* host
, FrameOwner
* owner
, const AtomicString
& name
, const AtomicString
& fallbackName
)
1734 RefPtrWillBeRawPtr
<LocalFrame
> frame
= LocalFrame::create(m_frameLoaderClientImpl
.get(), host
, owner
);
1735 setCoreFrame(frame
);
1736 frame
->tree().setName(name
, fallbackName
);
1737 // We must call init() after m_frame is assigned because it is referenced
1738 // during init(). Note that this may dispatch JS events; the frame may be
1739 // detached after init() returns.
1744 PassRefPtrWillBeRawPtr
<LocalFrame
> WebLocalFrameImpl::createChildFrame(const FrameLoadRequest
& request
,
1745 const AtomicString
& name
, HTMLFrameOwnerElement
* ownerElement
)
1748 WebTreeScopeType scope
= frame()->document() == ownerElement
->treeScope()
1749 ? WebTreeScopeType::Document
1750 : WebTreeScopeType::Shadow
;
1751 WebLocalFrameImpl
* webframeChild
= toWebLocalFrameImpl(m_client
->createChildFrame(this, scope
, name
, static_cast<WebSandboxFlags
>(ownerElement
->sandboxFlags())));
1755 // FIXME: Using subResourceAttributeName as fallback is not a perfect
1756 // solution. subResourceAttributeName returns just one attribute name. The
1757 // element might not have the attribute, and there might be other attributes
1758 // which can identify the element.
1759 RefPtrWillBeRawPtr
<LocalFrame
> child
= webframeChild
->initializeCoreFrame(frame()->host(), ownerElement
, name
, ownerElement
->getAttribute(ownerElement
->subResourceAttributeName()));
1760 // Initializing the core frame may cause the new child to be detached, since
1761 // it may dispatch a load event in the parent.
1762 if (!child
->tree().parent())
1765 // If we're moving in the back/forward list, we might want to replace the content
1766 // of this child frame with whatever was there at that point.
1767 RefPtrWillBeRawPtr
<HistoryItem
> childItem
= nullptr;
1768 if (isBackForwardLoadType(frame()->loader().loadType()) && !frame()->document()->loadEventFinished())
1769 childItem
= PassRefPtrWillBeRawPtr
<HistoryItem
>(webframeChild
->client()->historyItemForNewChildFrame(webframeChild
));
1771 FrameLoadRequest newRequest
= request
;
1772 FrameLoadType loadType
= FrameLoadTypeStandard
;
1774 newRequest
= FrameLoadRequest(request
.originDocument(),
1775 FrameLoader::resourceRequestFromHistoryItem(childItem
.get(), UseProtocolCachePolicy
));
1776 loadType
= FrameLoadTypeInitialHistoryLoad
;
1778 child
->loader().load(newRequest
, loadType
, childItem
.get());
1780 // Note a synchronous navigation (about:blank) would have already processed
1781 // onload, so it is possible for the child frame to have already been
1782 // detached by script in the page.
1783 if (!child
->tree().parent())
1788 void WebLocalFrameImpl::didChangeContentsSize(const IntSize
& size
)
1790 // This is only possible on the main frame.
1791 if (m_textFinder
&& m_textFinder
->totalMatchCount() > 0) {
1793 m_textFinder
->increaseMarkerVersion();
1797 void WebLocalFrameImpl::createFrameView()
1799 TRACE_EVENT0("blink", "WebLocalFrameImpl::createFrameView");
1801 ASSERT(frame()); // If frame() doesn't exist, we probably didn't init properly.
1803 WebViewImpl
* webView
= viewImpl();
1805 IntSize initialSize
= frameWidget() ? (IntSize
)frameWidget()->size() : webView
->mainFrameSize();
1807 frame()->createView(initialSize
, webView
->baseBackgroundColor(), webView
->isTransparent());
1808 if (webView
->shouldAutoResize() && frame()->isLocalRoot())
1809 frame()->view()->enableAutoSizeMode(webView
->minAutoSize(), webView
->maxAutoSize());
1811 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation
, m_inputEventsScaleFactorForEmulation
);
1812 frame()->view()->setDisplayMode(webView
->displayMode());
1815 WebLocalFrameImpl
* WebLocalFrameImpl::fromFrame(LocalFrame
* frame
)
1819 return fromFrame(*frame
);
1822 WebLocalFrameImpl
* WebLocalFrameImpl::fromFrame(LocalFrame
& frame
)
1824 FrameLoaderClient
* client
= frame
.loader().client();
1825 if (!client
|| !client
->isFrameLoaderClientImpl())
1827 return toFrameLoaderClientImpl(client
)->webFrame();
1830 WebLocalFrameImpl
* WebLocalFrameImpl::fromFrameOwnerElement(Element
* element
)
1832 // FIXME: Why do we check specifically for <iframe> and <frame> here? Why can't we get the WebLocalFrameImpl from an <object> element, for example.
1833 if (!isHTMLFrameElementBase(element
))
1835 return fromFrame(toLocalFrame(toHTMLFrameElementBase(element
)->contentFrame()));
1838 WebViewImpl
* WebLocalFrameImpl::viewImpl() const
1842 return WebViewImpl::fromPage(frame()->page());
1845 WebDataSourceImpl
* WebLocalFrameImpl::dataSourceImpl() const
1847 return static_cast<WebDataSourceImpl
*>(dataSource());
1850 WebDataSourceImpl
* WebLocalFrameImpl::provisionalDataSourceImpl() const
1852 return static_cast<WebDataSourceImpl
*>(provisionalDataSource());
1855 void WebLocalFrameImpl::setFindEndstateFocusAndSelection()
1857 WebLocalFrameImpl
* mainFrameImpl
= viewImpl()->mainFrameImpl();
1859 if (this != mainFrameImpl
->activeMatchFrame())
1862 if (Range
* activeMatch
= m_textFinder
->activeMatch()) {
1863 // If the user has set the selection since the match was found, we
1864 // don't focus anything.
1865 VisibleSelection
selection(frame()->selection().selection());
1866 if (!selection
.isNone())
1869 // Need to clean out style and layout state before querying Element::isFocusable().
1870 frame()->document()->updateLayoutIgnorePendingStylesheets();
1872 // Try to find the first focusable node up the chain, which will, for
1873 // example, focus links if we have found text within the link.
1874 Node
* node
= activeMatch
->firstNode();
1875 if (node
&& node
->isInShadowTree()) {
1876 if (Node
* host
= node
->shadowHost()) {
1877 if (isHTMLInputElement(*host
) || isHTMLTextAreaElement(*host
))
1881 for (; node
; node
= node
->parentNode()) {
1882 if (!node
->isElementNode())
1884 Element
* element
= toElement(node
);
1885 if (element
->isFocusable()) {
1886 // Found a focusable parent node. Set the active match as the
1887 // selection and focus to the focusable node.
1888 frame()->selection().setSelection(VisibleSelection(EphemeralRange(activeMatch
)));
1889 frame()->document()->setFocusedElement(element
);
1894 // Iterate over all the nodes in the range until we find a focusable node.
1895 // This, for example, sets focus to the first link if you search for
1896 // text and text that is within one or more links.
1897 node
= activeMatch
->firstNode();
1898 for (; node
&& node
!= activeMatch
->pastLastNode(); node
= NodeTraversal::next(*node
)) {
1899 if (!node
->isElementNode())
1901 Element
* element
= toElement(node
);
1902 if (element
->isFocusable()) {
1903 frame()->document()->setFocusedElement(element
);
1908 // No node related to the active match was focusable, so set the
1909 // active match as the selection (so that when you end the Find session,
1910 // you'll have the last thing you found highlighted) and make sure that
1911 // we have nothing focused (otherwise you might have text selected but
1912 // a link focused, which is weird).
1913 frame()->selection().setSelection(VisibleSelection(EphemeralRange(activeMatch
)));
1914 frame()->document()->setFocusedElement(nullptr);
1916 // Finally clear the active match, for two reasons:
1917 // We just finished the find 'session' and we don't want future (potentially
1918 // unrelated) find 'sessions' operations to start at the same place.
1919 // The WebLocalFrameImpl could get reused and the activeMatch could end up pointing
1920 // to a document that is no longer valid. Keeping an invalid reference around
1921 // is just asking for trouble.
1922 m_textFinder
->resetActiveMatch();
1926 void WebLocalFrameImpl::didFail(const ResourceError
& error
, bool wasProvisional
, HistoryCommitType commitType
)
1930 WebURLError webError
= error
;
1931 WebHistoryCommitType webCommitType
= static_cast<WebHistoryCommitType
>(commitType
);
1933 client()->didFailProvisionalLoad(this, webError
, webCommitType
);
1935 client()->didFailLoad(this, webError
, webCommitType
);
1938 void WebLocalFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars
)
1940 frame()->view()->setCanHaveScrollbars(canHaveScrollbars
);
1943 void WebLocalFrameImpl::setInputEventsTransformForEmulation(const IntSize
& offset
, float contentScaleFactor
)
1945 m_inputEventsOffsetForEmulation
= offset
;
1946 m_inputEventsScaleFactorForEmulation
= contentScaleFactor
;
1947 if (frame()->view())
1948 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation
, m_inputEventsScaleFactorForEmulation
);
1951 void WebLocalFrameImpl::loadJavaScriptURL(const KURL
& url
)
1953 // This is copied from ScriptController::executeScriptIfJavaScriptURL.
1954 // Unfortunately, we cannot just use that method since it is private, and
1955 // it also doesn't quite behave as we require it to for bookmarklets. The
1956 // key difference is that we need to suppress loading the string result
1957 // from evaluating the JS URL if executing the JS URL resulted in a
1958 // location change. We also allow a JS URL to be loaded even if scripts on
1959 // the page are otherwise disabled.
1961 if (!frame()->document() || !frame()->page())
1964 RefPtrWillBeRawPtr
<Document
> ownerDocument(frame()->document());
1966 // Protect privileged pages against bookmarklets and other javascript manipulations.
1967 if (SchemeRegistry::shouldTreatURLSchemeAsNotAllowingJavascriptURLs(frame()->document()->url().protocol()))
1970 String script
= decodeURLEscapeSequences(url
.string().substring(strlen("javascript:")));
1971 UserGestureIndicator
gestureIndicator(DefinitelyProcessingNewUserGesture
);
1972 v8::HandleScope
handleScope(toIsolate(frame()));
1973 v8::Local
<v8::Value
> result
= frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script
));
1974 if (result
.IsEmpty() || !result
->IsString())
1976 String scriptResult
= toCoreString(v8::Local
<v8::String
>::Cast(result
));
1977 if (!frame()->navigationScheduler().locationChangePending())
1978 frame()->loader().replaceDocumentWhileExecutingJavaScriptURL(scriptResult
, ownerDocument
.get());
1981 static void ensureFrameLoaderHasCommitted(FrameLoader
& frameLoader
)
1983 // Internally, Blink uses CommittedMultipleRealLoads to track whether the
1984 // next commit should create a new history item or not. Ensure we have
1985 // reached that state.
1986 if (frameLoader
.stateMachine()->committedMultipleRealLoads())
1988 frameLoader
.stateMachine()->advanceTo(FrameLoaderStateMachine::CommittedMultipleRealLoads
);
1991 void WebLocalFrameImpl::initializeToReplaceRemoteFrame(WebRemoteFrame
* oldWebFrame
, const WebString
& name
, WebSandboxFlags flags
)
1993 Frame
* oldFrame
= toCoreFrame(oldWebFrame
);
1994 // Note: this *always* temporarily sets a frame owner, even for main frames!
1995 // When a core Frame is created with no owner, it attempts to set itself as
1996 // the main frame of the Page. However, this is a provisional frame, and may
1997 // disappear, so Page::m_mainFrame can't be updated just yet.
1998 OwnPtrWillBeRawPtr
<FrameOwner
> tempOwner
= RemoteBridgeFrameOwner::create(nullptr, SandboxNone
);
1999 RefPtrWillBeRawPtr
<LocalFrame
> frame
= LocalFrame::create(m_frameLoaderClientImpl
.get(), oldFrame
->host(), tempOwner
.get());
2000 frame
->setOwner(oldFrame
->owner());
2001 if (frame
->owner() && !frame
->owner()->isLocal())
2002 toRemoteBridgeFrameOwner(frame
->owner())->setSandboxFlags(static_cast<SandboxFlags
>(flags
));
2003 frame
->tree().setName(name
);
2004 setParent(oldWebFrame
->parent());
2005 setOpener(oldWebFrame
->opener());
2006 setCoreFrame(frame
);
2007 // We must call init() after m_frame is assigned because it is referenced
2008 // during init(). Note that this may dispatch JS events; the frame may be
2009 // detached after init() returns.
2013 void WebLocalFrameImpl::setAutofillClient(WebAutofillClient
* autofillClient
)
2015 m_autofillClient
= autofillClient
;
2018 WebAutofillClient
* WebLocalFrameImpl::autofillClient()
2020 return m_autofillClient
;
2023 void WebLocalFrameImpl::setDevToolsAgentClient(WebDevToolsAgentClient
* devToolsClient
)
2025 if (devToolsClient
) {
2026 m_devToolsAgent
= WebDevToolsAgentImpl::create(this, devToolsClient
);
2028 m_devToolsAgent
->willBeDestroyed();
2029 m_devToolsAgent
->dispose();
2030 m_devToolsAgent
.clear();
2034 WebDevToolsAgent
* WebLocalFrameImpl::devToolsAgent()
2036 return m_devToolsAgent
.get();
2039 void WebLocalFrameImpl::sendPings(const WebNode
& contextNode
, const WebURL
& destinationURL
)
2042 Element
* anchor
= contextNode
.constUnwrap
<Node
>()->enclosingLinkEventParentOrSelf();
2043 if (isHTMLAnchorElement(anchor
))
2044 toHTMLAnchorElement(anchor
)->sendPings(destinationURL
);
2047 WebURLRequest
WebLocalFrameImpl::requestFromHistoryItem(const WebHistoryItem
& item
,
2048 WebURLRequest::CachePolicy cachePolicy
) const
2050 RefPtrWillBeRawPtr
<HistoryItem
> historyItem
= PassRefPtrWillBeRawPtr
<HistoryItem
>(item
);
2051 ResourceRequest request
= FrameLoader::resourceRequestFromHistoryItem(
2052 historyItem
.get(), static_cast<ResourceRequestCachePolicy
>(cachePolicy
));
2053 return WrappedResourceRequest(request
);
2056 WebURLRequest
WebLocalFrameImpl::requestForReload(WebFrameLoadType loadType
,
2057 const WebURL
& overrideUrl
) const
2060 ResourceRequest request
= frame()->loader().resourceRequestForReload(
2061 static_cast<FrameLoadType
>(loadType
), overrideUrl
);
2062 return WrappedResourceRequest(request
);
2065 void WebLocalFrameImpl::load(const WebURLRequest
& request
, WebFrameLoadType webFrameLoadType
,
2066 const WebHistoryItem
& item
, WebHistoryLoadType webHistoryLoadType
)
2069 ASSERT(!request
.isNull());
2070 const ResourceRequest
& resourceRequest
= request
.toResourceRequest();
2072 if (resourceRequest
.url().protocolIs("javascript")
2073 && webFrameLoadType
== WebFrameLoadType::Standard
) {
2074 loadJavaScriptURL(resourceRequest
.url());
2078 FrameLoadRequest frameRequest
= FrameLoadRequest(nullptr, resourceRequest
);
2079 RefPtrWillBeRawPtr
<HistoryItem
> historyItem
= PassRefPtrWillBeRawPtr
<HistoryItem
>(item
);
2080 frame()->loader().load(
2081 frameRequest
, static_cast<FrameLoadType
>(webFrameLoadType
), historyItem
.get(),
2082 static_cast<HistoryLoadType
>(webHistoryLoadType
));
2085 bool WebLocalFrameImpl::isLoading() const
2087 if (!frame() || !frame()->document())
2089 return frame()->loader().stateMachine()->isDisplayingInitialEmptyDocument() || frame()->loader().provisionalDocumentLoader() || !frame()->document()->loadEventFinished();
2092 bool WebLocalFrameImpl::isResourceLoadInProgress() const
2094 if (!frame() || !frame()->document())
2096 return frame()->document()->fetcher()->requestCount();
2099 bool WebLocalFrameImpl::isNavigationScheduled() const
2101 return frame() && frame()->navigationScheduler().isNavigationScheduled();
2104 void WebLocalFrameImpl::setCommittedFirstRealLoad()
2107 ensureFrameLoaderHasCommitted(frame()->loader());
2110 void WebLocalFrameImpl::sendOrientationChangeEvent()
2115 // Screen Orientation API
2116 if (ScreenOrientationController::from(*frame()))
2117 ScreenOrientationController::from(*frame())->notifyOrientationChanged();
2119 // Legacy window.orientation API
2120 if (RuntimeEnabledFeatures::orientationEventEnabled() && frame()->domWindow())
2121 frame()->localDOMWindow()->sendOrientationChangeEvent();
2124 void WebLocalFrameImpl::willShowInstallBannerPrompt(int requestId
, const WebVector
<WebString
>& platforms
, WebAppBannerPromptReply
* reply
)
2126 if (!RuntimeEnabledFeatures::appBannerEnabled() || !frame())
2129 AppBannerController::willShowInstallBannerPrompt(requestId
, client()->appBannerClient(), frame(), platforms
, reply
);
2132 void WebLocalFrameImpl::requestRunTask(WebSuspendableTask
* task
) const
2135 ASSERT(frame()->document());
2136 frame()->document()->postSuspendableTask(WebSuspendableTaskWrapper::create(adoptPtr(task
)));
2139 void WebLocalFrameImpl::willBeDetached()
2141 if (m_devToolsAgent
)
2142 m_devToolsAgent
->willBeDestroyed();
2145 void WebLocalFrameImpl::willDetachParent()
2147 // Do not expect string scoping results from any frames that got detached
2148 // in the middle of the operation.
2149 if (m_textFinder
&& m_textFinder
->scopingInProgress()) {
2151 // There is a possibility that the frame being detached was the only
2152 // pending one. We need to make sure final replies can be sent.
2153 m_textFinder
->flushCurrentScoping();
2155 m_textFinder
->cancelPendingScopingEffort();
2159 WebLocalFrameImpl
* WebLocalFrameImpl::activeMatchFrame() const
2164 return m_textFinder
->activeMatchFrame();
2168 Range
* WebLocalFrameImpl::activeMatch() const
2171 return m_textFinder
->activeMatch();
2175 TextFinder
& WebLocalFrameImpl::ensureTextFinder()
2178 m_textFinder
= TextFinder::create(*this);
2180 return *m_textFinder
;
2183 void WebLocalFrameImpl::setFrameWidget(WebFrameWidget
* frameWidget
)
2185 m_frameWidget
= frameWidget
;
2188 WebFrameWidget
* WebLocalFrameImpl::frameWidget() const
2190 return m_frameWidget
;
2193 WebSandboxFlags
WebLocalFrameImpl::effectiveSandboxFlags() const
2196 return WebSandboxFlags::None
;
2197 return static_cast<WebSandboxFlags
>(frame()->loader().effectiveSandboxFlags());
2200 } // namespace blink