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/TextFinder.h"
205 #include "web/WebDataSourceImpl.h"
206 #include "web/WebDevToolsAgentPrivate.h"
207 #include "web/WebPluginContainerImpl.h"
208 #include "web/WebViewImpl.h"
209 #include "wtf/CurrentTime.h"
210 #include "wtf/HashMap.h"
215 static int frameCount = 0;
217 // Key for a StatsCounter tracking how many WebFrames are active.
218 static const char webFrameActiveCount[] = "WebFrameActiveCount";
220 static void frameContentAsPlainText(size_t maxChars, LocalFrame* frame, StringBuilder& output)
222 Document* document = frame->document();
229 // Select the document body.
230 RefPtrWillBeRawPtr<Range> range(document->createRange());
231 TrackExceptionState exceptionState;
232 range->selectNodeContents(document->body(), exceptionState);
234 if (!exceptionState.hadException()) {
235 // The text iterator will walk nodes giving us text. This is similar to
236 // the plainText() function in core/editing/TextIterator.h, but we implement the maximum
237 // size and also copy the results directly into a wstring, avoiding the
238 // string conversion.
239 for (TextIterator it(range.get()); !it.atEnd(); it.advance()) {
240 it.appendTextToStringBuilder(output, 0, maxChars - output.length());
241 if (output.length() >= maxChars)
242 return; // Filled up the buffer.
246 // The separator between frames when the frames are converted to plain text.
247 const LChar frameSeparator[] = { '\n', '\n' };
248 const size_t frameSeparatorLength = WTF_ARRAY_LENGTH(frameSeparator);
250 // Recursively walk the children.
251 const FrameTree& frameTree = frame->tree();
252 for (Frame* curChild = frameTree.firstChild(); curChild; curChild = curChild->tree().nextSibling()) {
253 if (!curChild->isLocalFrame())
255 LocalFrame* curLocalChild = toLocalFrame(curChild);
256 // Ignore the text of non-visible frames.
257 RenderView* contentRenderer = curLocalChild->contentRenderer();
258 RenderPart* ownerRenderer = curLocalChild->ownerRenderer();
259 if (!contentRenderer || !contentRenderer->width() || !contentRenderer->height()
260 || (contentRenderer->x() + contentRenderer->width() <= 0) || (contentRenderer->y() + contentRenderer->height() <= 0)
261 || (ownerRenderer && ownerRenderer->style() && ownerRenderer->style()->visibility() != VISIBLE)) {
265 // Make sure the frame separator won't fill up the buffer, and give up if
266 // it will. The danger is if the separator will make the buffer longer than
267 // maxChars. This will cause the computation above:
268 // maxChars - output->size()
269 // to be a negative number which will crash when the subframe is added.
270 if (output.length() >= maxChars - frameSeparatorLength)
273 output.append(frameSeparator, frameSeparatorLength);
274 frameContentAsPlainText(maxChars, curLocalChild, output);
275 if (output.length() >= maxChars)
276 return; // Filled up the buffer.
280 WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromFrame(LocalFrame* frame)
284 if (!frame->document() || !frame->document()->isPluginDocument())
286 PluginDocument* pluginDocument = toPluginDocument(frame->document());
287 return toWebPluginContainerImpl(pluginDocument->pluginWidget());
290 WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromNode(LocalFrame* frame, const WebNode& node)
292 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame);
294 return pluginContainer;
295 return toWebPluginContainerImpl(node.pluginContainer());
298 // Simple class to override some of PrintContext behavior. Some of the methods
299 // made virtual so that they can be overridden by ChromePluginPrintContext.
300 class ChromePrintContext : public PrintContext {
301 WTF_MAKE_NONCOPYABLE(ChromePrintContext);
303 ChromePrintContext(LocalFrame* frame)
304 : PrintContext(frame)
305 , m_printedPageWidth(0)
309 virtual ~ChromePrintContext() { }
311 virtual void begin(float width, float height)
313 ASSERT(!m_printedPageWidth);
314 m_printedPageWidth = width;
315 PrintContext::begin(m_printedPageWidth, height);
318 virtual float getPageShrink(int pageNumber) const
320 IntRect pageRect = m_pageRects[pageNumber];
321 return m_printedPageWidth / pageRect.width();
324 float spoolSinglePage(GraphicsContext& graphicsContext, int pageNumber)
326 // FIXME: Why is it ok to proceed without all the null checks that
327 // spoolAllPagesWithBoundaries does?
328 frame()->view()->updateLayoutAndStyleForPainting();
329 return spoolPage(graphicsContext, pageNumber);
332 void spoolAllPagesWithBoundaries(GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
334 if (!frame()->document() || !frame()->view() || !frame()->document()->renderView())
337 frame()->view()->updateLayoutAndStyleForPainting();
340 computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, pageHeight);
342 const float pageWidth = pageSizeInPixels.width();
343 size_t numPages = pageRects().size();
344 int totalHeight = numPages * (pageSizeInPixels.height() + 1) - 1;
346 // Fill the whole background by white.
347 graphicsContext.setFillColor(Color::white);
348 graphicsContext.fillRect(FloatRect(0, 0, pageWidth, totalHeight));
350 int currentHeight = 0;
351 for (size_t pageIndex = 0; pageIndex < numPages; pageIndex++) {
352 // Draw a line for a page boundary if this isn't the first page.
354 graphicsContext.save();
355 graphicsContext.setStrokeColor(Color(0, 0, 255));
356 graphicsContext.setFillColor(Color(0, 0, 255));
357 graphicsContext.drawLine(IntPoint(0, currentHeight), IntPoint(pageWidth, currentHeight));
358 graphicsContext.restore();
361 graphicsContext.save();
363 graphicsContext.translate(0, currentHeight);
364 #if OS(WIN) || OS(MACOSX)
365 // Account for the disabling of scaling in spoolPage. In the context
366 // of spoolAllPagesWithBoundaries the scale HAS NOT been pre-applied.
367 float scale = getPageShrink(pageIndex);
368 graphicsContext.scale(scale, scale);
370 spoolPage(graphicsContext, pageIndex);
371 graphicsContext.restore();
373 currentHeight += pageSizeInPixels.height() + 1;
378 // Spools the printed page, a subrect of frame(). Skip the scale step.
379 // NativeTheme doesn't play well with scaling. Scaling is done browser side
380 // instead. Returns the scale to be applied.
381 // On Linux, we don't have the problem with NativeTheme, hence we let WebKit
382 // do the scaling and ignore the return value.
383 virtual float spoolPage(GraphicsContext& context, int pageNumber)
385 IntRect pageRect = m_pageRects[pageNumber];
386 float scale = m_printedPageWidth / pageRect.width();
389 #if OS(POSIX) && !OS(MACOSX)
390 context.scale(scale, scale);
392 context.translate(static_cast<float>(-pageRect.x()), static_cast<float>(-pageRect.y()));
393 context.clip(pageRect);
394 frame()->view()->paintContents(&context, pageRect);
395 outputLinkAndLinkedDestinations(context, frame()->document(), pageRect);
401 // Set when printing.
402 float m_printedPageWidth;
405 // Simple class to override some of PrintContext behavior. This is used when
406 // the frame hosts a plugin that supports custom printing. In this case, we
407 // want to delegate all printing related calls to the plugin.
408 class ChromePluginPrintContext FINAL : public ChromePrintContext {
410 ChromePluginPrintContext(LocalFrame* frame, WebPluginContainerImpl* plugin, const WebPrintParams& printParams)
411 : ChromePrintContext(frame), m_plugin(plugin), m_printParams(printParams)
415 virtual ~ChromePluginPrintContext() { }
417 virtual void begin(float width, float height) OVERRIDE
421 virtual void end() OVERRIDE
423 m_plugin->printEnd();
426 virtual float getPageShrink(int pageNumber) const OVERRIDE
428 // We don't shrink the page (maybe we should ask the widget ??)
432 virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) OVERRIDE
434 m_printParams.printContentArea = IntRect(printRect);
435 m_pageRects.fill(IntRect(printRect), m_plugin->printBegin(m_printParams));
438 virtual void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling) OVERRIDE
440 ASSERT_NOT_REACHED();
444 // Spools the printed page, a subrect of frame(). Skip the scale step.
445 // NativeTheme doesn't play well with scaling. Scaling is done browser side
446 // instead. Returns the scale to be applied.
447 virtual float spoolPage(GraphicsContext& context, int pageNumber) OVERRIDE
449 m_plugin->printPage(pageNumber, &context);
454 // Set when printing.
455 WebPluginContainerImpl* m_plugin;
456 WebPrintParams m_printParams;
459 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader)
461 return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0;
464 // WebFrame -------------------------------------------------------------------
466 int WebFrame::instanceCount()
471 WebLocalFrame* WebLocalFrame::frameForCurrentContext()
473 v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentContext();
474 if (context.IsEmpty())
476 return frameForContext(context);
479 WebLocalFrame* WebLocalFrame::frameForContext(v8::Handle<v8::Context> context)
481 return WebLocalFrameImpl::fromFrame(toFrameIfNotDetached(context));
484 WebLocalFrame* WebLocalFrame::fromFrameOwnerElement(const WebElement& element)
486 return WebLocalFrameImpl::fromFrameOwnerElement(PassRefPtrWillBeRawPtr<Element>(element).get());
489 bool WebLocalFrameImpl::isWebLocalFrame() const
494 WebLocalFrame* WebLocalFrameImpl::toWebLocalFrame()
499 bool WebLocalFrameImpl::isWebRemoteFrame() const
504 WebRemoteFrame* WebLocalFrameImpl::toWebRemoteFrame()
506 ASSERT_NOT_REACHED();
510 void WebLocalFrameImpl::close()
515 m_selfKeepAlive.clear();
517 deref(); // Balances ref() acquired in WebFrame::create
521 WebString WebLocalFrameImpl::uniqueName() const
523 return frame()->tree().uniqueName();
526 WebString WebLocalFrameImpl::assignedName() const
528 return frame()->tree().name();
531 void WebLocalFrameImpl::setName(const WebString& name)
533 frame()->tree().setName(name);
536 WebVector<WebIconURL> WebLocalFrameImpl::iconURLs(int iconTypesMask) const
538 // The URL to the icon may be in the header. As such, only
539 // ask the loader for the icon if it's finished loading.
540 if (frame()->loader().state() == FrameStateComplete)
541 return frame()->document()->iconURLs(iconTypesMask);
542 return WebVector<WebIconURL>();
545 void WebLocalFrameImpl::setIsRemote(bool isRemote)
547 m_isRemote = isRemote;
549 client()->initializeChildFrame(frame()->view()->frameRect(), frame()->view()->visibleContentScaleFactor());
552 void WebLocalFrameImpl::setRemoteWebLayer(WebLayer* webLayer)
557 frame()->setRemotePlatformLayer(webLayer);
560 void WebLocalFrameImpl::setPermissionClient(WebPermissionClient* permissionClient)
562 m_permissionClient = permissionClient;
565 void WebLocalFrameImpl::setSharedWorkerRepositoryClient(WebSharedWorkerRepositoryClient* client)
567 m_sharedWorkerRepositoryClient = SharedWorkerRepositoryClientImpl::create(client);
570 WebSize WebLocalFrameImpl::scrollOffset() const
572 FrameView* view = frameView();
575 return view->scrollOffset();
578 WebSize WebLocalFrameImpl::minimumScrollOffset() const
580 FrameView* view = frameView();
583 return toIntSize(view->minimumScrollPosition());
586 WebSize WebLocalFrameImpl::maximumScrollOffset() const
588 FrameView* view = frameView();
591 return toIntSize(view->maximumScrollPosition());
594 void WebLocalFrameImpl::setScrollOffset(const WebSize& offset)
596 if (FrameView* view = frameView())
597 view->setScrollOffset(IntPoint(offset.width, offset.height));
600 WebSize WebLocalFrameImpl::contentsSize() const
602 if (FrameView* view = frameView())
603 return view->contentsSize();
607 bool WebLocalFrameImpl::hasVisibleContent() const
609 if (RenderPart* renderer = frame()->ownerRenderer()) {
610 if (renderer->style()->visibility() != VISIBLE)
614 if (FrameView* view = frameView())
615 return view->visibleWidth() > 0 && view->visibleHeight() > 0;
619 WebRect WebLocalFrameImpl::visibleContentRect() const
621 if (FrameView* view = frameView())
622 return view->visibleContentRect();
626 bool WebLocalFrameImpl::hasHorizontalScrollbar() const
628 return frame() && frame()->view() && frame()->view()->horizontalScrollbar();
631 bool WebLocalFrameImpl::hasVerticalScrollbar() const
633 return frame() && frame()->view() && frame()->view()->verticalScrollbar();
636 WebView* WebLocalFrameImpl::view() const
641 void WebLocalFrameImpl::setOpener(WebFrame* opener)
643 // FIXME: Does this need to move up into WebFrame too?
644 if (WebFrame::opener() && !opener && m_client)
645 m_client->didDisownOpener(this);
647 WebFrame::setOpener(opener);
650 if (m_frame && m_frame->document())
651 m_frame->document()->initSecurityContext();
654 WebDocument WebLocalFrameImpl::document() const
656 if (!frame() || !frame()->document())
657 return WebDocument();
658 return WebDocument(frame()->document());
661 WebPerformance WebLocalFrameImpl::performance() const
664 return WebPerformance();
665 return WebPerformance(&frame()->domWindow()->performance());
668 bool WebLocalFrameImpl::dispatchBeforeUnloadEvent()
672 return frame()->loader().shouldClose();
675 void WebLocalFrameImpl::dispatchUnloadEvent()
679 frame()->loader().closeURL();
682 NPObject* WebLocalFrameImpl::windowObject() const
686 return frame()->script().windowScriptNPObject();
689 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object)
691 bindToWindowObject(name, object, 0);
694 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object, void*)
696 if (!frame() || !frame()->script().canExecuteScripts(NotAboutToExecuteScript))
698 frame()->script().bindToWindowObject(frame(), String(name), object);
701 void WebLocalFrameImpl::executeScript(const WebScriptSource& source)
704 TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
705 v8::HandleScope handleScope(toIsolate(frame()));
706 frame()->script().executeScriptInMainWorld(ScriptSourceCode(source.code, source.url, position));
709 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup)
712 RELEASE_ASSERT(worldID > 0);
713 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
715 Vector<ScriptSourceCode> sources;
716 for (unsigned i = 0; i < numSources; ++i) {
717 TextPosition position(OrdinalNumber::fromOneBasedInt(sourcesIn[i].startLine), OrdinalNumber::first());
718 sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position));
721 v8::HandleScope handleScope(toIsolate(frame()));
722 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
725 void WebLocalFrameImpl::setIsolatedWorldSecurityOrigin(int worldID, const WebSecurityOrigin& securityOrigin)
728 DOMWrapperWorld::setIsolatedWorldSecurityOrigin(worldID, securityOrigin.get());
731 void WebLocalFrameImpl::setIsolatedWorldContentSecurityPolicy(int worldID, const WebString& policy)
734 DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(worldID, policy);
737 void WebLocalFrameImpl::setIsolatedWorldHumanReadableName(int worldID, const WebString& humanReadableName)
740 DOMWrapperWorld::setIsolatedWorldHumanReadableName(worldID, humanReadableName);
743 void WebLocalFrameImpl::addMessageToConsole(const WebConsoleMessage& message)
747 MessageLevel webCoreMessageLevel;
748 switch (message.level) {
749 case WebConsoleMessage::LevelDebug:
750 webCoreMessageLevel = DebugMessageLevel;
752 case WebConsoleMessage::LevelLog:
753 webCoreMessageLevel = LogMessageLevel;
755 case WebConsoleMessage::LevelWarning:
756 webCoreMessageLevel = WarningMessageLevel;
758 case WebConsoleMessage::LevelError:
759 webCoreMessageLevel = ErrorMessageLevel;
762 ASSERT_NOT_REACHED();
766 frame()->document()->addConsoleMessage(ConsoleMessage::create(OtherMessageSource, webCoreMessageLevel, message.text));
769 void WebLocalFrameImpl::collectGarbage()
773 if (!frame()->settings()->scriptEnabled())
775 V8GCController::collectGarbage(v8::Isolate::GetCurrent());
778 bool WebLocalFrameImpl::checkIfRunInsecureContent(const WebURL& url) const
781 return frame()->loader().mixedContentChecker()->canFrameInsecureContent(frame()->document()->securityOrigin(), url);
784 v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValue(const WebScriptSource& source)
788 TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
789 return frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source.code, source.url, position));
792 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, WebVector<v8::Local<v8::Value> >* results)
795 RELEASE_ASSERT(worldID > 0);
796 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
798 Vector<ScriptSourceCode> sources;
800 for (unsigned i = 0; i < numSources; ++i) {
801 TextPosition position(OrdinalNumber::fromOneBasedInt(sourcesIn[i].startLine), OrdinalNumber::first());
802 sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position));
806 Vector<v8::Local<v8::Value> > scriptResults;
807 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, &scriptResults);
808 WebVector<v8::Local<v8::Value> > v8Results(scriptResults.size());
809 for (unsigned i = 0; i < scriptResults.size(); i++)
810 v8Results[i] = v8::Local<v8::Value>::New(toIsolate(frame()), scriptResults[i]);
811 results->swap(v8Results);
813 v8::HandleScope handleScope(toIsolate(frame()));
814 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
818 v8::Handle<v8::Value> WebLocalFrameImpl::callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> argv[])
821 return frame()->script().callFunction(function, receiver, argc, argv);
824 v8::Local<v8::Context> WebLocalFrameImpl::mainWorldScriptContext() const
826 return toV8Context(frame(), DOMWrapperWorld::mainWorld());
829 void WebLocalFrameImpl::reload(bool ignoreCache)
832 frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload);
835 void WebLocalFrameImpl::reloadWithOverrideURL(const WebURL& overrideUrl, bool ignoreCache)
838 frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload, overrideUrl);
841 void WebLocalFrameImpl::loadRequest(const WebURLRequest& request)
844 ASSERT(!request.isNull());
845 const ResourceRequest& resourceRequest = request.toResourceRequest();
847 if (resourceRequest.url().protocolIs("javascript")) {
848 loadJavaScriptURL(resourceRequest.url());
852 frame()->loader().load(FrameLoadRequest(0, resourceRequest));
855 void WebLocalFrameImpl::loadHistoryItem(const WebHistoryItem& item, WebHistoryLoadType loadType, WebURLRequest::CachePolicy cachePolicy)
858 RefPtr<HistoryItem> historyItem = PassRefPtr<HistoryItem>(item);
860 frame()->loader().loadHistoryItem(historyItem.get(), static_cast<HistoryLoadType>(loadType), static_cast<ResourceRequestCachePolicy>(cachePolicy));
863 void WebLocalFrameImpl::loadData(const WebData& data, const WebString& mimeType, const WebString& textEncoding, const WebURL& baseURL, const WebURL& unreachableURL, bool replace)
867 // If we are loading substitute data to replace an existing load, then
868 // inherit all of the properties of that original request. This way,
869 // reload will re-attempt the original request. It is essential that
870 // we only do this when there is an unreachableURL since a non-empty
871 // unreachableURL informs FrameLoader::reload to load unreachableURL
872 // instead of the currently loaded URL.
873 ResourceRequest request;
874 if (replace && !unreachableURL.isEmpty() && frame()->loader().provisionalDocumentLoader())
875 request = frame()->loader().provisionalDocumentLoader()->originalRequest();
876 request.setURL(baseURL);
878 FrameLoadRequest frameRequest(0, request, SubstituteData(data, mimeType, textEncoding, unreachableURL));
879 ASSERT(frameRequest.substituteData().isValid());
880 frameRequest.setLockBackForwardList(replace);
881 frame()->loader().load(frameRequest);
884 void WebLocalFrameImpl::loadHTMLString(const WebData& data, const WebURL& baseURL, const WebURL& unreachableURL, bool replace)
887 loadData(data, WebString::fromUTF8("text/html"), WebString::fromUTF8("UTF-8"), baseURL, unreachableURL, replace);
890 void WebLocalFrameImpl::stopLoading()
894 // FIXME: Figure out what we should really do here. It seems like a bug
895 // that FrameLoader::stopLoading doesn't call stopAllLoaders.
896 frame()->loader().stopAllLoaders();
899 WebDataSource* WebLocalFrameImpl::provisionalDataSource() const
903 // We regard the policy document loader as still provisional.
904 DocumentLoader* documentLoader = frame()->loader().provisionalDocumentLoader();
906 documentLoader = frame()->loader().policyDocumentLoader();
908 return DataSourceForDocLoader(documentLoader);
911 WebDataSource* WebLocalFrameImpl::dataSource() const
914 return DataSourceForDocLoader(frame()->loader().documentLoader());
917 void WebLocalFrameImpl::enableViewSourceMode(bool enable)
920 frame()->setInViewSourceMode(enable);
923 bool WebLocalFrameImpl::isViewSourceModeEnabled() const
927 return frame()->inViewSourceMode();
930 void WebLocalFrameImpl::setReferrerForRequest(WebURLRequest& request, const WebURL& referrerURL)
932 String referrer = referrerURL.isEmpty() ? frame()->document()->outgoingReferrer() : String(referrerURL.spec().utf16());
933 referrer = SecurityPolicy::generateReferrerHeader(frame()->document()->referrerPolicy(), request.url(), referrer);
934 if (referrer.isEmpty())
936 request.setHTTPReferrer(referrer, static_cast<WebReferrerPolicy>(frame()->document()->referrerPolicy()));
939 void WebLocalFrameImpl::dispatchWillSendRequest(WebURLRequest& request)
941 ResourceResponse response;
942 frame()->loader().client()->dispatchWillSendRequest(0, 0, request.toMutableResourceRequest(), response);
945 WebURLLoader* WebLocalFrameImpl::createAssociatedURLLoader(const WebURLLoaderOptions& options)
947 return new AssociatedURLLoader(this, options);
950 unsigned WebLocalFrameImpl::unloadListenerCount() const
952 return frame()->domWindow()->pendingUnloadEventListeners();
955 void WebLocalFrameImpl::replaceSelection(const WebString& text)
957 bool selectReplacement = false;
958 bool smartReplace = true;
959 frame()->editor().replaceSelectionWithText(text, selectReplacement, smartReplace);
962 void WebLocalFrameImpl::insertText(const WebString& text)
964 if (frame()->inputMethodController().hasComposition())
965 frame()->inputMethodController().confirmComposition(text);
967 frame()->editor().insertText(text, 0);
970 void WebLocalFrameImpl::setMarkedText(const WebString& text, unsigned location, unsigned length)
972 Vector<CompositionUnderline> decorations;
973 frame()->inputMethodController().setComposition(text, decorations, location, length);
976 void WebLocalFrameImpl::unmarkText()
978 frame()->inputMethodController().cancelComposition();
981 bool WebLocalFrameImpl::hasMarkedText() const
983 return frame()->inputMethodController().hasComposition();
986 WebRange WebLocalFrameImpl::markedRange() const
988 return frame()->inputMethodController().compositionRange();
991 bool WebLocalFrameImpl::firstRectForCharacterRange(unsigned location, unsigned length, WebRect& rect) const
993 if ((location + length < location) && (location + length))
996 Element* editable = frame()->selection().rootEditableElementOrDocumentElement();
998 RefPtrWillBeRawPtr<Range> range = PlainTextRange(location, location + length).createRange(*editable);
1001 IntRect intRect = frame()->editor().firstRectForRange(range.get());
1002 rect = WebRect(intRect);
1003 rect = frame()->view()->contentsToWindow(rect);
1007 size_t WebLocalFrameImpl::characterIndexForPoint(const WebPoint& webPoint) const
1012 IntPoint point = frame()->view()->windowToContents(webPoint);
1013 HitTestResult result = frame()->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active);
1014 RefPtrWillBeRawPtr<Range> range = frame()->rangeForPoint(result.roundedPointInInnerNodeFrame());
1017 Element* editable = frame()->selection().rootEditableElementOrDocumentElement();
1019 return PlainTextRange::create(*editable, *range.get()).start();
1022 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebNode& node)
1026 if (name.length() <= 2)
1029 // Since we don't have NSControl, we will convert the format of command
1030 // string and call the function on Editor directly.
1031 String command = name;
1033 // Make sure the first letter is upper case.
1034 command.replace(0, 1, command.substring(0, 1).upper());
1036 // Remove the trailing ':' if existing.
1037 if (command[command.length() - 1] == UChar(':'))
1038 command = command.substring(0, command.length() - 1);
1040 WebPluginContainerImpl* pluginContainer = pluginContainerFromNode(frame(), node);
1041 if (pluginContainer && pluginContainer->executeEditCommand(name))
1044 return frame()->editor().executeCommand(command);
1047 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebString& value, const WebNode& node)
1051 WebPluginContainerImpl* pluginContainer = pluginContainerFromNode(frame(), node);
1052 if (pluginContainer && pluginContainer->executeEditCommand(name, value))
1055 return frame()->editor().executeCommand(name, value);
1058 bool WebLocalFrameImpl::isCommandEnabled(const WebString& name) const
1061 return frame()->editor().command(name).isEnabled();
1064 void WebLocalFrameImpl::enableContinuousSpellChecking(bool enable)
1066 if (enable == isContinuousSpellCheckingEnabled())
1068 frame()->spellChecker().toggleContinuousSpellChecking();
1071 bool WebLocalFrameImpl::isContinuousSpellCheckingEnabled() const
1073 return frame()->spellChecker().isContinuousSpellCheckingEnabled();
1076 void WebLocalFrameImpl::requestTextChecking(const WebElement& webElement)
1078 if (webElement.isNull())
1080 frame()->spellChecker().requestTextChecking(*webElement.constUnwrap<Element>());
1083 void WebLocalFrameImpl::replaceMisspelledRange(const WebString& text)
1085 // If this caret selection has two or more markers, this function replace the range covered by the first marker with the specified word as Microsoft Word does.
1086 if (pluginContainerFromFrame(frame()))
1088 frame()->spellChecker().replaceMisspelledRange(text);
1091 void WebLocalFrameImpl::removeSpellingMarkers()
1093 frame()->spellChecker().removeSpellingMarkers();
1096 bool WebLocalFrameImpl::hasSelection() const
1098 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1099 if (pluginContainer)
1100 return pluginContainer->plugin()->hasSelection();
1102 // frame()->selection()->isNone() never returns true.
1103 return frame()->selection().start() != frame()->selection().end();
1106 WebRange WebLocalFrameImpl::selectionRange() const
1108 return frame()->selection().toNormalizedRange();
1111 WebString WebLocalFrameImpl::selectionAsText() const
1113 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1114 if (pluginContainer)
1115 return pluginContainer->plugin()->selectionAsText();
1117 RefPtrWillBeRawPtr<Range> range = frame()->selection().toNormalizedRange();
1121 String text = range->text();
1123 replaceNewlinesWithWindowsStyleNewlines(text);
1125 replaceNBSPWithSpace(text);
1129 WebString WebLocalFrameImpl::selectionAsMarkup() const
1131 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1132 if (pluginContainer)
1133 return pluginContainer->plugin()->selectionAsMarkup();
1135 RefPtrWillBeRawPtr<Range> range = frame()->selection().toNormalizedRange();
1139 return createMarkup(range.get(), 0, AnnotateForInterchange, false, ResolveNonLocalURLs);
1142 void WebLocalFrameImpl::selectWordAroundPosition(LocalFrame* frame, VisiblePosition position)
1144 VisibleSelection selection(position);
1145 selection.expandUsingGranularity(WordGranularity);
1147 TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity;
1148 frame->selection().setSelection(selection, granularity);
1151 bool WebLocalFrameImpl::selectWordAroundCaret()
1153 FrameSelection& selection = frame()->selection();
1154 if (selection.isNone() || selection.isRange())
1156 selectWordAroundPosition(frame(), selection.selection().visibleStart());
1160 void WebLocalFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent)
1162 moveRangeSelection(base, extent);
1165 void WebLocalFrameImpl::selectRange(const WebRange& webRange)
1167 if (RefPtrWillBeRawPtr<Range> range = static_cast<PassRefPtrWillBeRawPtr<Range> >(webRange))
1168 frame()->selection().setSelectedRange(range.get(), VP_DEFAULT_AFFINITY, FrameSelection::NonDirectional, NotUserTriggered);
1171 void WebLocalFrameImpl::moveRangeSelection(const WebPoint& base, const WebPoint& extent)
1173 VisiblePosition basePosition = visiblePositionForWindowPoint(base);
1174 VisiblePosition extentPosition = visiblePositionForWindowPoint(extent);
1175 VisibleSelection newSelection = VisibleSelection(basePosition, extentPosition);
1176 frame()->selection().setSelection(newSelection, CharacterGranularity);
1179 void WebLocalFrameImpl::moveCaretSelection(const WebPoint& point)
1181 Element* editable = frame()->selection().rootEditableElement();
1185 VisiblePosition position = visiblePositionForWindowPoint(point);
1186 frame()->selection().moveTo(position, UserTriggered);
1189 bool WebLocalFrameImpl::setEditableSelectionOffsets(int start, int end)
1191 return frame()->inputMethodController().setEditableSelectionOffsets(PlainTextRange(start, end));
1194 bool WebLocalFrameImpl::setCompositionFromExistingText(int compositionStart, int compositionEnd, const WebVector<WebCompositionUnderline>& underlines)
1196 if (!frame()->editor().canEdit())
1199 InputMethodController& inputMethodController = frame()->inputMethodController();
1200 inputMethodController.cancelComposition();
1202 if (compositionStart == compositionEnd)
1205 inputMethodController.setCompositionFromExistingText(CompositionUnderlineVectorBuilder(underlines), compositionStart, compositionEnd);
1210 void WebLocalFrameImpl::extendSelectionAndDelete(int before, int after)
1212 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported()) {
1213 plugin->extendSelectionAndDelete(before, after);
1216 frame()->inputMethodController().extendSelectionAndDelete(before, after);
1219 void WebLocalFrameImpl::setCaretVisible(bool visible)
1221 frame()->selection().setCaretVisible(visible);
1224 VisiblePosition WebLocalFrameImpl::visiblePositionForWindowPoint(const WebPoint& point)
1226 // FIXME(bokan): crbug.com/371902 - These scale/pinch transforms shouldn't
1227 // be ad hoc and explicit.
1228 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
1229 FloatPoint unscaledPoint(point);
1230 unscaledPoint.scale(1 / view()->pageScaleFactor(), 1 / view()->pageScaleFactor());
1231 unscaledPoint.moveBy(pinchViewport.visibleRect().location());
1233 HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping;
1234 HitTestResult result(frame()->view()->windowToContents(roundedIntPoint(unscaledPoint)));
1235 frame()->document()->renderView()->layer()->hitTest(request, result);
1237 if (Node* node = result.innerNode())
1238 return frame()->selection().selection().visiblePositionRespectingEditingBoundary(result.localPoint(), node);
1239 return VisiblePosition();
1242 WebPlugin* WebLocalFrameImpl::focusedPluginIfInputMethodSupported()
1244 WebPluginContainerImpl* container = WebLocalFrameImpl::pluginContainerFromNode(frame(), WebNode(frame()->document()->focusedElement()));
1245 if (container && container->supportsInputMethod())
1246 return container->plugin();
1250 int WebLocalFrameImpl::printBegin(const WebPrintParams& printParams, const WebNode& constrainToNode)
1252 ASSERT(!frame()->document()->isFrameSet());
1253 WebPluginContainerImpl* pluginContainer = 0;
1254 if (constrainToNode.isNull()) {
1255 // If this is a plugin document, check if the plugin supports its own
1256 // printing. If it does, we will delegate all printing to that.
1257 pluginContainer = pluginContainerFromFrame(frame());
1259 // We only support printing plugin nodes for now.
1260 pluginContainer = toWebPluginContainerImpl(constrainToNode.pluginContainer());
1263 if (pluginContainer && pluginContainer->supportsPaginatedPrint())
1264 m_printContext = adoptPtrWillBeNoop(new ChromePluginPrintContext(frame(), pluginContainer, printParams));
1266 m_printContext = adoptPtrWillBeNoop(new ChromePrintContext(frame()));
1268 FloatRect rect(0, 0, static_cast<float>(printParams.printContentArea.width), static_cast<float>(printParams.printContentArea.height));
1269 m_printContext->begin(rect.width(), rect.height());
1271 // We ignore the overlays calculation for now since they are generated in the
1272 // browser. pageHeight is actually an output parameter.
1273 m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight);
1275 return static_cast<int>(m_printContext->pageCount());
1278 float WebLocalFrameImpl::getPrintPageShrink(int page)
1280 ASSERT(m_printContext && page >= 0);
1281 return m_printContext->getPageShrink(page);
1284 float WebLocalFrameImpl::printPage(int page, WebCanvas* canvas)
1286 #if ENABLE(PRINTING)
1287 ASSERT(m_printContext && page >= 0 && frame() && frame()->document());
1289 GraphicsContext graphicsContext(canvas);
1290 graphicsContext.setPrinting(true);
1291 return m_printContext->spoolSinglePage(graphicsContext, page);
1297 void WebLocalFrameImpl::printEnd()
1299 ASSERT(m_printContext);
1300 m_printContext->end();
1301 m_printContext.clear();
1304 bool WebLocalFrameImpl::isPrintScalingDisabledForPlugin(const WebNode& node)
1306 WebPluginContainerImpl* pluginContainer = node.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node.pluginContainer());
1308 if (!pluginContainer || !pluginContainer->supportsPaginatedPrint())
1311 return pluginContainer->isPrintScalingDisabled();
1314 int WebLocalFrameImpl::getPrintCopiesForPlugin(const WebNode& node)
1316 WebPluginContainerImpl* pluginContainer = node.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node.pluginContainer());
1318 if (!pluginContainer || !pluginContainer->supportsPaginatedPrint())
1321 return pluginContainer->getCopiesToPrint();
1324 bool WebLocalFrameImpl::hasCustomPageSizeStyle(int pageIndex)
1326 return frame()->document()->styleForPage(pageIndex)->pageSizeType() != PAGE_SIZE_AUTO;
1329 bool WebLocalFrameImpl::isPageBoxVisible(int pageIndex)
1331 return frame()->document()->isPageBoxVisible(pageIndex);
1334 void WebLocalFrameImpl::pageSizeAndMarginsInPixels(int pageIndex, WebSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
1336 IntSize size = pageSize;
1337 frame()->document()->pageSizeAndMarginsInPixels(pageIndex, size, marginTop, marginRight, marginBottom, marginLeft);
1341 WebString WebLocalFrameImpl::pageProperty(const WebString& propertyName, int pageIndex)
1343 ASSERT(m_printContext);
1344 return m_printContext->pageProperty(frame(), propertyName.utf8().data(), pageIndex);
1347 bool WebLocalFrameImpl::find(int identifier, const WebString& searchText, const WebFindOptions& options, bool wrapWithinFrame, WebRect* selectionRect)
1349 return ensureTextFinder().find(identifier, searchText, options, wrapWithinFrame, selectionRect);
1352 void WebLocalFrameImpl::stopFinding(bool clearSelection)
1355 if (!clearSelection)
1356 setFindEndstateFocusAndSelection();
1357 m_textFinder->stopFindingAndClearSelection();
1361 void WebLocalFrameImpl::scopeStringMatches(int identifier, const WebString& searchText, const WebFindOptions& options, bool reset)
1363 ensureTextFinder().scopeStringMatches(identifier, searchText, options, reset);
1366 void WebLocalFrameImpl::cancelPendingScopingEffort()
1369 m_textFinder->cancelPendingScopingEffort();
1372 void WebLocalFrameImpl::increaseMatchCount(int count, int identifier)
1374 // This function should only be called on the mainframe.
1376 ensureTextFinder().increaseMatchCount(identifier, count);
1379 void WebLocalFrameImpl::resetMatchCount()
1381 ensureTextFinder().resetMatchCount();
1384 void WebLocalFrameImpl::dispatchMessageEventWithOriginCheck(const WebSecurityOrigin& intendedTargetOrigin, const WebDOMEvent& event)
1386 ASSERT(!event.isNull());
1387 frame()->domWindow()->dispatchMessageEventWithOriginCheck(intendedTargetOrigin.get(), event, nullptr);
1390 int WebLocalFrameImpl::findMatchMarkersVersion() const
1395 return m_textFinder->findMatchMarkersVersion();
1399 int WebLocalFrameImpl::selectNearestFindMatch(const WebFloatPoint& point, WebRect* selectionRect)
1402 return ensureTextFinder().selectNearestFindMatch(point, selectionRect);
1405 WebFloatRect WebLocalFrameImpl::activeFindMatchRect()
1410 return m_textFinder->activeFindMatchRect();
1411 return WebFloatRect();
1414 void WebLocalFrameImpl::findMatchRects(WebVector<WebFloatRect>& outputRects)
1417 ensureTextFinder().findMatchRects(outputRects);
1420 void WebLocalFrameImpl::setTickmarks(const WebVector<WebRect>& tickmarks)
1423 Vector<IntRect> tickmarksConverted(tickmarks.size());
1424 for (size_t i = 0; i < tickmarks.size(); ++i)
1425 tickmarksConverted[i] = tickmarks[i];
1426 frameView()->setTickmarks(tickmarksConverted);
1427 invalidateScrollbar();
1431 WebString WebLocalFrameImpl::contentAsText(size_t maxChars) const
1436 frameContentAsPlainText(maxChars, frame(), text);
1437 return text.toString();
1440 WebString WebLocalFrameImpl::contentAsMarkup() const
1444 return createMarkup(frame()->document());
1447 WebString WebLocalFrameImpl::renderTreeAsText(RenderAsTextControls toShow) const
1449 RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal;
1451 if (toShow & RenderAsTextDebug)
1452 behavior |= RenderAsTextShowCompositedLayers | RenderAsTextShowAddresses | RenderAsTextShowIDAndClass | RenderAsTextShowLayerNesting;
1454 if (toShow & RenderAsTextPrinting)
1455 behavior |= RenderAsTextPrintingMode;
1457 return externalRepresentation(frame(), behavior);
1460 WebString WebLocalFrameImpl::markerTextForListItem(const WebElement& webElement) const
1462 return blink::markerTextForListItem(const_cast<Element*>(webElement.constUnwrap<Element>()));
1465 void WebLocalFrameImpl::printPagesWithBoundaries(WebCanvas* canvas, const WebSize& pageSizeInPixels)
1467 ASSERT(m_printContext);
1469 GraphicsContext graphicsContext(canvas);
1470 graphicsContext.setPrinting(true);
1472 m_printContext->spoolAllPagesWithBoundaries(graphicsContext, FloatSize(pageSizeInPixels.width, pageSizeInPixels.height));
1475 WebRect WebLocalFrameImpl::selectionBoundsRect() const
1477 return hasSelection() ? WebRect(IntRect(frame()->selection().bounds())) : WebRect();
1480 bool WebLocalFrameImpl::selectionStartHasSpellingMarkerFor(int from, int length) const
1484 return frame()->spellChecker().selectionStartHasSpellingMarkerFor(from, length);
1487 WebString WebLocalFrameImpl::layerTreeAsText(bool showDebugInfo) const
1492 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesDebugInfo : LayerTreeNormal));
1495 // WebLocalFrameImpl public ---------------------------------------------------------
1497 WebLocalFrame* WebLocalFrame::create(WebFrameClient* client)
1499 return WebLocalFrameImpl::create(client);
1502 WebLocalFrameImpl* WebLocalFrameImpl::create(WebFrameClient* client)
1504 WebLocalFrameImpl* frame = new WebLocalFrameImpl(client);
1508 return adoptRef(frame).leakRef();
1512 WebLocalFrameImpl::WebLocalFrameImpl(WebFrameClient* client)
1513 : m_frameLoaderClientImpl(this)
1515 , m_permissionClient(0)
1516 , m_inputEventsScaleFactorForEmulation(1)
1517 , m_userMediaClientImpl(this)
1518 , m_geolocationClientProxy(GeolocationClientProxy::create(client ? client->geolocationClient() : 0))
1520 , m_selfKeepAlive(this)
1523 Platform::current()->incrementStatsCounter(webFrameActiveCount);
1527 WebLocalFrameImpl::~WebLocalFrameImpl()
1529 Platform::current()->decrementStatsCounter(webFrameActiveCount);
1532 cancelPendingScopingEffort();
1535 void WebLocalFrameImpl::trace(Visitor* visitor)
1538 visitor->trace(m_frame);
1539 visitor->trace(m_printContext);
1540 visitor->trace(m_geolocationClientProxy);
1542 WebFrame::traceChildren(visitor, this);
1546 void WebLocalFrameImpl::setCoreFrame(PassRefPtrWillBeRawPtr<LocalFrame> frame)
1550 // FIXME: we shouldn't add overhead to every frame by registering these objects when they're not used.
1552 OwnPtr<NotificationPresenterImpl> notificationPresenter = adoptPtr(new NotificationPresenterImpl());
1554 notificationPresenter->initialize(m_client->notificationPresenter());
1556 provideNotification(*m_frame, notificationPresenter.release());
1557 provideNotificationPermissionClientTo(*m_frame, NotificationPermissionClientImpl::create());
1558 provideUserMediaTo(*m_frame, &m_userMediaClientImpl);
1559 provideGeolocationTo(*m_frame, m_geolocationClientProxy.get());
1560 m_geolocationClientProxy->setController(GeolocationController::from(m_frame.get()));
1561 provideMIDITo(*m_frame, MIDIClientProxy::create(m_client ? m_client->webMIDIClient() : 0));
1562 provideLocalFileSystemTo(*m_frame, LocalFileSystemClient::create());
1564 if (RuntimeEnabledFeatures::screenOrientationEnabled())
1565 ScreenOrientationController::provideTo(*m_frame, m_client ? m_client->webScreenOrientationClient() : 0);
1569 PassRefPtrWillBeRawPtr<LocalFrame> WebLocalFrameImpl::initializeCoreFrame(FrameHost* host, FrameOwner* owner, const AtomicString& name, const AtomicString& fallbackName)
1571 RefPtrWillBeRawPtr<LocalFrame> frame = LocalFrame::create(&m_frameLoaderClientImpl, host, owner);
1572 setCoreFrame(frame);
1573 frame->tree().setName(name, fallbackName);
1574 // We must call init() after m_frame is assigned because it is referenced
1575 // during init(). Note that this may dispatch JS events; the frame may be
1576 // detached after init() returns.
1581 PassRefPtrWillBeRawPtr<LocalFrame> WebLocalFrameImpl::createChildFrame(const FrameLoadRequest& request, HTMLFrameOwnerElement* ownerElement)
1584 WebLocalFrameImpl* webframeChild = toWebLocalFrameImpl(m_client->createChildFrame(this, request.frameName()));
1588 // FIXME: Using subResourceAttributeName as fallback is not a perfect
1589 // solution. subResourceAttributeName returns just one attribute name. The
1590 // element might not have the attribute, and there might be other attributes
1591 // which can identify the element.
1592 RefPtrWillBeRawPtr<LocalFrame> child = webframeChild->initializeCoreFrame(frame()->host(), ownerElement, request.frameName(), ownerElement->getAttribute(ownerElement->subResourceAttributeName()));
1593 // Initializing the core frame may cause the new child to be detached, since
1594 // it may dispatch a load event in the parent.
1595 if (!child->tree().parent())
1598 // If we're moving in the back/forward list, we might want to replace the content
1599 // of this child frame with whatever was there at that point.
1600 RefPtr<HistoryItem> childItem;
1601 if (isBackForwardLoadType(frame()->loader().loadType()) && !frame()->document()->loadEventFinished())
1602 childItem = PassRefPtr<HistoryItem>(webframeChild->client()->historyItemForNewChildFrame(webframeChild));
1605 child->loader().loadHistoryItem(childItem.get());
1607 child->loader().load(FrameLoadRequest(0, request.resourceRequest(), "_self"));
1609 // Note a synchronous navigation (about:blank) would have already processed
1610 // onload, so it is possible for the child frame to have already been
1611 // detached by script in the page.
1612 if (!child->tree().parent())
1617 void WebLocalFrameImpl::didChangeContentsSize(const IntSize& size)
1619 // This is only possible on the main frame.
1620 if (m_textFinder && m_textFinder->totalMatchCount() > 0) {
1622 m_textFinder->increaseMarkerVersion();
1626 void WebLocalFrameImpl::createFrameView()
1628 TRACE_EVENT0("blink", "WebLocalFrameImpl::createFrameView");
1630 ASSERT(frame()); // If frame() doesn't exist, we probably didn't init properly.
1632 WebViewImpl* webView = viewImpl();
1633 bool isLocalRoot = frame()->isLocalRoot();
1635 webView->suppressInvalidations(true);
1637 frame()->createView(webView->size(), webView->baseBackgroundColor(), webView->isTransparent());
1638 if (webView->shouldAutoResize() && isLocalRoot)
1639 frame()->view()->enableAutoSizeMode(webView->minAutoSize(), webView->maxAutoSize());
1641 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation, m_inputEventsScaleFactorForEmulation);
1644 webView->suppressInvalidations(false);
1647 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame* frame)
1651 return fromFrame(*frame);
1654 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame& frame)
1656 FrameLoaderClient* client = frame.loader().client();
1657 if (!client || !client->isFrameLoaderClientImpl())
1659 return toFrameLoaderClientImpl(client)->webFrame();
1662 WebLocalFrameImpl* WebLocalFrameImpl::fromFrameOwnerElement(Element* element)
1664 // FIXME: Why do we check specifically for <iframe> and <frame> here? Why can't we get the WebLocalFrameImpl from an <object> element, for example.
1665 if (!isHTMLFrameElementBase(element))
1667 return fromFrame(toLocalFrame(toHTMLFrameElementBase(element)->contentFrame()));
1670 WebViewImpl* WebLocalFrameImpl::viewImpl() const
1674 return WebViewImpl::fromPage(frame()->page());
1677 WebDataSourceImpl* WebLocalFrameImpl::dataSourceImpl() const
1679 return static_cast<WebDataSourceImpl*>(dataSource());
1682 WebDataSourceImpl* WebLocalFrameImpl::provisionalDataSourceImpl() const
1684 return static_cast<WebDataSourceImpl*>(provisionalDataSource());
1687 void WebLocalFrameImpl::setFindEndstateFocusAndSelection()
1689 WebLocalFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1691 if (this != mainFrameImpl->activeMatchFrame())
1694 if (Range* activeMatch = m_textFinder->activeMatch()) {
1695 // If the user has set the selection since the match was found, we
1696 // don't focus anything.
1697 VisibleSelection selection(frame()->selection().selection());
1698 if (!selection.isNone())
1701 // Need to clean out style and layout state before querying Element::isFocusable().
1702 frame()->document()->updateLayoutIgnorePendingStylesheets();
1704 // Try to find the first focusable node up the chain, which will, for
1705 // example, focus links if we have found text within the link.
1706 Node* node = activeMatch->firstNode();
1707 if (node && node->isInShadowTree()) {
1708 if (Node* host = node->shadowHost()) {
1709 if (isHTMLInputElement(*host) || isHTMLTextAreaElement(*host))
1713 for (; node; node = node->parentNode()) {
1714 if (!node->isElementNode())
1716 Element* element = toElement(node);
1717 if (element->isFocusable()) {
1718 // Found a focusable parent node. Set the active match as the
1719 // selection and focus to the focusable node.
1720 frame()->selection().setSelection(VisibleSelection(activeMatch));
1721 frame()->document()->setFocusedElement(element);
1726 // Iterate over all the nodes in the range until we find a focusable node.
1727 // This, for example, sets focus to the first link if you search for
1728 // text and text that is within one or more links.
1729 node = activeMatch->firstNode();
1730 for (; node && node != activeMatch->pastLastNode(); node = NodeTraversal::next(*node)) {
1731 if (!node->isElementNode())
1733 Element* element = toElement(node);
1734 if (element->isFocusable()) {
1735 frame()->document()->setFocusedElement(element);
1740 // No node related to the active match was focusable, so set the
1741 // active match as the selection (so that when you end the Find session,
1742 // you'll have the last thing you found highlighted) and make sure that
1743 // we have nothing focused (otherwise you might have text selected but
1744 // a link focused, which is weird).
1745 frame()->selection().setSelection(VisibleSelection(activeMatch));
1746 frame()->document()->setFocusedElement(nullptr);
1748 // Finally clear the active match, for two reasons:
1749 // We just finished the find 'session' and we don't want future (potentially
1750 // unrelated) find 'sessions' operations to start at the same place.
1751 // The WebLocalFrameImpl could get reused and the activeMatch could end up pointing
1752 // to a document that is no longer valid. Keeping an invalid reference around
1753 // is just asking for trouble.
1754 m_textFinder->resetActiveMatch();
1758 void WebLocalFrameImpl::didFail(const ResourceError& error, bool wasProvisional)
1762 WebURLError webError = error;
1764 client()->didFailProvisionalLoad(this, webError);
1766 client()->didFailLoad(this, webError);
1769 void WebLocalFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars)
1771 frame()->view()->setCanHaveScrollbars(canHaveScrollbars);
1774 void WebLocalFrameImpl::setInputEventsTransformForEmulation(const IntSize& offset, float contentScaleFactor)
1776 m_inputEventsOffsetForEmulation = offset;
1777 m_inputEventsScaleFactorForEmulation = contentScaleFactor;
1778 if (frame()->view())
1779 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation, m_inputEventsScaleFactorForEmulation);
1782 void WebLocalFrameImpl::loadJavaScriptURL(const KURL& url)
1784 // This is copied from ScriptController::executeScriptIfJavaScriptURL.
1785 // Unfortunately, we cannot just use that method since it is private, and
1786 // it also doesn't quite behave as we require it to for bookmarklets. The
1787 // key difference is that we need to suppress loading the string result
1788 // from evaluating the JS URL if executing the JS URL resulted in a
1789 // location change. We also allow a JS URL to be loaded even if scripts on
1790 // the page are otherwise disabled.
1792 if (!frame()->document() || !frame()->page())
1795 RefPtrWillBeRawPtr<Document> ownerDocument(frame()->document());
1797 // Protect privileged pages against bookmarklets and other javascript manipulations.
1798 if (SchemeRegistry::shouldTreatURLSchemeAsNotAllowingJavascriptURLs(frame()->document()->url().protocol()))
1801 String script = decodeURLEscapeSequences(url.string().substring(strlen("javascript:")));
1802 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
1803 v8::HandleScope handleScope(toIsolate(frame()));
1804 v8::Local<v8::Value> result = frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script));
1805 if (result.IsEmpty() || !result->IsString())
1807 String scriptResult = toCoreString(v8::Handle<v8::String>::Cast(result));
1808 if (!frame()->navigationScheduler().locationChangePending())
1809 frame()->loader().replaceDocumentWhileExecutingJavaScriptURL(scriptResult, ownerDocument.get());
1812 void WebLocalFrameImpl::sendPings(const WebNode& linkNode, const WebURL& destinationURL)
1815 const Node* node = linkNode.constUnwrap<Node>();
1816 if (isHTMLAnchorElement(node))
1817 toHTMLAnchorElement(node)->sendPings(destinationURL);
1820 bool WebLocalFrameImpl::isLoading() const
1822 if (!frame() || !frame()->document())
1824 return frame()->loader().stateMachine()->isDisplayingInitialEmptyDocument() || !frame()->document()->loadEventFinished();
1827 bool WebLocalFrameImpl::isResourceLoadInProgress() const
1829 if (!frame() || !frame()->document())
1831 return frame()->document()->fetcher()->requestCount();
1834 void WebLocalFrameImpl::addStyleSheetByURL(const WebString& url)
1836 RefPtrWillBeRawPtr<Element> styleElement = frame()->document()->createElement(HTMLNames::linkTag, false);
1838 styleElement->setAttribute(HTMLNames::typeAttr, "text/css");
1839 styleElement->setAttribute(HTMLNames::relAttr, "stylesheet");
1840 styleElement->setAttribute(HTMLNames::hrefAttr, url);
1842 frame()->document()->head()->appendChild(styleElement.release(), IGNORE_EXCEPTION);
1845 void WebLocalFrameImpl::navigateToSandboxedMarkup(const WebData& markup)
1847 ASSERT(document().securityOrigin().isUnique());
1848 frame()->loader().forceSandboxFlags(SandboxAll);
1849 loadHTMLString(markup, document().url(), WebURL(), true);
1852 void WebLocalFrameImpl::sendOrientationChangeEvent()
1857 // Screen Orientation API
1858 if (ScreenOrientationController::from(*frame()))
1859 ScreenOrientationController::from(*frame())->notifyOrientationChanged();
1861 // Legacy window.orientation API.
1862 if (RuntimeEnabledFeatures::orientationEventEnabled() && frame()->domWindow())
1863 frame()->domWindow()->dispatchEvent(Event::create(EventTypeNames::orientationchange));
1866 v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValueForTests(const WebScriptSource& source)
1868 // FIXME: This fake UserGestureIndicator is required for a bunch of browser
1869 // tests to pass. We should update the tests to simulate input and get rid
1871 // http://code.google.com/p/chromium/issues/detail?id=86397
1872 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
1873 return executeScriptAndReturnValue(source);
1876 void WebLocalFrameImpl::willDetachParent()
1878 // Do not expect string scoping results from any frames that got detached
1879 // in the middle of the operation.
1880 if (m_textFinder && m_textFinder->scopingInProgress()) {
1882 // There is a possibility that the frame being detached was the only
1883 // pending one. We need to make sure final replies can be sent.
1884 m_textFinder->flushCurrentScoping();
1886 m_textFinder->cancelPendingScopingEffort();
1890 WebLocalFrameImpl* WebLocalFrameImpl::activeMatchFrame() const
1895 return m_textFinder->activeMatchFrame();
1899 Range* WebLocalFrameImpl::activeMatch() const
1902 return m_textFinder->activeMatch();
1906 TextFinder& WebLocalFrameImpl::ensureTextFinder()
1909 m_textFinder = TextFinder::create(*this);
1911 return *m_textFinder;
1914 void WebLocalFrameImpl::invalidateScrollbar() const
1916 ASSERT(frame() && frame()->view());
1917 FrameView* view = frame()->view();
1918 // Invalidate the vertical scroll bar region for the view.
1919 Scrollbar* scrollbar = view->verticalScrollbar();
1921 scrollbar->invalidate();
1924 void WebLocalFrameImpl::invalidateAll() const
1926 ASSERT(frame() && frame()->view());
1927 FrameView* view = frame()->view();
1928 view->invalidateRect(view->frameRect());
1929 invalidateScrollbar();
1932 } // namespace blink