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 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.
82 // The client is expected to be set whenever the WebLocalFrameImpl is attached to
86 #include "web/WebLocalFrameImpl.h"
88 #include "bindings/core/v8/DOMWrapperWorld.h"
89 #include "bindings/core/v8/ExceptionState.h"
90 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
91 #include "bindings/core/v8/ScriptController.h"
92 #include "bindings/core/v8/ScriptSourceCode.h"
93 #include "bindings/core/v8/ScriptValue.h"
94 #include "bindings/core/v8/V8Binding.h"
95 #include "bindings/core/v8/V8GCController.h"
96 #include "bindings/core/v8/V8PerIsolateData.h"
97 #include "core/HTMLNames.h"
98 #include "core/dom/Document.h"
99 #include "core/dom/IconURL.h"
100 #include "core/dom/MessagePort.h"
101 #include "core/dom/Node.h"
102 #include "core/dom/NodeTraversal.h"
103 #include "core/dom/shadow/ShadowRoot.h"
104 #include "core/editing/Editor.h"
105 #include "core/editing/FrameSelection.h"
106 #include "core/editing/InputMethodController.h"
107 #include "core/editing/PlainTextRange.h"
108 #include "core/editing/SpellChecker.h"
109 #include "core/editing/TextAffinity.h"
110 #include "core/editing/TextIterator.h"
111 #include "core/editing/htmlediting.h"
112 #include "core/editing/markup.h"
113 #include "core/fetch/ResourceFetcher.h"
114 #include "core/frame/Console.h"
115 #include "core/frame/LocalDOMWindow.h"
116 #include "core/frame/FrameHost.h"
117 #include "core/frame/FrameView.h"
118 #include "core/frame/Settings.h"
119 #include "core/html/HTMLAnchorElement.h"
120 #include "core/html/HTMLCollection.h"
121 #include "core/html/HTMLFormElement.h"
122 #include "core/html/HTMLFrameElementBase.h"
123 #include "core/html/HTMLFrameOwnerElement.h"
124 #include "core/html/HTMLHeadElement.h"
125 #include "core/html/HTMLInputElement.h"
126 #include "core/html/HTMLLinkElement.h"
127 #include "core/html/PluginDocument.h"
128 #include "core/inspector/ConsoleMessage.h"
129 #include "core/inspector/InspectorController.h"
130 #include "core/inspector/ScriptCallStack.h"
131 #include "core/loader/DocumentLoader.h"
132 #include "core/loader/FrameLoadRequest.h"
133 #include "core/loader/FrameLoader.h"
134 #include "core/loader/HistoryItem.h"
135 #include "core/loader/SubstituteData.h"
136 #include "core/page/Chrome.h"
137 #include "core/page/EventHandler.h"
138 #include "core/page/FocusController.h"
139 #include "core/page/FrameTree.h"
140 #include "core/page/Page.h"
141 #include "core/page/PrintContext.h"
142 #include "core/rendering/HitTestResult.h"
143 #include "core/rendering/RenderBox.h"
144 #include "core/rendering/RenderFrame.h"
145 #include "core/rendering/RenderLayer.h"
146 #include "core/rendering/RenderObject.h"
147 #include "core/rendering/RenderTreeAsText.h"
148 #include "core/rendering/RenderView.h"
149 #include "core/rendering/style/StyleInheritedData.h"
150 #include "core/timing/Performance.h"
151 #include "modules/geolocation/GeolocationController.h"
152 #include "modules/notifications/NotificationController.h"
153 #include "modules/notifications/NotificationPermissionClient.h"
154 #include "modules/screen_orientation/ScreenOrientationController.h"
155 #include "platform/TraceEvent.h"
156 #include "platform/UserGestureIndicator.h"
157 #include "platform/clipboard/ClipboardUtilities.h"
158 #include "platform/fonts/FontCache.h"
159 #include "platform/graphics/GraphicsContext.h"
160 #include "platform/graphics/GraphicsLayerClient.h"
161 #include "platform/graphics/skia/SkiaUtils.h"
162 #include "platform/heap/Handle.h"
163 #include "platform/network/ResourceRequest.h"
164 #include "platform/scroll/ScrollTypes.h"
165 #include "platform/scroll/ScrollbarTheme.h"
166 #include "platform/weborigin/KURL.h"
167 #include "platform/weborigin/SchemeRegistry.h"
168 #include "platform/weborigin/SecurityPolicy.h"
169 #include "public/platform/Platform.h"
170 #include "public/platform/WebFloatPoint.h"
171 #include "public/platform/WebFloatRect.h"
172 #include "public/platform/WebLayer.h"
173 #include "public/platform/WebPoint.h"
174 #include "public/platform/WebRect.h"
175 #include "public/platform/WebSize.h"
176 #include "public/platform/WebURLError.h"
177 #include "public/platform/WebVector.h"
178 #include "public/web/WebConsoleMessage.h"
179 #include "public/web/WebDOMEvent.h"
180 #include "public/web/WebDocument.h"
181 #include "public/web/WebFindOptions.h"
182 #include "public/web/WebFormElement.h"
183 #include "public/web/WebFrameClient.h"
184 #include "public/web/WebHistoryItem.h"
185 #include "public/web/WebIconURL.h"
186 #include "public/web/WebInputElement.h"
187 #include "public/web/WebNode.h"
188 #include "public/web/WebPerformance.h"
189 #include "public/web/WebPlugin.h"
190 #include "public/web/WebPrintParams.h"
191 #include "public/web/WebRange.h"
192 #include "public/web/WebScriptSource.h"
193 #include "public/web/WebSecurityOrigin.h"
194 #include "public/web/WebSerializedScriptValue.h"
195 #include "web/AssociatedURLLoader.h"
196 #include "web/CompositionUnderlineVectorBuilder.h"
197 #include "web/FindInPageCoordinates.h"
198 #include "web/GeolocationClientProxy.h"
199 #include "web/LocalFileSystemClient.h"
200 #include "web/MIDIClientProxy.h"
201 #include "web/NotificationPermissionClientImpl.h"
202 #include "web/PageOverlay.h"
203 #include "web/SharedWorkerRepositoryClientImpl.h"
204 #include "web/SuspendableScriptExecutor.h"
205 #include "web/TextFinder.h"
206 #include "web/WebDataSourceImpl.h"
207 #include "web/WebDevToolsAgentPrivate.h"
208 #include "web/WebPluginContainerImpl.h"
209 #include "web/WebRemoteFrameImpl.h"
210 #include "web/WebViewImpl.h"
211 #include "wtf/CurrentTime.h"
212 #include "wtf/HashMap.h"
217 static int frameCount = 0;
219 // Key for a StatsCounter tracking how many WebFrames are active.
220 static const char webFrameActiveCount[] = "WebFrameActiveCount";
222 static void frameContentAsPlainText(size_t maxChars, LocalFrame* frame, StringBuilder& output)
224 Document* document = frame->document();
231 // Select the document body.
232 RefPtrWillBeRawPtr<Range> range(document->createRange());
233 TrackExceptionState exceptionState;
234 range->selectNodeContents(document->body(), exceptionState);
236 if (!exceptionState.hadException()) {
237 // The text iterator will walk nodes giving us text. This is similar to
238 // the plainText() function in core/editing/TextIterator.h, but we implement the maximum
239 // size and also copy the results directly into a wstring, avoiding the
240 // string conversion.
241 for (TextIterator it(range.get()); !it.atEnd(); it.advance()) {
242 it.appendTextToStringBuilder(output, 0, maxChars - output.length());
243 if (output.length() >= maxChars)
244 return; // Filled up the buffer.
248 // The separator between frames when the frames are converted to plain text.
249 const LChar frameSeparator[] = { '\n', '\n' };
250 const size_t frameSeparatorLength = WTF_ARRAY_LENGTH(frameSeparator);
252 // Recursively walk the children.
253 const FrameTree& frameTree = frame->tree();
254 for (Frame* curChild = frameTree.firstChild(); curChild; curChild = curChild->tree().nextSibling()) {
255 if (!curChild->isLocalFrame())
257 LocalFrame* curLocalChild = toLocalFrame(curChild);
258 // Ignore the text of non-visible frames.
259 RenderView* contentRenderer = curLocalChild->contentRenderer();
260 RenderPart* ownerRenderer = curLocalChild->ownerRenderer();
261 if (!contentRenderer || !contentRenderer->width() || !contentRenderer->height()
262 || (contentRenderer->x() + contentRenderer->width() <= 0) || (contentRenderer->y() + contentRenderer->height() <= 0)
263 || (ownerRenderer && ownerRenderer->style() && ownerRenderer->style()->visibility() != VISIBLE)) {
267 // Make sure the frame separator won't fill up the buffer, and give up if
268 // it will. The danger is if the separator will make the buffer longer than
269 // maxChars. This will cause the computation above:
270 // maxChars - output->size()
271 // to be a negative number which will crash when the subframe is added.
272 if (output.length() >= maxChars - frameSeparatorLength)
275 output.append(frameSeparator, frameSeparatorLength);
276 frameContentAsPlainText(maxChars, curLocalChild, output);
277 if (output.length() >= maxChars)
278 return; // Filled up the buffer.
282 static Vector<ScriptSourceCode> createSourcesVector(const WebScriptSource* sourcesIn, unsigned numSources)
284 Vector<ScriptSourceCode> sources;
285 sources.append(sourcesIn, numSources);
289 WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromFrame(LocalFrame* frame)
293 if (!frame->document() || !frame->document()->isPluginDocument())
295 PluginDocument* pluginDocument = toPluginDocument(frame->document());
296 return toWebPluginContainerImpl(pluginDocument->pluginWidget());
299 WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromNode(LocalFrame* frame, const WebNode& node)
301 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame);
303 return pluginContainer;
304 return toWebPluginContainerImpl(node.pluginContainer());
307 // Simple class to override some of PrintContext behavior. Some of the methods
308 // made virtual so that they can be overridden by ChromePluginPrintContext.
309 class ChromePrintContext : public PrintContext {
310 WTF_MAKE_NONCOPYABLE(ChromePrintContext);
312 ChromePrintContext(LocalFrame* frame)
313 : PrintContext(frame)
314 , m_printedPageWidth(0)
318 virtual ~ChromePrintContext() { }
320 virtual void begin(float width, float height)
322 ASSERT(!m_printedPageWidth);
323 m_printedPageWidth = width;
324 PrintContext::begin(m_printedPageWidth, height);
327 virtual float getPageShrink(int pageNumber) const
329 IntRect pageRect = m_pageRects[pageNumber];
330 return m_printedPageWidth / pageRect.width();
333 float spoolSinglePage(GraphicsContext& graphicsContext, int pageNumber)
335 dispatchEventsForPrintingOnAllFrames();
336 if (!frame()->document() || !frame()->document()->renderView())
339 frame()->view()->updateLayoutAndStyleForPainting();
340 if (!frame()->document() || !frame()->document()->renderView())
343 return spoolPage(graphicsContext, pageNumber);
346 void spoolAllPagesWithBoundaries(GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
348 dispatchEventsForPrintingOnAllFrames();
349 if (!frame()->document() || !frame()->document()->renderView())
352 frame()->view()->updateLayoutAndStyleForPainting();
353 if (!frame()->document() || !frame()->document()->renderView())
357 computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, pageHeight);
359 const float pageWidth = pageSizeInPixels.width();
360 size_t numPages = pageRects().size();
361 int totalHeight = numPages * (pageSizeInPixels.height() + 1) - 1;
363 // Fill the whole background by white.
364 graphicsContext.fillRect(FloatRect(0, 0, pageWidth, totalHeight), Color::white);
366 int currentHeight = 0;
367 for (size_t pageIndex = 0; pageIndex < numPages; pageIndex++) {
368 // Draw a line for a page boundary if this isn't the first page.
370 graphicsContext.save();
371 graphicsContext.setStrokeColor(Color(0, 0, 255));
372 graphicsContext.setFillColor(Color(0, 0, 255));
373 graphicsContext.drawLine(IntPoint(0, currentHeight), IntPoint(pageWidth, currentHeight));
374 graphicsContext.restore();
377 graphicsContext.save();
379 graphicsContext.translate(0, currentHeight);
380 #if OS(WIN) || OS(MACOSX)
381 // Account for the disabling of scaling in spoolPage. In the context
382 // of spoolAllPagesWithBoundaries the scale HAS NOT been pre-applied.
383 float scale = getPageShrink(pageIndex);
384 graphicsContext.scale(scale, scale);
386 spoolPage(graphicsContext, pageIndex);
387 graphicsContext.restore();
389 currentHeight += pageSizeInPixels.height() + 1;
394 // Spools the printed page, a subrect of frame(). Skip the scale step.
395 // NativeTheme doesn't play well with scaling. Scaling is done browser side
396 // instead. Returns the scale to be applied.
397 // On Linux, we don't have the problem with NativeTheme, hence we let WebKit
398 // do the scaling and ignore the return value.
399 virtual float spoolPage(GraphicsContext& context, int pageNumber)
401 IntRect pageRect = m_pageRects[pageNumber];
402 float scale = m_printedPageWidth / pageRect.width();
405 #if OS(POSIX) && !OS(MACOSX)
406 context.scale(scale, scale);
408 context.translate(static_cast<float>(-pageRect.x()), static_cast<float>(-pageRect.y()));
409 context.clip(pageRect);
410 frame()->view()->paintContents(&context, pageRect);
411 outputLinkAndLinkedDestinations(context, frame()->document(), pageRect);
417 void dispatchEventsForPrintingOnAllFrames()
419 WillBeHeapVector<RefPtrWillBeMember<Document>> documents;
420 for (Frame* currentFrame = frame(); currentFrame; currentFrame = currentFrame->tree().traverseNext(frame())) {
421 if (currentFrame->isLocalFrame())
422 documents.append(toLocalFrame(currentFrame)->document());
425 for (auto& doc : documents)
426 doc->dispatchEventsForPrinting();
429 // Set when printing.
430 float m_printedPageWidth;
433 // Simple class to override some of PrintContext behavior. This is used when
434 // the frame hosts a plugin that supports custom printing. In this case, we
435 // want to delegate all printing related calls to the plugin.
436 class ChromePluginPrintContext final : public ChromePrintContext {
438 ChromePluginPrintContext(LocalFrame* frame, WebPluginContainerImpl* plugin, const WebPrintParams& printParams)
439 : ChromePrintContext(frame), m_plugin(plugin), m_printParams(printParams)
443 virtual ~ChromePluginPrintContext() { }
445 virtual void begin(float width, float height) override
449 virtual void end() override
451 m_plugin->printEnd();
454 virtual float getPageShrink(int pageNumber) const override
456 // We don't shrink the page (maybe we should ask the widget ??)
460 virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) override
462 m_printParams.printContentArea = IntRect(printRect);
463 m_pageRects.fill(IntRect(printRect), m_plugin->printBegin(m_printParams));
466 virtual void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling) override
468 ASSERT_NOT_REACHED();
472 // Spools the printed page, a subrect of frame(). Skip the scale step.
473 // NativeTheme doesn't play well with scaling. Scaling is done browser side
474 // instead. Returns the scale to be applied.
475 virtual float spoolPage(GraphicsContext& context, int pageNumber) override
477 m_plugin->printPage(pageNumber, &context);
482 // Set when printing.
483 WebPluginContainerImpl* m_plugin;
484 WebPrintParams m_printParams;
487 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader)
489 return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0;
492 // WebFrame -------------------------------------------------------------------
494 int WebFrame::instanceCount()
499 WebLocalFrame* WebLocalFrame::frameForCurrentContext()
501 v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentContext();
502 if (context.IsEmpty())
504 return frameForContext(context);
507 WebLocalFrame* WebLocalFrame::frameForContext(v8::Handle<v8::Context> context)
509 return WebLocalFrameImpl::fromFrame(toFrameIfNotDetached(context));
512 WebLocalFrame* WebLocalFrame::fromFrameOwnerElement(const WebElement& element)
514 return WebLocalFrameImpl::fromFrameOwnerElement(PassRefPtrWillBeRawPtr<Element>(element).get());
517 bool WebLocalFrameImpl::isWebLocalFrame() const
522 WebLocalFrame* WebLocalFrameImpl::toWebLocalFrame()
527 bool WebLocalFrameImpl::isWebRemoteFrame() const
532 WebRemoteFrame* WebLocalFrameImpl::toWebRemoteFrame()
534 ASSERT_NOT_REACHED();
538 void WebLocalFrameImpl::close()
543 m_selfKeepAlive.clear();
545 deref(); // Balances ref() acquired in WebFrame::create
549 WebString WebLocalFrameImpl::uniqueName() const
551 return frame()->tree().uniqueName();
554 WebString WebLocalFrameImpl::assignedName() const
556 return frame()->tree().name();
559 void WebLocalFrameImpl::setName(const WebString& name)
561 frame()->tree().setName(name);
564 WebVector<WebIconURL> WebLocalFrameImpl::iconURLs(int iconTypesMask) const
566 // The URL to the icon may be in the header. As such, only
567 // ask the loader for the icon if it's finished loading.
568 if (frame()->loader().state() == FrameStateComplete)
569 return frame()->document()->iconURLs(iconTypesMask);
570 return WebVector<WebIconURL>();
573 void WebLocalFrameImpl::setRemoteWebLayer(WebLayer* webLayer)
578 frame()->setRemotePlatformLayer(webLayer);
581 void WebLocalFrameImpl::setPermissionClient(WebPermissionClient* permissionClient)
583 m_permissionClient = permissionClient;
586 void WebLocalFrameImpl::setSharedWorkerRepositoryClient(WebSharedWorkerRepositoryClient* client)
588 m_sharedWorkerRepositoryClient = SharedWorkerRepositoryClientImpl::create(client);
591 WebSize WebLocalFrameImpl::scrollOffset() const
593 FrameView* view = frameView();
596 return view->scrollOffset();
599 WebSize WebLocalFrameImpl::minimumScrollOffset() const
601 FrameView* view = frameView();
604 return toIntSize(view->minimumScrollPosition());
607 WebSize WebLocalFrameImpl::maximumScrollOffset() const
609 FrameView* view = frameView();
612 return toIntSize(view->maximumScrollPosition());
615 void WebLocalFrameImpl::setScrollOffset(const WebSize& offset)
617 if (FrameView* view = frameView())
618 view->setScrollOffset(IntPoint(offset.width, offset.height));
621 WebSize WebLocalFrameImpl::contentsSize() const
623 if (FrameView* view = frameView())
624 return view->contentsSize();
628 bool WebLocalFrameImpl::hasVisibleContent() const
630 if (RenderPart* renderer = frame()->ownerRenderer()) {
631 if (renderer->style()->visibility() != VISIBLE)
635 if (FrameView* view = frameView())
636 return view->visibleWidth() > 0 && view->visibleHeight() > 0;
640 WebRect WebLocalFrameImpl::visibleContentRect() const
642 if (FrameView* view = frameView())
643 return view->visibleContentRect();
647 bool WebLocalFrameImpl::hasHorizontalScrollbar() const
649 return frame() && frame()->view() && frame()->view()->horizontalScrollbar();
652 bool WebLocalFrameImpl::hasVerticalScrollbar() const
654 return frame() && frame()->view() && frame()->view()->verticalScrollbar();
657 WebView* WebLocalFrameImpl::view() const
662 void WebLocalFrameImpl::setOpener(WebFrame* opener)
664 // FIXME: Does this need to move up into WebFrame too?
665 if (WebFrame::opener() && !opener && m_client)
666 m_client->didDisownOpener(this);
668 WebFrame::setOpener(opener);
671 if (m_frame && m_frame->document())
672 m_frame->document()->initSecurityContext();
675 WebDocument WebLocalFrameImpl::document() const
677 if (!frame() || !frame()->document())
678 return WebDocument();
679 return WebDocument(frame()->document());
682 WebPerformance WebLocalFrameImpl::performance() const
685 return WebPerformance();
686 return WebPerformance(frame()->domWindow()->performance());
689 bool WebLocalFrameImpl::dispatchBeforeUnloadEvent()
693 return frame()->loader().shouldClose();
696 void WebLocalFrameImpl::dispatchUnloadEvent()
700 frame()->loader().closeURL();
703 NPObject* WebLocalFrameImpl::windowObject() const
707 return frame()->script().windowScriptNPObject();
710 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object)
712 bindToWindowObject(name, object, 0);
715 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object, void*)
717 if (!frame() || !frame()->script().canExecuteScripts(NotAboutToExecuteScript))
719 frame()->script().bindToWindowObject(frame(), String(name), object);
722 void WebLocalFrameImpl::executeScript(const WebScriptSource& source)
725 TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
726 v8::HandleScope handleScope(toIsolate(frame()));
727 frame()->script().executeScriptInMainWorld(ScriptSourceCode(source.code, source.url, position));
730 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup)
733 RELEASE_ASSERT(worldID > 0);
734 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
736 Vector<ScriptSourceCode> sources = createSourcesVector(sourcesIn, numSources);
737 v8::HandleScope handleScope(toIsolate(frame()));
738 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
741 void WebLocalFrameImpl::setIsolatedWorldSecurityOrigin(int worldID, const WebSecurityOrigin& securityOrigin)
744 DOMWrapperWorld::setIsolatedWorldSecurityOrigin(worldID, securityOrigin.get());
747 void WebLocalFrameImpl::setIsolatedWorldContentSecurityPolicy(int worldID, const WebString& policy)
750 DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(worldID, policy);
753 void WebLocalFrameImpl::setIsolatedWorldHumanReadableName(int worldID, const WebString& humanReadableName)
756 DOMWrapperWorld::setIsolatedWorldHumanReadableName(worldID, humanReadableName);
759 void WebLocalFrameImpl::addMessageToConsole(const WebConsoleMessage& message)
763 MessageLevel webCoreMessageLevel;
764 switch (message.level) {
765 case WebConsoleMessage::LevelDebug:
766 webCoreMessageLevel = DebugMessageLevel;
768 case WebConsoleMessage::LevelLog:
769 webCoreMessageLevel = LogMessageLevel;
771 case WebConsoleMessage::LevelWarning:
772 webCoreMessageLevel = WarningMessageLevel;
774 case WebConsoleMessage::LevelError:
775 webCoreMessageLevel = ErrorMessageLevel;
778 ASSERT_NOT_REACHED();
782 frame()->document()->addConsoleMessage(ConsoleMessage::create(OtherMessageSource, webCoreMessageLevel, message.text));
785 void WebLocalFrameImpl::collectGarbage()
789 if (!frame()->settings()->scriptEnabled())
791 V8GCController::collectGarbage(v8::Isolate::GetCurrent());
794 bool WebLocalFrameImpl::checkIfRunInsecureContent(const WebURL& url) const
797 return frame()->loader().mixedContentChecker()->canFrameInsecureContent(frame()->document()->securityOrigin(), url);
800 v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValue(const WebScriptSource& source)
804 TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
805 return frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source.code, source.url, position));
808 void WebLocalFrameImpl::requestExecuteScriptAndReturnValue(const WebScriptSource& source, bool userGesture, WebScriptExecutionCallback* callback)
812 SuspendableScriptExecutor::createAndRun(frame(), 0, createSourcesVector(&source, 1), 0, userGesture, callback);
815 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, WebVector<v8::Local<v8::Value> >* results)
818 RELEASE_ASSERT(worldID > 0);
819 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
821 Vector<ScriptSourceCode> sources = createSourcesVector(sourcesIn, numSources);
824 Vector<v8::Local<v8::Value> > scriptResults;
825 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, &scriptResults);
826 WebVector<v8::Local<v8::Value> > v8Results(scriptResults.size());
827 for (unsigned i = 0; i < scriptResults.size(); i++)
828 v8Results[i] = v8::Local<v8::Value>::New(toIsolate(frame()), scriptResults[i]);
829 results->swap(v8Results);
831 v8::HandleScope handleScope(toIsolate(frame()));
832 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
836 void WebLocalFrameImpl::requestExecuteScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, bool userGesture, WebScriptExecutionCallback* callback)
839 RELEASE_ASSERT(worldID > 0);
840 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
842 SuspendableScriptExecutor::createAndRun(frame(), worldID, createSourcesVector(sourcesIn, numSources), extensionGroup, userGesture, callback);
845 v8::Handle<v8::Value> WebLocalFrameImpl::callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> argv[])
848 return frame()->script().callFunction(function, receiver, argc, argv);
851 v8::Local<v8::Context> WebLocalFrameImpl::mainWorldScriptContext() const
853 return toV8Context(frame(), DOMWrapperWorld::mainWorld());
856 void WebLocalFrameImpl::reload(bool ignoreCache)
859 frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload);
862 void WebLocalFrameImpl::reloadWithOverrideURL(const WebURL& overrideUrl, bool ignoreCache)
865 frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload, overrideUrl);
868 void WebLocalFrameImpl::loadRequest(const WebURLRequest& request)
871 ASSERT(!request.isNull());
872 const ResourceRequest& resourceRequest = request.toResourceRequest();
874 if (resourceRequest.url().protocolIs("javascript")) {
875 loadJavaScriptURL(resourceRequest.url());
879 frame()->loader().load(FrameLoadRequest(0, resourceRequest));
882 void WebLocalFrameImpl::loadHistoryItem(const WebHistoryItem& item, WebHistoryLoadType loadType, WebURLRequest::CachePolicy cachePolicy)
885 RefPtrWillBeRawPtr<HistoryItem> historyItem = PassRefPtrWillBeRawPtr<HistoryItem>(item);
887 frame()->loader().loadHistoryItem(historyItem.get(), FrameLoadTypeBackForward,
888 static_cast<HistoryLoadType>(loadType), static_cast<ResourceRequestCachePolicy>(cachePolicy));
891 void WebLocalFrameImpl::loadData(const WebData& data, const WebString& mimeType, const WebString& textEncoding, const WebURL& baseURL, const WebURL& unreachableURL, bool replace)
895 // If we are loading substitute data to replace an existing load, then
896 // inherit all of the properties of that original request. This way,
897 // reload will re-attempt the original request. It is essential that
898 // we only do this when there is an unreachableURL since a non-empty
899 // unreachableURL informs FrameLoader::reload to load unreachableURL
900 // instead of the currently loaded URL.
901 ResourceRequest request;
902 if (replace && !unreachableURL.isEmpty() && frame()->loader().provisionalDocumentLoader())
903 request = frame()->loader().provisionalDocumentLoader()->originalRequest();
904 request.setURL(baseURL);
906 FrameLoadRequest frameRequest(0, request, SubstituteData(data, mimeType, textEncoding, unreachableURL));
907 ASSERT(frameRequest.substituteData().isValid());
908 frameRequest.setLockBackForwardList(replace);
909 frame()->loader().load(frameRequest);
912 void WebLocalFrameImpl::loadHTMLString(const WebData& data, const WebURL& baseURL, const WebURL& unreachableURL, bool replace)
915 loadData(data, WebString::fromUTF8("text/html"), WebString::fromUTF8("UTF-8"), baseURL, unreachableURL, replace);
918 void WebLocalFrameImpl::stopLoading()
922 // FIXME: Figure out what we should really do here. It seems like a bug
923 // that FrameLoader::stopLoading doesn't call stopAllLoaders.
924 frame()->loader().stopAllLoaders();
927 WebDataSource* WebLocalFrameImpl::provisionalDataSource() const
931 // We regard the policy document loader as still provisional.
932 DocumentLoader* documentLoader = frame()->loader().provisionalDocumentLoader();
934 documentLoader = frame()->loader().policyDocumentLoader();
936 return DataSourceForDocLoader(documentLoader);
939 WebDataSource* WebLocalFrameImpl::dataSource() const
942 return DataSourceForDocLoader(frame()->loader().documentLoader());
945 void WebLocalFrameImpl::enableViewSourceMode(bool enable)
948 frame()->setInViewSourceMode(enable);
951 bool WebLocalFrameImpl::isViewSourceModeEnabled() const
955 return frame()->inViewSourceMode();
958 void WebLocalFrameImpl::setReferrerForRequest(WebURLRequest& request, const WebURL& referrerURL)
960 String referrer = referrerURL.isEmpty() ? frame()->document()->outgoingReferrer() : String(referrerURL.spec().utf16());
961 request.toMutableResourceRequest().setHTTPReferrer(SecurityPolicy::generateReferrer(frame()->document()->referrerPolicy(), request.url(), referrer));
964 void WebLocalFrameImpl::dispatchWillSendRequest(WebURLRequest& request)
966 ResourceResponse response;
967 frame()->loader().client()->dispatchWillSendRequest(0, 0, request.toMutableResourceRequest(), response);
970 WebURLLoader* WebLocalFrameImpl::createAssociatedURLLoader(const WebURLLoaderOptions& options)
972 return new AssociatedURLLoader(this, options);
975 unsigned WebLocalFrameImpl::unloadListenerCount() const
977 return frame()->domWindow()->pendingUnloadEventListeners();
980 void WebLocalFrameImpl::replaceSelection(const WebString& text)
982 bool selectReplacement = false;
983 bool smartReplace = true;
984 frame()->editor().replaceSelectionWithText(text, selectReplacement, smartReplace);
987 void WebLocalFrameImpl::insertText(const WebString& text)
989 if (frame()->inputMethodController().hasComposition())
990 frame()->inputMethodController().confirmComposition(text);
992 frame()->editor().insertText(text, 0);
995 void WebLocalFrameImpl::setMarkedText(const WebString& text, unsigned location, unsigned length)
997 Vector<CompositionUnderline> decorations;
998 frame()->inputMethodController().setComposition(text, decorations, location, length);
1001 void WebLocalFrameImpl::unmarkText()
1003 frame()->inputMethodController().cancelComposition();
1006 bool WebLocalFrameImpl::hasMarkedText() const
1008 return frame()->inputMethodController().hasComposition();
1011 WebRange WebLocalFrameImpl::markedRange() const
1013 return frame()->inputMethodController().compositionRange();
1016 bool WebLocalFrameImpl::firstRectForCharacterRange(unsigned location, unsigned length, WebRect& rect) const
1018 if ((location + length < location) && (location + length))
1021 Element* editable = frame()->selection().rootEditableElementOrDocumentElement();
1023 RefPtrWillBeRawPtr<Range> range = PlainTextRange(location, location + length).createRange(*editable);
1026 IntRect intRect = frame()->editor().firstRectForRange(range.get());
1027 rect = WebRect(intRect);
1028 rect = frame()->view()->contentsToWindow(rect);
1032 size_t WebLocalFrameImpl::characterIndexForPoint(const WebPoint& webPoint) const
1037 IntPoint point = frame()->view()->windowToContents(webPoint);
1038 HitTestResult result = frame()->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active);
1039 RefPtrWillBeRawPtr<Range> range = frame()->rangeForPoint(result.roundedPointInInnerNodeFrame());
1042 Element* editable = frame()->selection().rootEditableElementOrDocumentElement();
1044 return PlainTextRange::create(*editable, *range.get()).start();
1047 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebNode& node)
1051 if (name.length() <= 2)
1054 // Since we don't have NSControl, we will convert the format of command
1055 // string and call the function on Editor directly.
1056 String command = name;
1058 // Make sure the first letter is upper case.
1059 command.replace(0, 1, command.substring(0, 1).upper());
1061 // Remove the trailing ':' if existing.
1062 if (command[command.length() - 1] == UChar(':'))
1063 command = command.substring(0, command.length() - 1);
1065 WebPluginContainerImpl* pluginContainer = pluginContainerFromNode(frame(), node);
1066 if (pluginContainer && pluginContainer->executeEditCommand(name))
1069 return frame()->editor().executeCommand(command);
1072 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebString& value, const WebNode& node)
1076 WebPluginContainerImpl* pluginContainer = pluginContainerFromNode(frame(), node);
1077 if (pluginContainer && pluginContainer->executeEditCommand(name, value))
1080 return frame()->editor().executeCommand(name, value);
1083 bool WebLocalFrameImpl::isCommandEnabled(const WebString& name) const
1086 return frame()->editor().command(name).isEnabled();
1089 void WebLocalFrameImpl::enableContinuousSpellChecking(bool enable)
1091 if (enable == isContinuousSpellCheckingEnabled())
1093 frame()->spellChecker().toggleContinuousSpellChecking();
1096 bool WebLocalFrameImpl::isContinuousSpellCheckingEnabled() const
1098 return frame()->spellChecker().isContinuousSpellCheckingEnabled();
1101 void WebLocalFrameImpl::requestTextChecking(const WebElement& webElement)
1103 if (webElement.isNull())
1105 frame()->spellChecker().requestTextChecking(*webElement.constUnwrap<Element>());
1108 void WebLocalFrameImpl::replaceMisspelledRange(const WebString& text)
1110 // If this caret selection has two or more markers, this function replace the range covered by the first marker with the specified word as Microsoft Word does.
1111 if (pluginContainerFromFrame(frame()))
1113 frame()->spellChecker().replaceMisspelledRange(text);
1116 void WebLocalFrameImpl::removeSpellingMarkers()
1118 frame()->spellChecker().removeSpellingMarkers();
1121 bool WebLocalFrameImpl::hasSelection() const
1123 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1124 if (pluginContainer)
1125 return pluginContainer->plugin()->hasSelection();
1127 // frame()->selection()->isNone() never returns true.
1128 return frame()->selection().start() != frame()->selection().end();
1131 WebRange WebLocalFrameImpl::selectionRange() const
1133 return frame()->selection().toNormalizedRange();
1136 WebString WebLocalFrameImpl::selectionAsText() const
1138 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1139 if (pluginContainer)
1140 return pluginContainer->plugin()->selectionAsText();
1142 RefPtrWillBeRawPtr<Range> range = frame()->selection().toNormalizedRange();
1146 String text = range->text();
1148 replaceNewlinesWithWindowsStyleNewlines(text);
1150 replaceNBSPWithSpace(text);
1154 WebString WebLocalFrameImpl::selectionAsMarkup() const
1156 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1157 if (pluginContainer)
1158 return pluginContainer->plugin()->selectionAsMarkup();
1160 RefPtrWillBeRawPtr<Range> range = frame()->selection().toNormalizedRange();
1164 return createMarkup(range.get(), 0, AnnotateForInterchange, false, ResolveNonLocalURLs);
1167 void WebLocalFrameImpl::selectWordAroundPosition(LocalFrame* frame, VisiblePosition position)
1169 frame->selection().selectWordAroundPosition(position);
1172 bool WebLocalFrameImpl::selectWordAroundCaret()
1174 FrameSelection& selection = frame()->selection();
1175 if (selection.isNone() || selection.isRange())
1177 return frame()->selection().selectWordAroundPosition(selection.selection().visibleStart());
1180 void WebLocalFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent)
1182 moveRangeSelection(base, extent);
1185 void WebLocalFrameImpl::selectRange(const WebRange& webRange)
1187 if (RefPtrWillBeRawPtr<Range> range = static_cast<PassRefPtrWillBeRawPtr<Range> >(webRange))
1188 frame()->selection().setSelectedRange(range.get(), VP_DEFAULT_AFFINITY, FrameSelection::NonDirectional, NotUserTriggered);
1191 void WebLocalFrameImpl::moveRangeSelectionExtent(const WebPoint& point)
1193 VisibleSelection currentSelection = frame()->selection().selection();
1195 VisiblePosition basePosition = currentSelection.isBaseFirst() ?
1196 currentSelection.visibleStart() : currentSelection.visibleEnd();
1197 VisiblePosition extentPosition = visiblePositionForWindowPoint(point);
1199 // Prevent the selection from collapsing.
1200 if (comparePositions(basePosition, extentPosition) == 0)
1203 VisibleSelection newSelection = VisibleSelection(basePosition, extentPosition);
1204 frame()->selection().setSelection(newSelection, CharacterGranularity);
1207 void WebLocalFrameImpl::moveRangeSelection(const WebPoint& base, const WebPoint& extent)
1209 VisiblePosition basePosition = visiblePositionForWindowPoint(base);
1210 VisiblePosition extentPosition = visiblePositionForWindowPoint(extent);
1211 VisibleSelection newSelection = VisibleSelection(basePosition, extentPosition);
1212 frame()->selection().setSelection(newSelection, CharacterGranularity);
1215 void WebLocalFrameImpl::moveCaretSelection(const WebPoint& point)
1217 Element* editable = frame()->selection().rootEditableElement();
1221 VisiblePosition position = visiblePositionForWindowPoint(point);
1222 frame()->selection().moveTo(position, UserTriggered);
1225 bool WebLocalFrameImpl::setEditableSelectionOffsets(int start, int end)
1227 return frame()->inputMethodController().setEditableSelectionOffsets(PlainTextRange(start, end));
1230 bool WebLocalFrameImpl::setCompositionFromExistingText(int compositionStart, int compositionEnd, const WebVector<WebCompositionUnderline>& underlines)
1232 if (!frame()->editor().canEdit())
1235 InputMethodController& inputMethodController = frame()->inputMethodController();
1236 inputMethodController.cancelComposition();
1238 if (compositionStart == compositionEnd)
1241 inputMethodController.setCompositionFromExistingText(CompositionUnderlineVectorBuilder(underlines), compositionStart, compositionEnd);
1246 void WebLocalFrameImpl::extendSelectionAndDelete(int before, int after)
1248 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported()) {
1249 plugin->extendSelectionAndDelete(before, after);
1252 frame()->inputMethodController().extendSelectionAndDelete(before, after);
1255 void WebLocalFrameImpl::setCaretVisible(bool visible)
1257 frame()->selection().setCaretVisible(visible);
1260 VisiblePosition WebLocalFrameImpl::visiblePositionForWindowPoint(const WebPoint& point)
1262 // FIXME(bokan): crbug.com/371902 - These scale/pinch transforms shouldn't
1263 // be ad hoc and explicit.
1264 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
1265 FloatPoint unscaledPoint(point);
1266 unscaledPoint.scale(1 / view()->pageScaleFactor(), 1 / view()->pageScaleFactor());
1267 unscaledPoint.moveBy(pinchViewport.visibleRect().location());
1269 HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping;
1270 HitTestResult result(frame()->view()->windowToContents(roundedIntPoint(unscaledPoint)));
1271 frame()->document()->renderView()->layer()->hitTest(request, result);
1273 if (Node* node = result.innerNode())
1274 return frame()->selection().selection().visiblePositionRespectingEditingBoundary(result.localPoint(), node);
1275 return VisiblePosition();
1278 WebPlugin* WebLocalFrameImpl::focusedPluginIfInputMethodSupported()
1280 WebPluginContainerImpl* container = WebLocalFrameImpl::pluginContainerFromNode(frame(), WebNode(frame()->document()->focusedElement()));
1281 if (container && container->supportsInputMethod())
1282 return container->plugin();
1286 int WebLocalFrameImpl::printBegin(const WebPrintParams& printParams, const WebNode& constrainToNode)
1288 ASSERT(!frame()->document()->isFrameSet());
1289 WebPluginContainerImpl* pluginContainer = 0;
1290 if (constrainToNode.isNull()) {
1291 // If this is a plugin document, check if the plugin supports its own
1292 // printing. If it does, we will delegate all printing to that.
1293 pluginContainer = pluginContainerFromFrame(frame());
1295 // We only support printing plugin nodes for now.
1296 pluginContainer = toWebPluginContainerImpl(constrainToNode.pluginContainer());
1299 if (pluginContainer && pluginContainer->supportsPaginatedPrint())
1300 m_printContext = adoptPtrWillBeNoop(new ChromePluginPrintContext(frame(), pluginContainer, printParams));
1302 m_printContext = adoptPtrWillBeNoop(new ChromePrintContext(frame()));
1304 FloatRect rect(0, 0, static_cast<float>(printParams.printContentArea.width), static_cast<float>(printParams.printContentArea.height));
1305 m_printContext->begin(rect.width(), rect.height());
1307 // We ignore the overlays calculation for now since they are generated in the
1308 // browser. pageHeight is actually an output parameter.
1309 m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight);
1311 return static_cast<int>(m_printContext->pageCount());
1314 float WebLocalFrameImpl::getPrintPageShrink(int page)
1316 ASSERT(m_printContext && page >= 0);
1317 return m_printContext->getPageShrink(page);
1320 float WebLocalFrameImpl::printPage(int page, WebCanvas* canvas)
1322 #if ENABLE(PRINTING)
1323 ASSERT(m_printContext && page >= 0 && frame() && frame()->document());
1325 GraphicsContext graphicsContext(canvas);
1326 graphicsContext.setPrinting(true);
1327 return m_printContext->spoolSinglePage(graphicsContext, page);
1333 void WebLocalFrameImpl::printEnd()
1335 ASSERT(m_printContext);
1336 m_printContext->end();
1337 m_printContext.clear();
1340 bool WebLocalFrameImpl::isPrintScalingDisabledForPlugin(const WebNode& node)
1342 WebPluginContainerImpl* pluginContainer = node.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node.pluginContainer());
1344 if (!pluginContainer || !pluginContainer->supportsPaginatedPrint())
1347 return pluginContainer->isPrintScalingDisabled();
1350 int WebLocalFrameImpl::getPrintCopiesForPlugin(const WebNode& node)
1352 WebPluginContainerImpl* pluginContainer = node.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node.pluginContainer());
1354 if (!pluginContainer || !pluginContainer->supportsPaginatedPrint())
1357 return pluginContainer->getCopiesToPrint();
1360 bool WebLocalFrameImpl::hasCustomPageSizeStyle(int pageIndex)
1362 return frame()->document()->styleForPage(pageIndex)->pageSizeType() != PAGE_SIZE_AUTO;
1365 bool WebLocalFrameImpl::isPageBoxVisible(int pageIndex)
1367 return frame()->document()->isPageBoxVisible(pageIndex);
1370 void WebLocalFrameImpl::pageSizeAndMarginsInPixels(int pageIndex, WebSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
1372 IntSize size = pageSize;
1373 frame()->document()->pageSizeAndMarginsInPixels(pageIndex, size, marginTop, marginRight, marginBottom, marginLeft);
1377 WebString WebLocalFrameImpl::pageProperty(const WebString& propertyName, int pageIndex)
1379 ASSERT(m_printContext);
1380 return m_printContext->pageProperty(frame(), propertyName.utf8().data(), pageIndex);
1383 bool WebLocalFrameImpl::find(int identifier, const WebString& searchText, const WebFindOptions& options, bool wrapWithinFrame, WebRect* selectionRect)
1385 return ensureTextFinder().find(identifier, searchText, options, wrapWithinFrame, selectionRect);
1388 void WebLocalFrameImpl::stopFinding(bool clearSelection)
1391 if (!clearSelection)
1392 setFindEndstateFocusAndSelection();
1393 m_textFinder->stopFindingAndClearSelection();
1397 void WebLocalFrameImpl::scopeStringMatches(int identifier, const WebString& searchText, const WebFindOptions& options, bool reset)
1399 ensureTextFinder().scopeStringMatches(identifier, searchText, options, reset);
1402 void WebLocalFrameImpl::cancelPendingScopingEffort()
1405 m_textFinder->cancelPendingScopingEffort();
1408 void WebLocalFrameImpl::increaseMatchCount(int count, int identifier)
1410 // This function should only be called on the mainframe.
1412 ensureTextFinder().increaseMatchCount(identifier, count);
1415 void WebLocalFrameImpl::resetMatchCount()
1417 ensureTextFinder().resetMatchCount();
1420 void WebLocalFrameImpl::dispatchMessageEventWithOriginCheck(const WebSecurityOrigin& intendedTargetOrigin, const WebDOMEvent& event)
1422 ASSERT(!event.isNull());
1423 frame()->domWindow()->dispatchMessageEventWithOriginCheck(intendedTargetOrigin.get(), event, nullptr);
1426 int WebLocalFrameImpl::findMatchMarkersVersion() const
1431 return m_textFinder->findMatchMarkersVersion();
1435 int WebLocalFrameImpl::selectNearestFindMatch(const WebFloatPoint& point, WebRect* selectionRect)
1438 return ensureTextFinder().selectNearestFindMatch(point, selectionRect);
1441 WebFloatRect WebLocalFrameImpl::activeFindMatchRect()
1446 return m_textFinder->activeFindMatchRect();
1447 return WebFloatRect();
1450 void WebLocalFrameImpl::findMatchRects(WebVector<WebFloatRect>& outputRects)
1453 ensureTextFinder().findMatchRects(outputRects);
1456 void WebLocalFrameImpl::setTickmarks(const WebVector<WebRect>& tickmarks)
1459 Vector<IntRect> tickmarksConverted(tickmarks.size());
1460 for (size_t i = 0; i < tickmarks.size(); ++i)
1461 tickmarksConverted[i] = tickmarks[i];
1462 frameView()->setTickmarks(tickmarksConverted);
1463 invalidateScrollbar();
1467 WebString WebLocalFrameImpl::contentAsText(size_t maxChars) const
1472 frameContentAsPlainText(maxChars, frame(), text);
1473 return text.toString();
1476 WebString WebLocalFrameImpl::contentAsMarkup() const
1480 return createMarkup(frame()->document());
1483 WebString WebLocalFrameImpl::renderTreeAsText(RenderAsTextControls toShow) const
1485 RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal;
1487 if (toShow & RenderAsTextDebug)
1488 behavior |= RenderAsTextShowCompositedLayers | RenderAsTextShowAddresses | RenderAsTextShowIDAndClass | RenderAsTextShowLayerNesting;
1490 if (toShow & RenderAsTextPrinting)
1491 behavior |= RenderAsTextPrintingMode;
1493 return externalRepresentation(frame(), behavior);
1496 WebString WebLocalFrameImpl::markerTextForListItem(const WebElement& webElement) const
1498 return blink::markerTextForListItem(const_cast<Element*>(webElement.constUnwrap<Element>()));
1501 void WebLocalFrameImpl::printPagesWithBoundaries(WebCanvas* canvas, const WebSize& pageSizeInPixels)
1503 ASSERT(m_printContext);
1505 GraphicsContext graphicsContext(canvas);
1506 graphicsContext.setPrinting(true);
1508 m_printContext->spoolAllPagesWithBoundaries(graphicsContext, FloatSize(pageSizeInPixels.width, pageSizeInPixels.height));
1511 WebRect WebLocalFrameImpl::selectionBoundsRect() const
1513 return hasSelection() ? WebRect(IntRect(frame()->selection().bounds())) : WebRect();
1516 bool WebLocalFrameImpl::selectionStartHasSpellingMarkerFor(int from, int length) const
1520 return frame()->spellChecker().selectionStartHasSpellingMarkerFor(from, length);
1523 WebString WebLocalFrameImpl::layerTreeAsText(bool showDebugInfo) const
1528 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesDebugInfo : LayerTreeNormal));
1531 // WebLocalFrameImpl public ---------------------------------------------------------
1533 WebLocalFrame* WebLocalFrame::create(WebFrameClient* client)
1535 return WebLocalFrameImpl::create(client);
1538 WebLocalFrameImpl* WebLocalFrameImpl::create(WebFrameClient* client)
1540 WebLocalFrameImpl* frame = new WebLocalFrameImpl(client);
1544 return adoptRef(frame).leakRef();
1548 WebLocalFrameImpl::WebLocalFrameImpl(WebFrameClient* client)
1549 : m_frameLoaderClientImpl(this)
1551 , m_permissionClient(0)
1552 , m_inputEventsScaleFactorForEmulation(1)
1553 , m_userMediaClientImpl(this)
1554 , m_geolocationClientProxy(GeolocationClientProxy::create(client ? client->geolocationClient() : 0))
1556 , m_selfKeepAlive(this)
1559 Platform::current()->incrementStatsCounter(webFrameActiveCount);
1563 WebLocalFrameImpl::~WebLocalFrameImpl()
1565 Platform::current()->decrementStatsCounter(webFrameActiveCount);
1569 cancelPendingScopingEffort();
1574 void WebLocalFrameImpl::trace(Visitor* visitor)
1576 visitor->trace(m_frame);
1577 visitor->trace(m_textFinder);
1578 visitor->trace(m_printContext);
1579 visitor->trace(m_geolocationClientProxy);
1580 visitor->registerWeakMembers<WebFrame, &WebFrame::clearWeakFrames>(this);
1581 WebFrame::traceFrames(visitor, this);
1585 void WebLocalFrameImpl::setCoreFrame(PassRefPtrWillBeRawPtr<LocalFrame> frame)
1589 // FIXME: we shouldn't add overhead to every frame by registering these objects when they're not used.
1591 OwnPtr<NotificationPresenterImpl> notificationPresenter = adoptPtr(new NotificationPresenterImpl());
1593 notificationPresenter->initialize(m_client->notificationPresenter());
1595 provideNotification(*m_frame, notificationPresenter.release());
1596 provideNotificationPermissionClientTo(*m_frame, NotificationPermissionClientImpl::create());
1597 provideUserMediaTo(*m_frame, &m_userMediaClientImpl);
1598 provideGeolocationTo(*m_frame, m_geolocationClientProxy.get());
1599 m_geolocationClientProxy->setController(GeolocationController::from(m_frame.get()));
1600 provideMIDITo(*m_frame, MIDIClientProxy::create(m_client ? m_client->webMIDIClient() : 0));
1601 provideLocalFileSystemTo(*m_frame, LocalFileSystemClient::create());
1603 if (RuntimeEnabledFeatures::screenOrientationEnabled())
1604 ScreenOrientationController::provideTo(*m_frame, m_client ? m_client->webScreenOrientationClient() : 0);
1608 PassRefPtrWillBeRawPtr<LocalFrame> WebLocalFrameImpl::initializeCoreFrame(FrameHost* host, FrameOwner* owner, const AtomicString& name, const AtomicString& fallbackName)
1610 RefPtrWillBeRawPtr<LocalFrame> frame = LocalFrame::create(&m_frameLoaderClientImpl, host, owner);
1611 setCoreFrame(frame);
1612 frame->tree().setName(name, fallbackName);
1613 // We must call init() after m_frame is assigned because it is referenced
1614 // during init(). Note that this may dispatch JS events; the frame may be
1615 // detached after init() returns.
1620 PassRefPtrWillBeRawPtr<LocalFrame> WebLocalFrameImpl::createChildFrame(const FrameLoadRequest& request, HTMLFrameOwnerElement* ownerElement)
1623 WebLocalFrameImpl* webframeChild = toWebLocalFrameImpl(m_client->createChildFrame(this, request.frameName()));
1627 // FIXME: Using subResourceAttributeName as fallback is not a perfect
1628 // solution. subResourceAttributeName returns just one attribute name. The
1629 // element might not have the attribute, and there might be other attributes
1630 // which can identify the element.
1631 RefPtrWillBeRawPtr<LocalFrame> child = webframeChild->initializeCoreFrame(frame()->host(), ownerElement, request.frameName(), ownerElement->getAttribute(ownerElement->subResourceAttributeName()));
1632 // Initializing the core frame may cause the new child to be detached, since
1633 // it may dispatch a load event in the parent.
1634 if (!child->tree().parent())
1637 // If we're moving in the back/forward list, we might want to replace the content
1638 // of this child frame with whatever was there at that point.
1639 RefPtrWillBeRawPtr<HistoryItem> childItem = nullptr;
1640 if (isBackForwardLoadType(frame()->loader().loadType()) && !frame()->document()->loadEventFinished())
1641 childItem = PassRefPtrWillBeRawPtr<HistoryItem>(webframeChild->client()->historyItemForNewChildFrame(webframeChild));
1644 child->loader().loadHistoryItem(childItem.get(), FrameLoadTypeInitialHistoryLoad);
1646 child->loader().load(FrameLoadRequest(request.originDocument(), request.resourceRequest(), "_self"));
1648 // Note a synchronous navigation (about:blank) would have already processed
1649 // onload, so it is possible for the child frame to have already been
1650 // detached by script in the page.
1651 if (!child->tree().parent())
1656 void WebLocalFrameImpl::didChangeContentsSize(const IntSize& size)
1658 // This is only possible on the main frame.
1659 if (m_textFinder && m_textFinder->totalMatchCount() > 0) {
1661 m_textFinder->increaseMarkerVersion();
1665 void WebLocalFrameImpl::createFrameView()
1667 TRACE_EVENT0("blink", "WebLocalFrameImpl::createFrameView");
1669 ASSERT(frame()); // If frame() doesn't exist, we probably didn't init properly.
1671 WebViewImpl* webView = viewImpl();
1672 bool isLocalRoot = frame()->isLocalRoot();
1674 webView->suppressInvalidations(true);
1676 frame()->createView(webView->mainFrameSize(), webView->baseBackgroundColor(), webView->isTransparent());
1677 if (webView->shouldAutoResize() && isLocalRoot)
1678 frame()->view()->enableAutoSizeMode(webView->minAutoSize(), webView->maxAutoSize());
1680 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation, m_inputEventsScaleFactorForEmulation);
1683 webView->suppressInvalidations(false);
1686 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame* frame)
1690 return fromFrame(*frame);
1693 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame& frame)
1695 FrameLoaderClient* client = frame.loader().client();
1696 if (!client || !client->isFrameLoaderClientImpl())
1698 return toFrameLoaderClientImpl(client)->webFrame();
1701 WebLocalFrameImpl* WebLocalFrameImpl::fromFrameOwnerElement(Element* element)
1703 // FIXME: Why do we check specifically for <iframe> and <frame> here? Why can't we get the WebLocalFrameImpl from an <object> element, for example.
1704 if (!isHTMLFrameElementBase(element))
1706 return fromFrame(toLocalFrame(toHTMLFrameElementBase(element)->contentFrame()));
1709 WebViewImpl* WebLocalFrameImpl::viewImpl() const
1713 return WebViewImpl::fromPage(frame()->page());
1716 WebDataSourceImpl* WebLocalFrameImpl::dataSourceImpl() const
1718 return static_cast<WebDataSourceImpl*>(dataSource());
1721 WebDataSourceImpl* WebLocalFrameImpl::provisionalDataSourceImpl() const
1723 return static_cast<WebDataSourceImpl*>(provisionalDataSource());
1726 void WebLocalFrameImpl::setFindEndstateFocusAndSelection()
1728 WebLocalFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1730 if (this != mainFrameImpl->activeMatchFrame())
1733 if (Range* activeMatch = m_textFinder->activeMatch()) {
1734 // If the user has set the selection since the match was found, we
1735 // don't focus anything.
1736 VisibleSelection selection(frame()->selection().selection());
1737 if (!selection.isNone())
1740 // Need to clean out style and layout state before querying Element::isFocusable().
1741 frame()->document()->updateLayoutIgnorePendingStylesheets();
1743 // Try to find the first focusable node up the chain, which will, for
1744 // example, focus links if we have found text within the link.
1745 Node* node = activeMatch->firstNode();
1746 if (node && node->isInShadowTree()) {
1747 if (Node* host = node->shadowHost()) {
1748 if (isHTMLInputElement(*host) || isHTMLTextAreaElement(*host))
1752 for (; node; node = node->parentNode()) {
1753 if (!node->isElementNode())
1755 Element* element = toElement(node);
1756 if (element->isFocusable()) {
1757 // Found a focusable parent node. Set the active match as the
1758 // selection and focus to the focusable node.
1759 frame()->selection().setSelection(VisibleSelection(activeMatch));
1760 frame()->document()->setFocusedElement(element);
1765 // Iterate over all the nodes in the range until we find a focusable node.
1766 // This, for example, sets focus to the first link if you search for
1767 // text and text that is within one or more links.
1768 node = activeMatch->firstNode();
1769 for (; node && node != activeMatch->pastLastNode(); node = NodeTraversal::next(*node)) {
1770 if (!node->isElementNode())
1772 Element* element = toElement(node);
1773 if (element->isFocusable()) {
1774 frame()->document()->setFocusedElement(element);
1779 // No node related to the active match was focusable, so set the
1780 // active match as the selection (so that when you end the Find session,
1781 // you'll have the last thing you found highlighted) and make sure that
1782 // we have nothing focused (otherwise you might have text selected but
1783 // a link focused, which is weird).
1784 frame()->selection().setSelection(VisibleSelection(activeMatch));
1785 frame()->document()->setFocusedElement(nullptr);
1787 // Finally clear the active match, for two reasons:
1788 // We just finished the find 'session' and we don't want future (potentially
1789 // unrelated) find 'sessions' operations to start at the same place.
1790 // The WebLocalFrameImpl could get reused and the activeMatch could end up pointing
1791 // to a document that is no longer valid. Keeping an invalid reference around
1792 // is just asking for trouble.
1793 m_textFinder->resetActiveMatch();
1797 void WebLocalFrameImpl::didFail(const ResourceError& error, bool wasProvisional)
1801 WebURLError webError = error;
1803 client()->didFailProvisionalLoad(this, webError);
1805 client()->didFailLoad(this, webError);
1808 void WebLocalFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars)
1810 frame()->view()->setCanHaveScrollbars(canHaveScrollbars);
1813 void WebLocalFrameImpl::setInputEventsTransformForEmulation(const IntSize& offset, float contentScaleFactor)
1815 m_inputEventsOffsetForEmulation = offset;
1816 m_inputEventsScaleFactorForEmulation = contentScaleFactor;
1817 if (frame()->view())
1818 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation, m_inputEventsScaleFactorForEmulation);
1821 void WebLocalFrameImpl::loadJavaScriptURL(const KURL& url)
1823 // This is copied from ScriptController::executeScriptIfJavaScriptURL.
1824 // Unfortunately, we cannot just use that method since it is private, and
1825 // it also doesn't quite behave as we require it to for bookmarklets. The
1826 // key difference is that we need to suppress loading the string result
1827 // from evaluating the JS URL if executing the JS URL resulted in a
1828 // location change. We also allow a JS URL to be loaded even if scripts on
1829 // the page are otherwise disabled.
1831 if (!frame()->document() || !frame()->page())
1834 RefPtrWillBeRawPtr<Document> ownerDocument(frame()->document());
1836 // Protect privileged pages against bookmarklets and other javascript manipulations.
1837 if (SchemeRegistry::shouldTreatURLSchemeAsNotAllowingJavascriptURLs(frame()->document()->url().protocol()))
1840 String script = decodeURLEscapeSequences(url.string().substring(strlen("javascript:")));
1841 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
1842 v8::HandleScope handleScope(toIsolate(frame()));
1843 v8::Local<v8::Value> result = frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script));
1844 if (result.IsEmpty() || !result->IsString())
1846 String scriptResult = toCoreString(v8::Handle<v8::String>::Cast(result));
1847 if (!frame()->navigationScheduler().locationChangePending())
1848 frame()->loader().replaceDocumentWhileExecutingJavaScriptURL(scriptResult, ownerDocument.get());
1851 void WebLocalFrameImpl::initializeToReplaceRemoteFrame(WebRemoteFrame* oldWebFrame)
1853 Frame* oldFrame = toCoreFrame(oldWebFrame);
1854 OwnPtr<FrameOwner> tempOwner = adoptPtr(new PlaceholderFrameOwner());
1855 m_frame = LocalFrame::create(&m_frameLoaderClientImpl, oldFrame->host(), tempOwner.get());
1856 m_frame->setOwner(oldFrame->owner());
1857 m_frame->tree().setName(oldFrame->tree().name());
1858 setParent(oldWebFrame->parent());
1859 // We must call init() after m_frame is assigned because it is referenced
1860 // during init(). Note that this may dispatch JS events; the frame may be
1861 // detached after init() returns.
1865 void WebLocalFrameImpl::sendPings(const WebNode& linkNode, const WebURL& destinationURL)
1868 const Node* node = linkNode.constUnwrap<Node>();
1869 if (isHTMLAnchorElement(node))
1870 toHTMLAnchorElement(node)->sendPings(destinationURL);
1873 bool WebLocalFrameImpl::isLoading() const
1875 if (!frame() || !frame()->document())
1877 return frame()->loader().stateMachine()->isDisplayingInitialEmptyDocument() || !frame()->document()->loadEventFinished();
1880 bool WebLocalFrameImpl::isResourceLoadInProgress() const
1882 if (!frame() || !frame()->document())
1884 return frame()->document()->fetcher()->requestCount();
1887 void WebLocalFrameImpl::addStyleSheetByURL(const WebString& url)
1889 RefPtrWillBeRawPtr<Element> styleElement = frame()->document()->createElement(HTMLNames::linkTag, false);
1891 styleElement->setAttribute(HTMLNames::typeAttr, "text/css");
1892 styleElement->setAttribute(HTMLNames::relAttr, "stylesheet");
1893 styleElement->setAttribute(HTMLNames::hrefAttr, url);
1895 frame()->document()->head()->appendChild(styleElement.release(), IGNORE_EXCEPTION);
1898 void WebLocalFrameImpl::navigateToSandboxedMarkup(const WebData& markup)
1900 ASSERT(document().securityOrigin().isUnique());
1901 frame()->loader().forceSandboxFlags(SandboxAll);
1902 loadHTMLString(markup, document().url(), WebURL(), true);
1905 void WebLocalFrameImpl::sendOrientationChangeEvent()
1910 // Screen Orientation API
1911 if (ScreenOrientationController::from(*frame()))
1912 ScreenOrientationController::from(*frame())->notifyOrientationChanged();
1914 // Legacy window.orientation API
1915 if (RuntimeEnabledFeatures::orientationEventEnabled() && frame()->domWindow())
1916 frame()->domWindow()->sendOrientationChangeEvent();
1919 v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValueForTests(const WebScriptSource& source)
1921 // FIXME: This fake UserGestureIndicator is required for a bunch of browser
1922 // tests to pass. We should update the tests to simulate input and get rid
1924 // http://code.google.com/p/chromium/issues/detail?id=86397
1925 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
1926 return executeScriptAndReturnValue(source);
1929 void WebLocalFrameImpl::willDetachParent()
1931 // Do not expect string scoping results from any frames that got detached
1932 // in the middle of the operation.
1933 if (m_textFinder && m_textFinder->scopingInProgress()) {
1935 // There is a possibility that the frame being detached was the only
1936 // pending one. We need to make sure final replies can be sent.
1937 m_textFinder->flushCurrentScoping();
1939 m_textFinder->cancelPendingScopingEffort();
1943 WebLocalFrameImpl* WebLocalFrameImpl::activeMatchFrame() const
1948 return m_textFinder->activeMatchFrame();
1952 Range* WebLocalFrameImpl::activeMatch() const
1955 return m_textFinder->activeMatch();
1959 TextFinder& WebLocalFrameImpl::ensureTextFinder()
1962 m_textFinder = TextFinder::create(*this);
1964 return *m_textFinder;
1967 void WebLocalFrameImpl::invalidateScrollbar() const
1969 ASSERT(frame() && frame()->view());
1970 FrameView* view = frame()->view();
1971 // Invalidate the vertical scroll bar region for the view.
1972 Scrollbar* scrollbar = view->verticalScrollbar();
1974 scrollbar->invalidate();
1977 void WebLocalFrameImpl::invalidateAll() const
1979 ASSERT(frame() && frame()->view());
1980 FrameView* view = frame()->view();
1981 view->invalidateRect(view->frameRect());
1982 invalidateScrollbar();
1985 } // namespace blink