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 WebCore.
54 // How frames are destroyed
55 // ------------------------
57 // The main frame is never destroyed and is re-used. The FrameLoader is re-used
58 // and a reference to the main frame is kept by the Page.
60 // When frame content is replaced, all subframes are destroyed. This happens
61 // in FrameLoader::detachFromParent for each subframe in a pre-order depth-first
62 // traversal. Note that child node order may not match DOM node order!
63 // detachFromParent() calls FrameLoaderClient::detachedFromParent(), which calls
64 // WebFrame::frameDetached(). This triggers WebFrame to clear its reference to
65 // LocalFrame, and also notifies the embedder via WebFrameClient that the frame is
66 // detached. Most embedders will invoke close() on the WebFrame at this point,
67 // triggering its deletion unless something else is still retaining a reference.
69 // Thie client is expected to be set whenever the WebLocalFrameImpl is attached to
73 #include "web/WebLocalFrameImpl.h"
75 #include "bindings/v8/DOMWrapperWorld.h"
76 #include "bindings/v8/ExceptionState.h"
77 #include "bindings/v8/ExceptionStatePlaceholder.h"
78 #include "bindings/v8/ScriptController.h"
79 #include "bindings/v8/ScriptSourceCode.h"
80 #include "bindings/v8/ScriptValue.h"
81 #include "bindings/v8/V8GCController.h"
82 #include "bindings/v8/V8PerIsolateData.h"
83 #include "core/HTMLNames.h"
84 #include "core/dom/Document.h"
85 #include "core/dom/DocumentMarker.h"
86 #include "core/dom/DocumentMarkerController.h"
87 #include "core/dom/IconURL.h"
88 #include "core/dom/MessagePort.h"
89 #include "core/dom/Node.h"
90 #include "core/dom/NodeTraversal.h"
91 #include "core/dom/shadow/ShadowRoot.h"
92 #include "core/editing/Editor.h"
93 #include "core/editing/FrameSelection.h"
94 #include "core/editing/InputMethodController.h"
95 #include "core/editing/PlainTextRange.h"
96 #include "core/editing/SpellChecker.h"
97 #include "core/editing/TextAffinity.h"
98 #include "core/editing/TextIterator.h"
99 #include "core/editing/htmlediting.h"
100 #include "core/editing/markup.h"
101 #include "core/frame/Console.h"
102 #include "core/frame/LocalDOMWindow.h"
103 #include "core/frame/FrameHost.h"
104 #include "core/frame/FrameView.h"
105 #include "core/frame/Settings.h"
106 #include "core/html/HTMLCollection.h"
107 #include "core/html/HTMLFormElement.h"
108 #include "core/html/HTMLFrameElementBase.h"
109 #include "core/html/HTMLFrameOwnerElement.h"
110 #include "core/html/HTMLHeadElement.h"
111 #include "core/html/HTMLInputElement.h"
112 #include "core/html/HTMLLinkElement.h"
113 #include "core/html/PluginDocument.h"
114 #include "core/inspector/InspectorController.h"
115 #include "core/inspector/ScriptCallStack.h"
116 #include "core/loader/DocumentLoader.h"
117 #include "core/loader/FrameLoadRequest.h"
118 #include "core/loader/FrameLoader.h"
119 #include "core/loader/HistoryItem.h"
120 #include "core/loader/SubstituteData.h"
121 #include "core/page/Chrome.h"
122 #include "core/page/EventHandler.h"
123 #include "core/page/FocusController.h"
124 #include "core/page/FrameTree.h"
125 #include "core/page/Page.h"
126 #include "core/page/PrintContext.h"
127 #include "core/rendering/HitTestResult.h"
128 #include "core/rendering/RenderBox.h"
129 #include "core/rendering/RenderFrame.h"
130 #include "core/rendering/RenderLayer.h"
131 #include "core/rendering/RenderObject.h"
132 #include "core/rendering/RenderTreeAsText.h"
133 #include "core/rendering/RenderView.h"
134 #include "core/rendering/style/StyleInheritedData.h"
135 #include "core/timing/Performance.h"
136 #include "modules/geolocation/GeolocationController.h"
137 #include "modules/notifications/NotificationController.h"
138 #include "modules/screen_orientation/ScreenOrientationController.h"
139 #include "platform/TraceEvent.h"
140 #include "platform/UserGestureIndicator.h"
141 #include "platform/clipboard/ClipboardUtilities.h"
142 #include "platform/fonts/FontCache.h"
143 #include "platform/graphics/GraphicsContext.h"
144 #include "platform/graphics/GraphicsLayerClient.h"
145 #include "platform/graphics/skia/SkiaUtils.h"
146 #include "platform/heap/Handle.h"
147 #include "platform/network/ResourceRequest.h"
148 #include "platform/scroll/ScrollTypes.h"
149 #include "platform/scroll/ScrollbarTheme.h"
150 #include "platform/weborigin/KURL.h"
151 #include "platform/weborigin/SchemeRegistry.h"
152 #include "platform/weborigin/SecurityPolicy.h"
153 #include "public/platform/Platform.h"
154 #include "public/platform/WebFloatPoint.h"
155 #include "public/platform/WebFloatRect.h"
156 #include "public/platform/WebLayer.h"
157 #include "public/platform/WebPoint.h"
158 #include "public/platform/WebRect.h"
159 #include "public/platform/WebSize.h"
160 #include "public/platform/WebURLError.h"
161 #include "public/platform/WebVector.h"
162 #include "public/web/WebConsoleMessage.h"
163 #include "public/web/WebDOMEvent.h"
164 #include "public/web/WebDOMEventListener.h"
165 #include "public/web/WebDocument.h"
166 #include "public/web/WebFindOptions.h"
167 #include "public/web/WebFormElement.h"
168 #include "public/web/WebFrameClient.h"
169 #include "public/web/WebHistoryItem.h"
170 #include "public/web/WebIconURL.h"
171 #include "public/web/WebInputElement.h"
172 #include "public/web/WebNode.h"
173 #include "public/web/WebPerformance.h"
174 #include "public/web/WebPlugin.h"
175 #include "public/web/WebPrintParams.h"
176 #include "public/web/WebRange.h"
177 #include "public/web/WebScriptSource.h"
178 #include "public/web/WebSecurityOrigin.h"
179 #include "public/web/WebSerializedScriptValue.h"
180 #include "web/AssociatedURLLoader.h"
181 #include "web/CompositionUnderlineVectorBuilder.h"
182 #include "web/EventListenerWrapper.h"
183 #include "web/FindInPageCoordinates.h"
184 #include "web/GeolocationClientProxy.h"
185 #include "web/LocalFileSystemClient.h"
186 #include "web/MIDIClientProxy.h"
187 #include "web/PageOverlay.h"
188 #include "web/SharedWorkerRepositoryClientImpl.h"
189 #include "web/TextFinder.h"
190 #include "web/WebDataSourceImpl.h"
191 #include "web/WebDevToolsAgentPrivate.h"
192 #include "web/WebPluginContainerImpl.h"
193 #include "web/WebViewImpl.h"
194 #include "wtf/CurrentTime.h"
195 #include "wtf/HashMap.h"
198 using namespace WebCore;
202 static int frameCount = 0;
204 // Key for a StatsCounter tracking how many WebFrames are active.
205 static const char webFrameActiveCount[] = "WebFrameActiveCount";
207 static void frameContentAsPlainText(size_t maxChars, LocalFrame* frame, StringBuilder& output)
209 Document* document = frame->document();
216 // TextIterator iterates over the visual representation of the DOM. As such,
217 // it requires you to do a layout before using it (otherwise it'll crash).
218 document->updateLayout();
220 // Select the document body.
221 RefPtrWillBeRawPtr<Range> range(document->createRange());
222 TrackExceptionState exceptionState;
223 range->selectNodeContents(document->body(), exceptionState);
225 if (!exceptionState.hadException()) {
226 // The text iterator will walk nodes giving us text. This is similar to
227 // the plainText() function in core/editing/TextIterator.h, but we implement the maximum
228 // size and also copy the results directly into a wstring, avoiding the
229 // string conversion.
230 for (TextIterator it(range.get()); !it.atEnd(); it.advance()) {
231 it.appendTextToStringBuilder(output, 0, maxChars - output.length());
232 if (output.length() >= maxChars)
233 return; // Filled up the buffer.
237 // The separator between frames when the frames are converted to plain text.
238 const LChar frameSeparator[] = { '\n', '\n' };
239 const size_t frameSeparatorLength = WTF_ARRAY_LENGTH(frameSeparator);
241 // Recursively walk the children.
242 const FrameTree& frameTree = frame->tree();
243 for (Frame* curChild = frameTree.firstChild(); curChild; curChild = curChild->tree().nextSibling()) {
244 if (!curChild->isLocalFrame())
246 LocalFrame* curLocalChild = toLocalFrame(curChild);
247 // Ignore the text of non-visible frames.
248 RenderView* contentRenderer = curLocalChild->contentRenderer();
249 RenderPart* ownerRenderer = curLocalChild->ownerRenderer();
250 if (!contentRenderer || !contentRenderer->width() || !contentRenderer->height()
251 || (contentRenderer->x() + contentRenderer->width() <= 0) || (contentRenderer->y() + contentRenderer->height() <= 0)
252 || (ownerRenderer && ownerRenderer->style() && ownerRenderer->style()->visibility() != VISIBLE)) {
256 // Make sure the frame separator won't fill up the buffer, and give up if
257 // it will. The danger is if the separator will make the buffer longer than
258 // maxChars. This will cause the computation above:
259 // maxChars - output->size()
260 // to be a negative number which will crash when the subframe is added.
261 if (output.length() >= maxChars - frameSeparatorLength)
264 output.append(frameSeparator, frameSeparatorLength);
265 frameContentAsPlainText(maxChars, curLocalChild, output);
266 if (output.length() >= maxChars)
267 return; // Filled up the buffer.
271 WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromFrame(LocalFrame* frame)
275 if (!frame->document() || !frame->document()->isPluginDocument())
277 PluginDocument* pluginDocument = toPluginDocument(frame->document());
278 return toWebPluginContainerImpl(pluginDocument->pluginWidget());
281 WebPluginContainerImpl* WebLocalFrameImpl::pluginContainerFromNode(WebCore::LocalFrame* frame, const WebNode& node)
283 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame);
285 return pluginContainer;
286 return toWebPluginContainerImpl(node.pluginContainer());
289 // Simple class to override some of PrintContext behavior. Some of the methods
290 // made virtual so that they can be overridden by ChromePluginPrintContext.
291 class ChromePrintContext : public PrintContext {
292 WTF_MAKE_NONCOPYABLE(ChromePrintContext);
294 ChromePrintContext(LocalFrame* frame)
295 : PrintContext(frame)
296 , m_printedPageWidth(0)
300 virtual ~ChromePrintContext() { }
302 virtual void begin(float width, float height)
304 ASSERT(!m_printedPageWidth);
305 m_printedPageWidth = width;
306 PrintContext::begin(m_printedPageWidth, height);
314 virtual float getPageShrink(int pageNumber) const
316 IntRect pageRect = m_pageRects[pageNumber];
317 return m_printedPageWidth / pageRect.width();
320 // Spools the printed page, a subrect of frame(). Skip the scale step.
321 // NativeTheme doesn't play well with scaling. Scaling is done browser side
322 // instead. Returns the scale to be applied.
323 // On Linux, we don't have the problem with NativeTheme, hence we let WebKit
324 // do the scaling and ignore the return value.
325 virtual float spoolPage(GraphicsContext& context, int pageNumber)
327 IntRect pageRect = m_pageRects[pageNumber];
328 float scale = m_printedPageWidth / pageRect.width();
331 #if OS(POSIX) && !OS(MACOSX)
332 context.scale(scale, scale);
334 context.translate(static_cast<float>(-pageRect.x()), static_cast<float>(-pageRect.y()));
335 context.clip(pageRect);
336 frame()->view()->paintContents(&context, pageRect);
337 if (context.supportsURLFragments())
338 outputLinkedDestinations(context, frame()->document(), pageRect);
343 void spoolAllPagesWithBoundaries(GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
345 if (!frame()->document() || !frame()->view() || !frame()->document()->renderView())
348 frame()->document()->updateLayout();
351 computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, pageHeight);
353 const float pageWidth = pageSizeInPixels.width();
354 size_t numPages = pageRects().size();
355 int totalHeight = numPages * (pageSizeInPixels.height() + 1) - 1;
357 // Fill the whole background by white.
358 graphicsContext.setFillColor(Color::white);
359 graphicsContext.fillRect(FloatRect(0, 0, pageWidth, totalHeight));
361 int currentHeight = 0;
362 for (size_t pageIndex = 0; pageIndex < numPages; pageIndex++) {
363 // Draw a line for a page boundary if this isn't the first page.
365 graphicsContext.save();
366 graphicsContext.setStrokeColor(Color(0, 0, 255));
367 graphicsContext.setFillColor(Color(0, 0, 255));
368 graphicsContext.drawLine(IntPoint(0, currentHeight), IntPoint(pageWidth, currentHeight));
369 graphicsContext.restore();
372 graphicsContext.save();
374 graphicsContext.translate(0, currentHeight);
375 #if OS(WIN) || OS(MACOSX)
376 // Account for the disabling of scaling in spoolPage. In the context
377 // of spoolAllPagesWithBoundaries the scale HAS NOT been pre-applied.
378 float scale = getPageShrink(pageIndex);
379 graphicsContext.scale(scale, scale);
381 spoolPage(graphicsContext, pageIndex);
382 graphicsContext.restore();
384 currentHeight += pageSizeInPixels.height() + 1;
388 virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight)
390 PrintContext::computePageRects(printRect, headerHeight, footerHeight, userScaleFactor, outPageHeight);
393 virtual int pageCount() const
395 return PrintContext::pageCount();
399 // Set when printing.
400 float m_printedPageWidth;
403 // Simple class to override some of PrintContext behavior. This is used when
404 // the frame hosts a plugin that supports custom printing. In this case, we
405 // want to delegate all printing related calls to the plugin.
406 class ChromePluginPrintContext : public ChromePrintContext {
408 ChromePluginPrintContext(LocalFrame* frame, WebPluginContainerImpl* plugin, const WebPrintParams& printParams)
409 : ChromePrintContext(frame), m_plugin(plugin), m_pageCount(0), m_printParams(printParams)
413 virtual ~ChromePluginPrintContext() { }
415 virtual void begin(float width, float height)
421 m_plugin->printEnd();
424 virtual float getPageShrink(int pageNumber) const
426 // We don't shrink the page (maybe we should ask the widget ??)
430 virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight)
432 m_printParams.printContentArea = IntRect(printRect);
433 m_pageCount = m_plugin->printBegin(m_printParams);
436 virtual int pageCount() const
441 // Spools the printed page, a subrect of frame(). Skip the scale step.
442 // NativeTheme doesn't play well with scaling. Scaling is done browser side
443 // instead. Returns the scale to be applied.
444 virtual float spoolPage(GraphicsContext& context, int pageNumber)
446 m_plugin->printPage(pageNumber, &context);
451 // Set when printing.
452 WebPluginContainerImpl* m_plugin;
454 WebPrintParams m_printParams;
458 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader)
460 return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0;
463 // WebFrame -------------------------------------------------------------------
465 int WebFrame::instanceCount()
470 WebLocalFrame* WebLocalFrame::frameForCurrentContext()
472 v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentContext();
473 if (context.IsEmpty())
475 return frameForContext(context);
478 WebLocalFrame* WebLocalFrame::frameForContext(v8::Handle<v8::Context> context)
480 return WebLocalFrameImpl::fromFrame(toFrameIfNotDetached(context));
483 WebLocalFrame* WebLocalFrame::fromFrameOwnerElement(const WebElement& element)
485 return WebLocalFrameImpl::fromFrameOwnerElement(PassRefPtrWillBeRawPtr<Element>(element).get());
488 bool WebLocalFrameImpl::isWebLocalFrame() const
493 WebLocalFrame* WebLocalFrameImpl::toWebLocalFrame()
498 bool WebLocalFrameImpl::isWebRemoteFrame() const
503 WebRemoteFrame* WebLocalFrameImpl::toWebRemoteFrame()
505 ASSERT_NOT_REACHED();
509 void WebLocalFrameImpl::close()
513 // FIXME: Oilpan: Signal to LocalFrame and its supplements that the frame is
514 // being torn down so it can do prompt clean-up. For example, this will
515 // clear the raw back pointer to m_geolocationClientProxy. Once
516 // GeolocationClientProxy is on-heap it looks like we can completely remove
517 // |willBeDestroyed| from supplements since tracing will ensure safety.
519 m_frame->willBeDestroyed();
521 deref(); // Balances ref() acquired in WebFrame::create
524 WebString WebLocalFrameImpl::uniqueName() const
526 return frame()->tree().uniqueName();
529 WebString WebLocalFrameImpl::assignedName() const
531 return frame()->tree().name();
534 void WebLocalFrameImpl::setName(const WebString& name)
536 frame()->tree().setName(name);
539 WebVector<WebIconURL> WebLocalFrameImpl::iconURLs(int iconTypesMask) const
541 // The URL to the icon may be in the header. As such, only
542 // ask the loader for the icon if it's finished loading.
543 if (frame()->loader().state() == FrameStateComplete)
544 return frame()->document()->iconURLs(iconTypesMask);
545 return WebVector<WebIconURL>();
548 void WebLocalFrameImpl::setIsRemote(bool isRemote)
550 m_isRemote = isRemote;
552 client()->initializeChildFrame(frame()->view()->frameRect(), frame()->view()->visibleContentScaleFactor());
555 void WebLocalFrameImpl::setRemoteWebLayer(WebLayer* webLayer)
560 if (frame()->remotePlatformLayer())
561 GraphicsLayer::unregisterContentsLayer(frame()->remotePlatformLayer());
563 GraphicsLayer::registerContentsLayer(webLayer);
564 frame()->setRemotePlatformLayer(webLayer);
565 // FIXME: This should be moved to WebRemoteFrame.
566 ASSERT(frame()->deprecatedLocalOwner());
567 frame()->deprecatedLocalOwner()->setNeedsCompositingUpdate();
568 if (RenderPart* renderer = frame()->ownerRenderer())
569 renderer->layer()->updateSelfPaintingLayer();
572 void WebLocalFrameImpl::setPermissionClient(WebPermissionClient* permissionClient)
574 m_permissionClient = permissionClient;
577 void WebLocalFrameImpl::setSharedWorkerRepositoryClient(WebSharedWorkerRepositoryClient* client)
579 m_sharedWorkerRepositoryClient = SharedWorkerRepositoryClientImpl::create(client);
582 WebSize WebLocalFrameImpl::scrollOffset() const
584 FrameView* view = frameView();
587 return view->scrollOffset();
590 WebSize WebLocalFrameImpl::minimumScrollOffset() const
592 FrameView* view = frameView();
595 return toIntSize(view->minimumScrollPosition());
598 WebSize WebLocalFrameImpl::maximumScrollOffset() const
600 FrameView* view = frameView();
603 return toIntSize(view->maximumScrollPosition());
606 void WebLocalFrameImpl::setScrollOffset(const WebSize& offset)
608 if (FrameView* view = frameView())
609 view->setScrollOffset(IntPoint(offset.width, offset.height));
612 WebSize WebLocalFrameImpl::contentsSize() const
614 return frame()->view()->contentsSize();
617 bool WebLocalFrameImpl::hasVisibleContent() const
619 if (RenderPart* renderer = frame()->ownerRenderer()) {
620 if (renderer->style()->visibility() != VISIBLE)
623 return frame()->view()->visibleWidth() > 0 && frame()->view()->visibleHeight() > 0;
626 WebRect WebLocalFrameImpl::visibleContentRect() const
628 return frame()->view()->visibleContentRect();
631 bool WebLocalFrameImpl::hasHorizontalScrollbar() const
633 return frame() && frame()->view() && frame()->view()->horizontalScrollbar();
636 bool WebLocalFrameImpl::hasVerticalScrollbar() const
638 return frame() && frame()->view() && frame()->view()->verticalScrollbar();
641 WebView* WebLocalFrameImpl::view() const
646 void WebLocalFrameImpl::setOpener(WebFrame* opener)
648 // FIXME: Does this need to move up into WebFrame too?
649 if (WebFrame::opener() && !opener && m_client)
650 m_client->didDisownOpener(this);
652 WebFrame::setOpener(opener);
655 if (m_frame && m_frame->document())
656 m_frame->document()->initSecurityContext();
659 WebDocument WebLocalFrameImpl::document() const
661 if (!frame() || !frame()->document())
662 return WebDocument();
663 return WebDocument(frame()->document());
666 WebPerformance WebLocalFrameImpl::performance() const
669 return WebPerformance();
670 return WebPerformance(&frame()->domWindow()->performance());
673 bool WebLocalFrameImpl::dispatchBeforeUnloadEvent()
677 return frame()->loader().shouldClose();
680 void WebLocalFrameImpl::dispatchUnloadEvent()
684 frame()->loader().closeURL();
687 NPObject* WebLocalFrameImpl::windowObject() const
691 return frame()->script().windowScriptNPObject();
694 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object)
696 bindToWindowObject(name, object, 0);
699 void WebLocalFrameImpl::bindToWindowObject(const WebString& name, NPObject* object, void*)
701 if (!frame() || !frame()->script().canExecuteScripts(NotAboutToExecuteScript))
703 frame()->script().bindToWindowObject(frame(), String(name), object);
706 void WebLocalFrameImpl::executeScript(const WebScriptSource& source)
709 TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
710 v8::HandleScope handleScope(toIsolate(frame()));
711 frame()->script().executeScriptInMainWorld(ScriptSourceCode(source.code, source.url, position));
714 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup)
717 RELEASE_ASSERT(worldID > 0);
718 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
720 Vector<ScriptSourceCode> sources;
721 for (unsigned i = 0; i < numSources; ++i) {
722 TextPosition position(OrdinalNumber::fromOneBasedInt(sourcesIn[i].startLine), OrdinalNumber::first());
723 sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position));
726 v8::HandleScope handleScope(toIsolate(frame()));
727 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
730 void WebLocalFrameImpl::setIsolatedWorldSecurityOrigin(int worldID, const WebSecurityOrigin& securityOrigin)
733 DOMWrapperWorld::setIsolatedWorldSecurityOrigin(worldID, securityOrigin.get());
736 void WebLocalFrameImpl::setIsolatedWorldContentSecurityPolicy(int worldID, const WebString& policy)
739 DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(worldID, policy);
742 void WebLocalFrameImpl::addMessageToConsole(const WebConsoleMessage& message)
746 MessageLevel webCoreMessageLevel;
747 switch (message.level) {
748 case WebConsoleMessage::LevelDebug:
749 webCoreMessageLevel = DebugMessageLevel;
751 case WebConsoleMessage::LevelLog:
752 webCoreMessageLevel = LogMessageLevel;
754 case WebConsoleMessage::LevelWarning:
755 webCoreMessageLevel = WarningMessageLevel;
757 case WebConsoleMessage::LevelError:
758 webCoreMessageLevel = ErrorMessageLevel;
761 ASSERT_NOT_REACHED();
765 frame()->document()->addConsoleMessage(OtherMessageSource, webCoreMessageLevel, message.text);
768 void WebLocalFrameImpl::collectGarbage()
772 if (!frame()->settings()->scriptEnabled())
774 V8GCController::collectGarbage(v8::Isolate::GetCurrent());
777 bool WebLocalFrameImpl::checkIfRunInsecureContent(const WebURL& url) const
780 return frame()->loader().mixedContentChecker()->canRunInsecureContent(frame()->document()->securityOrigin(), url);
783 v8::Handle<v8::Value> WebLocalFrameImpl::executeScriptAndReturnValue(const WebScriptSource& source)
787 // FIXME: This fake user gesture is required to make a bunch of pyauto
788 // tests pass. If this isn't needed in non-test situations, we should
789 // consider removing this code and changing the tests.
790 // http://code.google.com/p/chromium/issues/detail?id=86397
791 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
793 TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
794 return frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source.code, source.url, position));
797 void WebLocalFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, WebVector<v8::Local<v8::Value> >* results)
800 RELEASE_ASSERT(worldID > 0);
801 RELEASE_ASSERT(worldID < EmbedderWorldIdLimit);
803 Vector<ScriptSourceCode> sources;
805 for (unsigned i = 0; i < numSources; ++i) {
806 TextPosition position(OrdinalNumber::fromOneBasedInt(sourcesIn[i].startLine), OrdinalNumber::first());
807 sources.append(ScriptSourceCode(sourcesIn[i].code, sourcesIn[i].url, position));
811 Vector<v8::Local<v8::Value> > scriptResults;
812 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, &scriptResults);
813 WebVector<v8::Local<v8::Value> > v8Results(scriptResults.size());
814 for (unsigned i = 0; i < scriptResults.size(); i++)
815 v8Results[i] = v8::Local<v8::Value>::New(toIsolate(frame()), scriptResults[i]);
816 results->swap(v8Results);
818 v8::HandleScope handleScope(toIsolate(frame()));
819 frame()->script().executeScriptInIsolatedWorld(worldID, sources, extensionGroup, 0);
823 v8::Handle<v8::Value> WebLocalFrameImpl::callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function> function, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::Value> argv[])
826 return frame()->script().callFunction(function, receiver, argc, argv);
829 v8::Local<v8::Context> WebLocalFrameImpl::mainWorldScriptContext() const
831 return toV8Context(frame(), DOMWrapperWorld::mainWorld());
834 void WebLocalFrameImpl::reload(bool ignoreCache)
837 frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload);
840 void WebLocalFrameImpl::reloadWithOverrideURL(const WebURL& overrideUrl, bool ignoreCache)
843 frame()->loader().reload(ignoreCache ? EndToEndReload : NormalReload, overrideUrl);
846 void WebLocalFrameImpl::loadRequest(const WebURLRequest& request)
849 ASSERT(!request.isNull());
850 const ResourceRequest& resourceRequest = request.toResourceRequest();
852 if (resourceRequest.url().protocolIs("javascript")) {
853 loadJavaScriptURL(resourceRequest.url());
857 frame()->loader().load(FrameLoadRequest(0, resourceRequest));
860 void WebLocalFrameImpl::loadHistoryItem(const WebHistoryItem& item, WebHistoryLoadType loadType, WebURLRequest::CachePolicy cachePolicy)
863 RefPtr<HistoryItem> historyItem = PassRefPtr<HistoryItem>(item);
865 frame()->loader().loadHistoryItem(historyItem.get(), static_cast<HistoryLoadType>(loadType), static_cast<ResourceRequestCachePolicy>(cachePolicy));
868 void WebLocalFrameImpl::loadData(const WebData& data, const WebString& mimeType, const WebString& textEncoding, const WebURL& baseURL, const WebURL& unreachableURL, bool replace)
872 // If we are loading substitute data to replace an existing load, then
873 // inherit all of the properties of that original request. This way,
874 // reload will re-attempt the original request. It is essential that
875 // we only do this when there is an unreachableURL since a non-empty
876 // unreachableURL informs FrameLoader::reload to load unreachableURL
877 // instead of the currently loaded URL.
878 ResourceRequest request;
879 if (replace && !unreachableURL.isEmpty() && frame()->loader().provisionalDocumentLoader())
880 request = frame()->loader().provisionalDocumentLoader()->originalRequest();
881 request.setURL(baseURL);
883 FrameLoadRequest frameRequest(0, request, SubstituteData(data, mimeType, textEncoding, unreachableURL));
884 ASSERT(frameRequest.substituteData().isValid());
885 frameRequest.setLockBackForwardList(replace);
886 frame()->loader().load(frameRequest);
889 void WebLocalFrameImpl::loadHTMLString(const WebData& data, const WebURL& baseURL, const WebURL& unreachableURL, bool replace)
892 loadData(data, WebString::fromUTF8("text/html"), WebString::fromUTF8("UTF-8"), baseURL, unreachableURL, replace);
895 bool WebLocalFrameImpl::isLoading() const
899 return frame()->loader().isLoading();
902 void WebLocalFrameImpl::stopLoading()
906 // FIXME: Figure out what we should really do here. It seems like a bug
907 // that FrameLoader::stopLoading doesn't call stopAllLoaders.
908 frame()->loader().stopAllLoaders();
911 WebDataSource* WebLocalFrameImpl::provisionalDataSource() const
915 // We regard the policy document loader as still provisional.
916 DocumentLoader* documentLoader = frame()->loader().provisionalDocumentLoader();
918 documentLoader = frame()->loader().policyDocumentLoader();
920 return DataSourceForDocLoader(documentLoader);
923 WebDataSource* WebLocalFrameImpl::dataSource() const
926 return DataSourceForDocLoader(frame()->loader().documentLoader());
929 void WebLocalFrameImpl::enableViewSourceMode(bool enable)
932 frame()->setInViewSourceMode(enable);
935 bool WebLocalFrameImpl::isViewSourceModeEnabled() const
939 return frame()->inViewSourceMode();
942 void WebLocalFrameImpl::setReferrerForRequest(WebURLRequest& request, const WebURL& referrerURL)
944 String referrer = referrerURL.isEmpty() ? frame()->document()->outgoingReferrer() : String(referrerURL.spec().utf16());
945 referrer = SecurityPolicy::generateReferrerHeader(frame()->document()->referrerPolicy(), request.url(), referrer);
946 if (referrer.isEmpty())
948 request.setHTTPReferrer(referrer, static_cast<WebReferrerPolicy>(frame()->document()->referrerPolicy()));
951 void WebLocalFrameImpl::dispatchWillSendRequest(WebURLRequest& request)
953 ResourceResponse response;
954 frame()->loader().client()->dispatchWillSendRequest(0, 0, request.toMutableResourceRequest(), response);
957 WebURLLoader* WebLocalFrameImpl::createAssociatedURLLoader(const WebURLLoaderOptions& options)
959 return new AssociatedURLLoader(this, options);
962 unsigned WebLocalFrameImpl::unloadListenerCount() const
964 return frame()->domWindow()->pendingUnloadEventListeners();
967 void WebLocalFrameImpl::replaceSelection(const WebString& text)
969 bool selectReplacement = false;
970 bool smartReplace = true;
971 frame()->editor().replaceSelectionWithText(text, selectReplacement, smartReplace);
974 void WebLocalFrameImpl::insertText(const WebString& text)
976 if (frame()->inputMethodController().hasComposition())
977 frame()->inputMethodController().confirmComposition(text);
979 frame()->editor().insertText(text, 0);
982 void WebLocalFrameImpl::setMarkedText(const WebString& text, unsigned location, unsigned length)
984 Vector<CompositionUnderline> decorations;
985 frame()->inputMethodController().setComposition(text, decorations, location, length);
988 void WebLocalFrameImpl::unmarkText()
990 frame()->inputMethodController().cancelComposition();
993 bool WebLocalFrameImpl::hasMarkedText() const
995 return frame()->inputMethodController().hasComposition();
998 WebRange WebLocalFrameImpl::markedRange() const
1000 return frame()->inputMethodController().compositionRange();
1003 bool WebLocalFrameImpl::firstRectForCharacterRange(unsigned location, unsigned length, WebRect& rect) const
1005 if ((location + length < location) && (location + length))
1008 Element* editable = frame()->selection().rootEditableElementOrDocumentElement();
1010 RefPtrWillBeRawPtr<Range> range = PlainTextRange(location, location + length).createRange(*editable);
1013 IntRect intRect = frame()->editor().firstRectForRange(range.get());
1014 rect = WebRect(intRect);
1015 rect = frame()->view()->contentsToWindow(rect);
1019 size_t WebLocalFrameImpl::characterIndexForPoint(const WebPoint& webPoint) const
1024 IntPoint point = frame()->view()->windowToContents(webPoint);
1025 HitTestResult result = frame()->eventHandler().hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
1026 RefPtrWillBeRawPtr<Range> range = frame()->rangeForPoint(result.roundedPointInInnerNodeFrame());
1029 Element* editable = frame()->selection().rootEditableElementOrDocumentElement();
1031 return PlainTextRange::create(*editable, *range.get()).start();
1034 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebNode& node)
1038 if (name.length() <= 2)
1041 // Since we don't have NSControl, we will convert the format of command
1042 // string and call the function on Editor directly.
1043 String command = name;
1045 // Make sure the first letter is upper case.
1046 command.replace(0, 1, command.substring(0, 1).upper());
1048 // Remove the trailing ':' if existing.
1049 if (command[command.length() - 1] == UChar(':'))
1050 command = command.substring(0, command.length() - 1);
1052 WebPluginContainerImpl* pluginContainer = pluginContainerFromNode(frame(), node);
1053 if (pluginContainer && pluginContainer->executeEditCommand(name))
1058 // Specially handling commands that Editor::execCommand does not directly
1060 if (command == "DeleteToEndOfParagraph") {
1061 if (!frame()->editor().deleteWithDirection(DirectionForward, ParagraphBoundary, true, false))
1062 frame()->editor().deleteWithDirection(DirectionForward, CharacterGranularity, true, false);
1063 } else if (command == "Indent") {
1064 frame()->editor().indent();
1065 } else if (command == "Outdent") {
1066 frame()->editor().outdent();
1067 } else if (command == "DeleteBackward") {
1068 result = frame()->editor().command(AtomicString("BackwardDelete")).execute();
1069 } else if (command == "DeleteForward") {
1070 result = frame()->editor().command(AtomicString("ForwardDelete")).execute();
1071 } else if (command == "AdvanceToNextMisspelling") {
1072 // Wee need to pass false here or else the currently selected word will never be skipped.
1073 frame()->spellChecker().advanceToNextMisspelling(false);
1074 } else if (command == "ToggleSpellPanel") {
1075 frame()->spellChecker().showSpellingGuessPanel();
1077 result = frame()->editor().command(command).execute();
1082 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebString& value, const WebNode& node)
1085 String webName = name;
1087 WebPluginContainerImpl* pluginContainer = pluginContainerFromNode(frame(), node);
1088 if (pluginContainer && pluginContainer->executeEditCommand(name, value))
1091 // moveToBeginningOfDocument and moveToEndfDocument are only handled by WebKit for editable nodes.
1092 if (!frame()->editor().canEdit() && webName == "moveToBeginningOfDocument")
1093 return viewImpl()->bubblingScroll(ScrollUp, ScrollByDocument);
1095 if (!frame()->editor().canEdit() && webName == "moveToEndOfDocument")
1096 return viewImpl()->bubblingScroll(ScrollDown, ScrollByDocument);
1098 if (webName == "showGuessPanel") {
1099 frame()->spellChecker().showSpellingGuessPanel();
1103 return frame()->editor().command(webName).execute(value);
1106 bool WebLocalFrameImpl::isCommandEnabled(const WebString& name) const
1109 return frame()->editor().command(name).isEnabled();
1112 void WebLocalFrameImpl::enableContinuousSpellChecking(bool enable)
1114 if (enable == isContinuousSpellCheckingEnabled())
1116 frame()->spellChecker().toggleContinuousSpellChecking();
1119 bool WebLocalFrameImpl::isContinuousSpellCheckingEnabled() const
1121 return frame()->spellChecker().isContinuousSpellCheckingEnabled();
1124 void WebLocalFrameImpl::requestTextChecking(const WebElement& webElement)
1126 if (webElement.isNull())
1128 frame()->spellChecker().requestTextChecking(*webElement.constUnwrap<Element>());
1131 void WebLocalFrameImpl::replaceMisspelledRange(const WebString& text)
1133 // If this caret selection has two or more markers, this function replace the range covered by the first marker with the specified word as Microsoft Word does.
1134 if (pluginContainerFromFrame(frame()))
1136 RefPtrWillBeRawPtr<Range> caretRange = frame()->selection().toNormalizedRange();
1139 WillBeHeapVector<DocumentMarker*> markers = frame()->document()->markers().markersInRange(caretRange.get(), DocumentMarker::MisspellingMarkers());
1140 if (markers.size() < 1 || markers[0]->startOffset() >= markers[0]->endOffset())
1142 RefPtrWillBeRawPtr<Range> markerRange = Range::create(caretRange->ownerDocument(), caretRange->startContainer(), markers[0]->startOffset(), caretRange->endContainer(), markers[0]->endOffset());
1145 frame()->selection().setSelection(VisibleSelection(markerRange.get()), CharacterGranularity);
1146 frame()->editor().replaceSelectionWithText(text, false, false);
1149 void WebLocalFrameImpl::removeSpellingMarkers()
1151 frame()->document()->markers().removeMarkers(DocumentMarker::MisspellingMarkers());
1154 bool WebLocalFrameImpl::hasSelection() const
1156 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1157 if (pluginContainer)
1158 return pluginContainer->plugin()->hasSelection();
1160 // frame()->selection()->isNone() never returns true.
1161 return frame()->selection().start() != frame()->selection().end();
1164 WebRange WebLocalFrameImpl::selectionRange() const
1166 return frame()->selection().toNormalizedRange();
1169 WebString WebLocalFrameImpl::selectionAsText() const
1171 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1172 if (pluginContainer)
1173 return pluginContainer->plugin()->selectionAsText();
1175 RefPtrWillBeRawPtr<Range> range = frame()->selection().toNormalizedRange();
1179 String text = range->text();
1181 replaceNewlinesWithWindowsStyleNewlines(text);
1183 replaceNBSPWithSpace(text);
1187 WebString WebLocalFrameImpl::selectionAsMarkup() const
1189 WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame());
1190 if (pluginContainer)
1191 return pluginContainer->plugin()->selectionAsMarkup();
1193 RefPtrWillBeRawPtr<Range> range = frame()->selection().toNormalizedRange();
1197 return createMarkup(range.get(), 0, AnnotateForInterchange, false, ResolveNonLocalURLs);
1200 void WebLocalFrameImpl::selectWordAroundPosition(LocalFrame* frame, VisiblePosition position)
1202 VisibleSelection selection(position);
1203 selection.expandUsingGranularity(WordGranularity);
1205 TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity;
1206 frame->selection().setSelection(selection, granularity);
1209 bool WebLocalFrameImpl::selectWordAroundCaret()
1211 FrameSelection& selection = frame()->selection();
1212 if (selection.isNone() || selection.isRange())
1214 selectWordAroundPosition(frame(), selection.selection().visibleStart());
1218 void WebLocalFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent)
1220 moveRangeSelection(base, extent);
1223 void WebLocalFrameImpl::selectRange(const WebRange& webRange)
1225 if (RefPtrWillBeRawPtr<Range> range = static_cast<PassRefPtrWillBeRawPtr<Range> >(webRange))
1226 frame()->selection().setSelectedRange(range.get(), WebCore::VP_DEFAULT_AFFINITY, FrameSelection::NonDirectional, NotUserTriggered);
1229 void WebLocalFrameImpl::moveRangeSelection(const WebPoint& base, const WebPoint& extent)
1231 VisiblePosition basePosition = visiblePositionForWindowPoint(base);
1232 VisiblePosition extentPosition = visiblePositionForWindowPoint(extent);
1233 VisibleSelection newSelection = VisibleSelection(basePosition, extentPosition);
1234 frame()->selection().setSelection(newSelection, CharacterGranularity);
1237 void WebLocalFrameImpl::moveCaretSelection(const WebPoint& point)
1239 Element* editable = frame()->selection().rootEditableElement();
1243 VisiblePosition position = visiblePositionForWindowPoint(point);
1244 frame()->selection().moveTo(position, UserTriggered);
1247 bool WebLocalFrameImpl::setEditableSelectionOffsets(int start, int end)
1249 return frame()->inputMethodController().setEditableSelectionOffsets(PlainTextRange(start, end));
1252 bool WebLocalFrameImpl::setCompositionFromExistingText(int compositionStart, int compositionEnd, const WebVector<WebCompositionUnderline>& underlines)
1254 if (!frame()->editor().canEdit())
1257 InputMethodController& inputMethodController = frame()->inputMethodController();
1258 inputMethodController.cancelComposition();
1260 if (compositionStart == compositionEnd)
1263 inputMethodController.setCompositionFromExistingText(CompositionUnderlineVectorBuilder(underlines), compositionStart, compositionEnd);
1268 void WebLocalFrameImpl::extendSelectionAndDelete(int before, int after)
1270 if (WebPlugin* plugin = focusedPluginIfInputMethodSupported()) {
1271 plugin->extendSelectionAndDelete(before, after);
1274 frame()->inputMethodController().extendSelectionAndDelete(before, after);
1277 void WebLocalFrameImpl::setCaretVisible(bool visible)
1279 frame()->selection().setCaretVisible(visible);
1282 VisiblePosition WebLocalFrameImpl::visiblePositionForWindowPoint(const WebPoint& point)
1284 // FIXME(bokan): crbug.com/371902 - These scale/pinch transforms shouldn't
1285 // be ad hoc and explicit.
1286 PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
1287 FloatPoint unscaledPoint(point);
1288 unscaledPoint.scale(1 / view()->pageScaleFactor(), 1 / view()->pageScaleFactor());
1289 unscaledPoint.moveBy(pinchViewport.visibleRect().location());
1291 HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent;
1292 HitTestResult result(frame()->view()->windowToContents(roundedIntPoint(unscaledPoint)));
1293 frame()->document()->renderView()->layer()->hitTest(request, result);
1295 if (Node* node = result.targetNode())
1296 return frame()->selection().selection().visiblePositionRespectingEditingBoundary(result.localPoint(), node);
1297 return VisiblePosition();
1300 WebPlugin* WebLocalFrameImpl::focusedPluginIfInputMethodSupported()
1302 WebPluginContainerImpl* container = WebLocalFrameImpl::pluginContainerFromNode(frame(), WebNode(frame()->document()->focusedElement()));
1303 if (container && container->supportsInputMethod())
1304 return container->plugin();
1308 int WebLocalFrameImpl::printBegin(const WebPrintParams& printParams, const WebNode& constrainToNode)
1310 ASSERT(!frame()->document()->isFrameSet());
1311 WebPluginContainerImpl* pluginContainer = 0;
1312 if (constrainToNode.isNull()) {
1313 // If this is a plugin document, check if the plugin supports its own
1314 // printing. If it does, we will delegate all printing to that.
1315 pluginContainer = pluginContainerFromFrame(frame());
1317 // We only support printing plugin nodes for now.
1318 pluginContainer = toWebPluginContainerImpl(constrainToNode.pluginContainer());
1321 if (pluginContainer && pluginContainer->supportsPaginatedPrint())
1322 m_printContext = adoptPtr(new ChromePluginPrintContext(frame(), pluginContainer, printParams));
1324 m_printContext = adoptPtr(new ChromePrintContext(frame()));
1326 FloatRect rect(0, 0, static_cast<float>(printParams.printContentArea.width), static_cast<float>(printParams.printContentArea.height));
1327 m_printContext->begin(rect.width(), rect.height());
1329 // We ignore the overlays calculation for now since they are generated in the
1330 // browser. pageHeight is actually an output parameter.
1331 m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight);
1333 return m_printContext->pageCount();
1336 float WebLocalFrameImpl::getPrintPageShrink(int page)
1338 ASSERT(m_printContext && page >= 0);
1339 return m_printContext->getPageShrink(page);
1342 float WebLocalFrameImpl::printPage(int page, WebCanvas* canvas)
1344 #if ENABLE(PRINTING)
1345 ASSERT(m_printContext && page >= 0 && frame() && frame()->document());
1347 GraphicsContext graphicsContext(canvas);
1348 graphicsContext.setPrinting(true);
1349 return m_printContext->spoolPage(graphicsContext, page);
1355 void WebLocalFrameImpl::printEnd()
1357 ASSERT(m_printContext);
1358 m_printContext->end();
1359 m_printContext.clear();
1362 bool WebLocalFrameImpl::isPrintScalingDisabledForPlugin(const WebNode& node)
1364 WebPluginContainerImpl* pluginContainer = node.isNull() ? pluginContainerFromFrame(frame()) : toWebPluginContainerImpl(node.pluginContainer());
1366 if (!pluginContainer || !pluginContainer->supportsPaginatedPrint())
1369 return pluginContainer->isPrintScalingDisabled();
1372 bool WebLocalFrameImpl::hasCustomPageSizeStyle(int pageIndex)
1374 return frame()->document()->styleForPage(pageIndex)->pageSizeType() != PAGE_SIZE_AUTO;
1377 bool WebLocalFrameImpl::isPageBoxVisible(int pageIndex)
1379 return frame()->document()->isPageBoxVisible(pageIndex);
1382 void WebLocalFrameImpl::pageSizeAndMarginsInPixels(int pageIndex, WebSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
1384 IntSize size = pageSize;
1385 frame()->document()->pageSizeAndMarginsInPixels(pageIndex, size, marginTop, marginRight, marginBottom, marginLeft);
1389 WebString WebLocalFrameImpl::pageProperty(const WebString& propertyName, int pageIndex)
1391 ASSERT(m_printContext);
1392 return m_printContext->pageProperty(frame(), propertyName.utf8().data(), pageIndex);
1395 bool WebLocalFrameImpl::find(int identifier, const WebString& searchText, const WebFindOptions& options, bool wrapWithinFrame, WebRect* selectionRect)
1397 return ensureTextFinder().find(identifier, searchText, options, wrapWithinFrame, selectionRect);
1400 void WebLocalFrameImpl::stopFinding(bool clearSelection)
1403 if (!clearSelection)
1404 setFindEndstateFocusAndSelection();
1405 m_textFinder->stopFindingAndClearSelection();
1409 void WebLocalFrameImpl::scopeStringMatches(int identifier, const WebString& searchText, const WebFindOptions& options, bool reset)
1411 ensureTextFinder().scopeStringMatches(identifier, searchText, options, reset);
1414 void WebLocalFrameImpl::cancelPendingScopingEffort()
1417 m_textFinder->cancelPendingScopingEffort();
1420 void WebLocalFrameImpl::increaseMatchCount(int count, int identifier)
1422 // This function should only be called on the mainframe.
1424 ensureTextFinder().increaseMatchCount(identifier, count);
1427 void WebLocalFrameImpl::resetMatchCount()
1429 ensureTextFinder().resetMatchCount();
1432 void WebLocalFrameImpl::sendOrientationChangeEvent()
1435 frame()->sendOrientationChangeEvent();
1438 void WebLocalFrameImpl::dispatchMessageEventWithOriginCheck(const WebSecurityOrigin& intendedTargetOrigin, const WebDOMEvent& event)
1440 ASSERT(!event.isNull());
1441 frame()->domWindow()->dispatchMessageEventWithOriginCheck(intendedTargetOrigin.get(), event, nullptr);
1444 int WebLocalFrameImpl::findMatchMarkersVersion() const
1449 return m_textFinder->findMatchMarkersVersion();
1453 int WebLocalFrameImpl::selectNearestFindMatch(const WebFloatPoint& point, WebRect* selectionRect)
1456 return ensureTextFinder().selectNearestFindMatch(point, selectionRect);
1459 WebFloatRect WebLocalFrameImpl::activeFindMatchRect()
1464 return m_textFinder->activeFindMatchRect();
1465 return WebFloatRect();
1468 void WebLocalFrameImpl::findMatchRects(WebVector<WebFloatRect>& outputRects)
1471 ensureTextFinder().findMatchRects(outputRects);
1474 void WebLocalFrameImpl::setTickmarks(const WebVector<WebRect>& tickmarks)
1477 Vector<IntRect> tickmarksConverted(tickmarks.size());
1478 for (size_t i = 0; i < tickmarks.size(); ++i)
1479 tickmarksConverted[i] = tickmarks[i];
1480 frameView()->setTickmarks(tickmarksConverted);
1481 invalidateScrollbar();
1485 WebString WebLocalFrameImpl::contentAsText(size_t maxChars) const
1490 frameContentAsPlainText(maxChars, frame(), text);
1491 return text.toString();
1494 WebString WebLocalFrameImpl::contentAsMarkup() const
1498 return createFullMarkup(frame()->document());
1501 WebString WebLocalFrameImpl::renderTreeAsText(RenderAsTextControls toShow) const
1503 RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal;
1505 if (toShow & RenderAsTextDebug)
1506 behavior |= RenderAsTextShowCompositedLayers | RenderAsTextShowAddresses | RenderAsTextShowIDAndClass | RenderAsTextShowLayerNesting;
1508 if (toShow & RenderAsTextPrinting)
1509 behavior |= RenderAsTextPrintingMode;
1511 return externalRepresentation(frame(), behavior);
1514 WebString WebLocalFrameImpl::markerTextForListItem(const WebElement& webElement) const
1516 return WebCore::markerTextForListItem(const_cast<Element*>(webElement.constUnwrap<Element>()));
1519 void WebLocalFrameImpl::printPagesWithBoundaries(WebCanvas* canvas, const WebSize& pageSizeInPixels)
1521 ASSERT(m_printContext);
1523 GraphicsContext graphicsContext(canvas);
1524 graphicsContext.setPrinting(true);
1526 m_printContext->spoolAllPagesWithBoundaries(graphicsContext, FloatSize(pageSizeInPixels.width, pageSizeInPixels.height));
1529 WebRect WebLocalFrameImpl::selectionBoundsRect() const
1531 return hasSelection() ? WebRect(IntRect(frame()->selection().bounds(false))) : WebRect();
1534 bool WebLocalFrameImpl::selectionStartHasSpellingMarkerFor(int from, int length) const
1538 return frame()->spellChecker().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1541 WebString WebLocalFrameImpl::layerTreeAsText(bool showDebugInfo) const
1546 return WebString(frame()->layerTreeAsText(showDebugInfo ? LayerTreeIncludesDebugInfo : LayerTreeNormal));
1549 // WebLocalFrameImpl public ---------------------------------------------------------
1551 WebLocalFrame* WebLocalFrame::create(WebFrameClient* client)
1553 return WebLocalFrameImpl::create(client);
1556 WebLocalFrameImpl* WebLocalFrameImpl::create(WebFrameClient* client)
1558 return adoptRef(new WebLocalFrameImpl(client)).leakRef();
1561 WebLocalFrameImpl::WebLocalFrameImpl(WebFrameClient* client)
1562 : m_frameLoaderClientImpl(this)
1564 , m_permissionClient(0)
1565 , m_inputEventsScaleFactorForEmulation(1)
1566 , m_userMediaClientImpl(this)
1567 , m_geolocationClientProxy(adoptPtr(new GeolocationClientProxy(client ? client->geolocationClient() : 0)))
1569 blink::Platform::current()->incrementStatsCounter(webFrameActiveCount);
1573 WebLocalFrameImpl::~WebLocalFrameImpl()
1575 blink::Platform::current()->decrementStatsCounter(webFrameActiveCount);
1578 cancelPendingScopingEffort();
1581 void WebLocalFrameImpl::setWebCoreFrame(PassRefPtr<WebCore::LocalFrame> frame)
1585 // FIXME: we shouldn't add overhead to every frame by registering these objects when they're not used.
1587 OwnPtr<NotificationPresenterImpl> notificationPresenter = adoptPtr(new NotificationPresenterImpl());
1589 notificationPresenter->initialize(m_client->notificationPresenter());
1591 provideNotification(*m_frame, notificationPresenter.release());
1592 provideUserMediaTo(*m_frame, &m_userMediaClientImpl);
1593 provideGeolocationTo(*m_frame, m_geolocationClientProxy.get());
1594 m_geolocationClientProxy->setController(GeolocationController::from(m_frame.get()));
1595 provideMIDITo(*m_frame, MIDIClientProxy::create(m_client ? m_client->webMIDIClient() : 0));
1596 if (RuntimeEnabledFeatures::screenOrientationEnabled())
1597 ScreenOrientationController::provideTo(*m_frame, m_client ? m_client->webScreenOrientationClient() : 0);
1598 provideLocalFileSystemTo(*m_frame, LocalFileSystemClient::create());
1602 void WebLocalFrameImpl::initializeAsMainFrame(WebCore::Page* page)
1604 setWebCoreFrame(LocalFrame::create(&m_frameLoaderClientImpl, &page->frameHost(), 0));
1606 // We must call init() after m_frame is assigned because it is referenced
1611 PassRefPtr<LocalFrame> WebLocalFrameImpl::createChildFrame(const FrameLoadRequest& request, HTMLFrameOwnerElement* ownerElement)
1614 WebLocalFrameImpl* webframeChild = toWebLocalFrameImpl(m_client->createChildFrame(this, request.frameName()));
1618 // FIXME: Using subResourceAttributeName as fallback is not a perfect
1619 // solution. subResourceAttributeName returns just one attribute name. The
1620 // element might not have the attribute, and there might be other attributes
1621 // which can identify the element.
1622 RefPtr<LocalFrame> child = webframeChild->initializeAsChildFrame(frame()->host(), ownerElement, request.frameName(), ownerElement->getAttribute(ownerElement->subResourceAttributeName()));
1623 // Initializing the WebCore frame may cause the new child to be detached, since it may dispatch a load event in the parent.
1624 if (!child->tree().parent())
1627 // If we're moving in the back/forward list, we might want to replace the content
1628 // of this child frame with whatever was there at that point.
1629 RefPtr<HistoryItem> childItem;
1630 if (isBackForwardLoadType(frame()->loader().loadType()) && !frame()->document()->loadEventFinished())
1631 childItem = PassRefPtr<HistoryItem>(webframeChild->client()->historyItemForNewChildFrame(webframeChild));
1634 child->loader().loadHistoryItem(childItem.get());
1636 child->loader().load(FrameLoadRequest(0, request.resourceRequest(), "_self"));
1638 // Note a synchronous navigation (about:blank) would have already processed
1639 // onload, so it is possible for the child frame to have already been
1640 // detached by script in the page.
1641 if (!child->tree().parent())
1646 void WebLocalFrameImpl::didChangeContentsSize(const IntSize& size)
1648 // This is only possible on the main frame.
1649 if (m_textFinder && m_textFinder->totalMatchCount() > 0) {
1651 m_textFinder->increaseMarkerVersion();
1655 void WebLocalFrameImpl::createFrameView()
1657 TRACE_EVENT0("webkit", "WebLocalFrameImpl::createFrameView");
1659 ASSERT(frame()); // If frame() doesn't exist, we probably didn't init properly.
1661 WebViewImpl* webView = viewImpl();
1662 bool isMainFrame = webView->mainFrameImpl()->frame() == frame();
1664 webView->suppressInvalidations(true);
1666 frame()->createView(webView->size(), webView->baseBackgroundColor(), webView->isTransparent());
1667 if (webView->shouldAutoResize() && isMainFrame)
1668 frame()->view()->enableAutoSizeMode(true, webView->minAutoSize(), webView->maxAutoSize());
1670 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation, m_inputEventsScaleFactorForEmulation);
1673 webView->suppressInvalidations(false);
1676 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame* frame)
1680 return fromFrame(*frame);
1683 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame& frame)
1685 FrameLoaderClient* client = frame.loader().client();
1686 if (!client || !client->isFrameLoaderClientImpl())
1688 return toFrameLoaderClientImpl(client)->webFrame();
1691 WebLocalFrameImpl* WebLocalFrameImpl::fromFrameOwnerElement(Element* element)
1693 // FIXME: Why do we check specifically for <iframe> and <frame> here? Why can't we get the WebLocalFrameImpl from an <object> element, for example.
1694 if (!isHTMLFrameElementBase(element))
1696 return fromFrame(toLocalFrame(toHTMLFrameElementBase(element)->contentFrame()));
1699 WebViewImpl* WebLocalFrameImpl::viewImpl() const
1703 return WebViewImpl::fromPage(frame()->page());
1706 WebDataSourceImpl* WebLocalFrameImpl::dataSourceImpl() const
1708 return static_cast<WebDataSourceImpl*>(dataSource());
1711 WebDataSourceImpl* WebLocalFrameImpl::provisionalDataSourceImpl() const
1713 return static_cast<WebDataSourceImpl*>(provisionalDataSource());
1716 void WebLocalFrameImpl::setFindEndstateFocusAndSelection()
1718 WebLocalFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1720 if (this != mainFrameImpl->activeMatchFrame())
1723 if (Range* activeMatch = m_textFinder->activeMatch()) {
1724 // If the user has set the selection since the match was found, we
1725 // don't focus anything.
1726 VisibleSelection selection(frame()->selection().selection());
1727 if (!selection.isNone())
1730 // Try to find the first focusable node up the chain, which will, for
1731 // example, focus links if we have found text within the link.
1732 Node* node = activeMatch->firstNode();
1733 if (node && node->isInShadowTree()) {
1734 if (Node* host = node->shadowHost()) {
1735 if (isHTMLInputElement(*host) || isHTMLTextAreaElement(*host))
1739 for (; node; node = node->parentNode()) {
1740 if (!node->isElementNode())
1742 Element* element = toElement(node);
1743 if (element->isFocusable()) {
1744 // Found a focusable parent node. Set the active match as the
1745 // selection and focus to the focusable node.
1746 frame()->selection().setSelection(VisibleSelection(activeMatch));
1747 frame()->document()->setFocusedElement(element);
1752 // Iterate over all the nodes in the range until we find a focusable node.
1753 // This, for example, sets focus to the first link if you search for
1754 // text and text that is within one or more links.
1755 node = activeMatch->firstNode();
1756 for (; node && node != activeMatch->pastLastNode(); node = NodeTraversal::next(*node)) {
1757 if (!node->isElementNode())
1759 Element* element = toElement(node);
1760 if (element->isFocusable()) {
1761 frame()->document()->setFocusedElement(element);
1766 // No node related to the active match was focusable, so set the
1767 // active match as the selection (so that when you end the Find session,
1768 // you'll have the last thing you found highlighted) and make sure that
1769 // we have nothing focused (otherwise you might have text selected but
1770 // a link focused, which is weird).
1771 frame()->selection().setSelection(VisibleSelection(activeMatch));
1772 frame()->document()->setFocusedElement(nullptr);
1774 // Finally clear the active match, for two reasons:
1775 // We just finished the find 'session' and we don't want future (potentially
1776 // unrelated) find 'sessions' operations to start at the same place.
1777 // The WebLocalFrameImpl could get reused and the activeMatch could end up pointing
1778 // to a document that is no longer valid. Keeping an invalid reference around
1779 // is just asking for trouble.
1780 m_textFinder->resetActiveMatch();
1784 void WebLocalFrameImpl::didFail(const ResourceError& error, bool wasProvisional)
1788 WebURLError webError = error;
1790 client()->didFailProvisionalLoad(this, webError);
1792 client()->didFailLoad(this, webError);
1795 void WebLocalFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars)
1797 frame()->view()->setCanHaveScrollbars(canHaveScrollbars);
1800 void WebLocalFrameImpl::setInputEventsTransformForEmulation(const IntSize& offset, float contentScaleFactor)
1802 m_inputEventsOffsetForEmulation = offset;
1803 m_inputEventsScaleFactorForEmulation = contentScaleFactor;
1804 if (frame()->view())
1805 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForEmulation, m_inputEventsScaleFactorForEmulation);
1808 void WebLocalFrameImpl::loadJavaScriptURL(const KURL& url)
1810 // This is copied from ScriptController::executeScriptIfJavaScriptURL.
1811 // Unfortunately, we cannot just use that method since it is private, and
1812 // it also doesn't quite behave as we require it to for bookmarklets. The
1813 // key difference is that we need to suppress loading the string result
1814 // from evaluating the JS URL if executing the JS URL resulted in a
1815 // location change. We also allow a JS URL to be loaded even if scripts on
1816 // the page are otherwise disabled.
1818 if (!frame()->document() || !frame()->page())
1821 RefPtrWillBeRawPtr<Document> ownerDocument(frame()->document());
1823 // Protect privileged pages against bookmarklets and other javascript manipulations.
1824 if (SchemeRegistry::shouldTreatURLSchemeAsNotAllowingJavascriptURLs(frame()->document()->url().protocol()))
1827 String script = decodeURLEscapeSequences(url.string().substring(strlen("javascript:")));
1828 UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
1829 v8::HandleScope handleScope(toIsolate(frame()));
1830 v8::Local<v8::Value> result = frame()->script().executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script));
1831 if (result.IsEmpty() || !result->IsString())
1833 String scriptResult = toCoreString(v8::Handle<v8::String>::Cast(result));
1834 if (!frame()->navigationScheduler().locationChangePending())
1835 frame()->document()->loader()->replaceDocument(scriptResult, ownerDocument.get());
1838 void WebLocalFrameImpl::addStyleSheetByURL(const WebString& url)
1840 RefPtrWillBeRawPtr<Element> styleElement = frame()->document()->createElement(HTMLNames::linkTag, false);
1842 styleElement->setAttribute(HTMLNames::typeAttr, "text/css");
1843 styleElement->setAttribute(HTMLNames::relAttr, "stylesheet");
1844 styleElement->setAttribute(HTMLNames::hrefAttr, url);
1846 frame()->document()->head()->appendChild(styleElement.release(), IGNORE_EXCEPTION);
1849 void WebLocalFrameImpl::willDetachParent()
1851 // Do not expect string scoping results from any frames that got detached
1852 // in the middle of the operation.
1853 if (m_textFinder && m_textFinder->scopingInProgress()) {
1855 // There is a possibility that the frame being detached was the only
1856 // pending one. We need to make sure final replies can be sent.
1857 m_textFinder->flushCurrentScoping();
1859 m_textFinder->cancelPendingScopingEffort();
1863 WebLocalFrameImpl* WebLocalFrameImpl::activeMatchFrame() const
1868 return m_textFinder->activeMatchFrame();
1872 WebCore::Range* WebLocalFrameImpl::activeMatch() const
1875 return m_textFinder->activeMatch();
1879 TextFinder& WebLocalFrameImpl::ensureTextFinder()
1882 m_textFinder = TextFinder::create(*this);
1884 return *m_textFinder;
1887 void WebLocalFrameImpl::invalidateScrollbar() const
1889 ASSERT(frame() && frame()->view());
1890 FrameView* view = frame()->view();
1891 // Invalidate the vertical scroll bar region for the view.
1892 Scrollbar* scrollbar = view->verticalScrollbar();
1894 scrollbar->invalidate();
1897 void WebLocalFrameImpl::invalidateAll() const
1899 ASSERT(frame() && frame()->view());
1900 FrameView* view = frame()->view();
1901 view->invalidateRect(view->frameRect());
1902 invalidateScrollbar();
1905 PassRefPtr<LocalFrame> WebLocalFrameImpl::initializeAsChildFrame(FrameHost* host, FrameOwner* owner, const AtomicString& name, const AtomicString& fallbackName)
1907 RefPtr<LocalFrame> frame = LocalFrame::create(&m_frameLoaderClientImpl, host, owner);
1908 setWebCoreFrame(frame);
1909 frame->tree().setName(name, fallbackName);
1910 // May dispatch JS events; frame may be detached after this.
1915 } // namespace blink