summaryrefslogtreecommitdiff
path: root/Source/web/WebFrameImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/web/WebFrameImpl.cpp')
-rw-r--r--Source/web/WebFrameImpl.cpp168
1 files changed, 109 insertions, 59 deletions
diff --git a/Source/web/WebFrameImpl.cpp b/Source/web/WebFrameImpl.cpp
index 5a53a30f4..d160e3676 100644
--- a/Source/web/WebFrameImpl.cpp
+++ b/Source/web/WebFrameImpl.cpp
@@ -50,7 +50,7 @@
// ref initially and it is removed when the FrameLoader is getting destroyed.
//
// WebFrames are created in two places, first in WebViewImpl when the root
-// frame is created, and second in WebFrame::CreateChildFrame when sub-frames
+// frame is created, and second in WebFrame::createChildFrame when sub-frames
// are created. WebKit will hook up this object to the FrameLoader/Frame
// and the refcount will be correct.
//
@@ -64,13 +64,17 @@
// in FrameLoader::detachFromParent for each subframe.
//
// Frame going away causes the FrameLoader to get deleted. In FrameLoader's
-// destructor, it notifies its client with frameLoaderDestroyed. This calls
-// WebFrame::Closing and then derefs the WebFrame and will cause it to be
-// deleted (unless an external someone is also holding a reference).
+// destructor, it notifies its client with frameLoaderDestroyed. This derefs
+// the WebFrame and will cause it to be deleted (unless an external someone
+// is also holding a reference).
+//
+// Thie client is expected to be set whenever the WebFrameImpl is attached to
+// the DOM.
#include "config.h"
#include "WebFrameImpl.h"
+#include <algorithm>
#include "AssociatedURLLoader.h"
#include "DOMUtilitiesPrivate.h"
#include "EventListenerWrapper.h"
@@ -116,17 +120,16 @@
#include "core/dom/MessagePort.h"
#include "core/dom/Node.h"
#include "core/dom/NodeTraversal.h"
-#include "core/dom/UserGestureIndicator.h"
-#include "core/dom/default/chromium/PlatformMessagePortChannelChromium.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/Editor.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/InputMethodController.h"
-#include "core/editing/SpellCheckRequester.h"
+#include "core/editing/SpellChecker.h"
#include "core/editing/TextAffinity.h"
#include "core/editing/TextIterator.h"
#include "core/editing/htmlediting.h"
#include "core/editing/markup.h"
+#include "core/frame/Console.h"
#include "core/history/BackForwardController.h"
#include "core/history/HistoryItem.h"
#include "core/html/HTMLCollection.h"
@@ -146,20 +149,15 @@
#include "core/loader/IconController.h"
#include "core/loader/SubstituteData.h"
#include "core/page/Chrome.h"
-#include "core/page/Console.h"
-#include "core/page/DOMWindow.h"
+#include "core/frame/DOMWindow.h"
#include "core/page/EventHandler.h"
#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
-#include "core/page/FrameView.h"
+#include "core/frame/FrameView.h"
#include "core/page/Page.h"
-#include "core/page/Performance.h"
#include "core/page/PrintContext.h"
#include "core/page/Settings.h"
-#include "core/platform/ScrollTypes.h"
#include "core/platform/ScrollbarTheme.h"
-#include "core/platform/chromium/ClipboardUtilitiesChromium.h"
-#include "core/platform/chromium/TraceEvent.h"
#include "core/platform/graphics/FontCache.h"
#include "core/platform/graphics/GraphicsContext.h"
#include "core/platform/graphics/GraphicsLayerClient.h"
@@ -173,12 +171,17 @@
#include "core/rendering/RenderTreeAsText.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/style/StyleInheritedData.h"
+#include "core/timing/Performance.h"
#include "core/xml/DocumentXPathEvaluator.h"
#include "core/xml/XPathResult.h"
#include "modules/filesystem/DOMFileSystem.h"
#include "modules/filesystem/DirectoryEntry.h"
#include "modules/filesystem/FileEntry.h"
-#include "modules/filesystem/FileSystemType.h"
+#include "platform/FileSystemType.h"
+#include "platform/TraceEvent.h"
+#include "platform/UserGestureIndicator.h"
+#include "platform/clipboard/ClipboardUtilities.h"
+#include "platform/scroll/ScrollTypes.h"
#include "public/platform/Platform.h"
#include "public/platform/WebFileSystem.h"
#include "public/platform/WebFileSystemType.h"
@@ -194,7 +197,6 @@
#include "weborigin/SecurityPolicy.h"
#include "wtf/CurrentTime.h"
#include "wtf/HashMap.h"
-#include <algorithm>
using namespace WebCore;
@@ -266,12 +268,6 @@ static void frameContentAsPlainText(size_t maxChars, Frame* frame, StringBuilder
}
}
-static long long generateFrameIdentifier()
-{
- static long long next = 0;
- return ++next;
-}
-
WebPluginContainerImpl* WebFrameImpl::pluginContainerFromFrame(Frame* frame)
{
if (!frame)
@@ -526,6 +522,12 @@ WebFrame* WebFrame::fromFrameOwnerElement(const WebElement& element)
return WebFrameImpl::fromFrameOwnerElement(PassRefPtr<Element>(element).get());
}
+void WebFrameImpl::close()
+{
+ m_client = 0;
+ deref(); // Balances ref() acquired in WebFrame::create
+}
+
WebString WebFrameImpl::uniqueName() const
{
return frame()->tree()->uniqueName();
@@ -541,9 +543,9 @@ void WebFrameImpl::setName(const WebString& name)
frame()->tree()->setName(name);
}
-long long WebFrameImpl::identifier() const
+long long WebFrameImpl::embedderIdentifier() const
{
- return m_identifier;
+ return m_embedderIdentifier;
}
WebVector<WebIconURL> WebFrameImpl::iconURLs(int iconTypesMask) const
@@ -744,7 +746,7 @@ void WebFrameImpl::executeScript(const WebScriptSource& source)
{
ASSERT(frame());
TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
- frame()->script()->executeScript(ScriptSourceCode(source.code, source.url, position));
+ frame()->script()->executeScriptInMainWorld(ScriptSourceCode(source.code, source.url, position));
}
void WebFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup)
@@ -826,7 +828,7 @@ v8::Handle<v8::Value> WebFrameImpl::executeScriptAndReturnValue(const WebScriptS
UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
TextPosition position(OrdinalNumber::fromOneBasedInt(source.startLine), OrdinalNumber::first());
- return frame()->script()->executeScript(ScriptSourceCode(source.code, source.url, position)).v8Value();
+ return frame()->script()->executeScriptInMainWorldAndReturnValue(ScriptSourceCode(source.code, source.url, position)).v8Value();
}
void WebFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup, WebVector<v8::Local<v8::Value> >* results)
@@ -856,7 +858,7 @@ void WebFrameImpl::executeScriptInIsolatedWorld(int worldID, const WebScriptSour
v8::Handle<v8::Value> WebFrameImpl::callFunctionEvenIfScriptDisabled(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> argv[])
{
ASSERT(frame());
- return frame()->script()->callFunctionEvenIfScriptDisabled(function, receiver, argc, argv).v8Value();
+ return frame()->script()->callFunction(function, receiver, argc, argv);
}
v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const
@@ -1168,9 +1170,9 @@ bool WebFrameImpl::executeCommand(const WebString& name, const WebNode& node)
result = frame()->editor().command(AtomicString("ForwardDelete")).execute();
} else if (command == "AdvanceToNextMisspelling") {
// Wee need to pass false here or else the currently selected word will never be skipped.
- frame()->editor().advanceToNextMisspelling(false);
+ frame()->spellChecker().advanceToNextMisspelling(false);
} else if (command == "ToggleSpellPanel") {
- frame()->editor().showSpellingGuessPanel();
+ frame()->spellChecker().showSpellingGuessPanel();
} else {
result = frame()->editor().command(command).execute();
}
@@ -1193,6 +1195,11 @@ bool WebFrameImpl::executeCommand(const WebString& name, const WebString& value,
if (!frame()->editor().canEdit() && webName == "moveToEndOfDocument")
return viewImpl()->propagateScroll(ScrollDown, ScrollByDocument);
+ if (webName == "showGuessPanel") {
+ frame()->spellChecker().showSpellingGuessPanel();
+ return true;
+ }
+
return frame()->editor().command(webName).execute(value);
}
@@ -1206,20 +1213,19 @@ void WebFrameImpl::enableContinuousSpellChecking(bool enable)
{
if (enable == isContinuousSpellCheckingEnabled())
return;
- frame()->editor().toggleContinuousSpellChecking();
+ frame()->spellChecker().toggleContinuousSpellChecking();
}
bool WebFrameImpl::isContinuousSpellCheckingEnabled() const
{
- return frame()->editor().isContinuousSpellCheckingEnabled();
+ return frame()->spellChecker().isContinuousSpellCheckingEnabled();
}
void WebFrameImpl::requestTextChecking(const WebElement& webElement)
{
if (webElement.isNull())
return;
- RefPtr<Range> rangeToCheck = rangeOfContents(const_cast<Element*>(webElement.constUnwrap<Element>()));
- frame()->editor().spellCheckRequester().requestCheckingFor(SpellCheckRequest::create(TextCheckingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToCheck, rangeToCheck));
+ frame()->spellChecker().requestTextChecking(*webElement.constUnwrap<Element>());
}
void WebFrameImpl::replaceMisspelledRange(const WebString& text)
@@ -1236,8 +1242,6 @@ void WebFrameImpl::replaceMisspelledRange(const WebString& text)
RefPtr<Range> markerRange = Range::create(caretRange->ownerDocument(), caretRange->startContainer(), markers[0]->startOffset(), caretRange->endContainer(), markers[0]->endOffset());
if (!markerRange)
return;
- if (!frame()->selection().shouldChangeSelection(markerRange.get()))
- return;
frame()->selection().setSelection(markerRange.get(), CharacterGranularity);
frame()->editor().replaceSelectionWithText(text, false, false);
}
@@ -1298,10 +1302,8 @@ void WebFrameImpl::selectWordAroundPosition(Frame* frame, VisiblePosition positi
VisibleSelection selection(position);
selection.expandUsingGranularity(WordGranularity);
- if (frame->selection().shouldChangeSelection(selection)) {
- TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity;
- frame->selection().setSelection(selection, granularity);
- }
+ TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity;
+ frame->selection().setSelection(selection, granularity);
}
bool WebFrameImpl::selectWordAroundCaret()
@@ -1335,8 +1337,7 @@ void WebFrameImpl::moveRangeSelection(const WebPoint& base, const WebPoint& exte
VisiblePosition basePosition = visiblePositionForWindowPoint(base);
VisiblePosition extentPosition = visiblePositionForWindowPoint(extent);
VisibleSelection newSelection = VisibleSelection(basePosition, extentPosition);
- if (frame()->selection().shouldChangeSelection(newSelection))
- frame()->selection().setSelection(newSelection, CharacterGranularity);
+ frame()->selection().setSelection(newSelection, CharacterGranularity);
}
void WebFrameImpl::moveCaretSelection(const WebPoint& point)
@@ -1346,8 +1347,7 @@ void WebFrameImpl::moveCaretSelection(const WebPoint& point)
return;
VisiblePosition position = visiblePositionForWindowPoint(point);
- if (frame()->selection().shouldChangeSelection(position))
- frame()->selection().moveTo(position, UserTriggered);
+ frame()->selection().moveTo(position, UserTriggered);
}
void WebFrameImpl::setCaretVisible(bool visible)
@@ -2048,7 +2048,7 @@ bool WebFrameImpl::selectionStartHasSpellingMarkerFor(int from, int length) cons
{
if (!frame())
return false;
- return frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
+ return frame()->spellChecker().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
}
WebString WebFrameImpl::layerTreeAsText(bool showDebugInfo) const
@@ -2061,12 +2061,34 @@ WebString WebFrameImpl::layerTreeAsText(bool showDebugInfo) const
// WebFrameImpl public ---------------------------------------------------------
-PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client)
+WebFrame* WebFrame::create(WebFrameClient* client)
{
- return adoptRef(new WebFrameImpl(client));
+ return WebFrameImpl::create(client);
}
-WebFrameImpl::WebFrameImpl(WebFrameClient* client)
+WebFrame* WebFrame::create(WebFrameClient* client, long long embedderIdentifier)
+{
+ return WebFrameImpl::create(client, embedderIdentifier);
+}
+
+long long WebFrame::generateEmbedderIdentifier()
+{
+ static long long next = 0;
+ // Assume that 64-bit will not wrap to -1.
+ return ++next;
+}
+
+WebFrameImpl* WebFrameImpl::create(WebFrameClient* client)
+{
+ return WebFrameImpl::create(client, generateEmbedderIdentifier());
+}
+
+WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIdentifier)
+{
+ return adoptRef(new WebFrameImpl(client, embedderIdentifier)).leakRef();
+}
+
+WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier)
: FrameDestructionObserver(0)
, m_frameLoaderClient(this)
, m_client(client)
@@ -2083,8 +2105,9 @@ WebFrameImpl::WebFrameImpl(WebFrameClient* client)
, m_nextInvalidateAfter(0)
, m_findMatchMarkersVersion(0)
, m_findMatchRectsAreValid(false)
- , m_identifier(generateFrameIdentifier())
+ , m_embedderIdentifier(embedderIdentifier)
, m_inSameDocumentHistoryLoad(false)
+ , m_inputEventsScaleFactorForEmulation(1)
{
WebKit::Platform::current()->incrementStatsCounter(webFrameActiveCount);
frameCount++;
@@ -2109,7 +2132,7 @@ void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page)
RefPtr<Frame> mainFrame = Frame::create(page, 0, &m_frameLoaderClient);
setWebCoreFrame(mainFrame.get());
- // Add reference on behalf of FrameLoader. See comments in
+ // Add reference on behalf of FrameLoader. See comments in
// WebFrameLoaderClient::frameLoaderDestroyed for more info.
ref();
@@ -2120,9 +2143,26 @@ void WebFrameImpl::initializeAsMainFrame(WebCore::Page* page)
PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request, HTMLFrameOwnerElement* ownerElement)
{
- RefPtr<WebFrameImpl> webframe(adoptRef(new WebFrameImpl(m_client)));
+ ASSERT(m_client);
+ WebFrameImpl* webframe = toWebFrameImpl(m_client->createChildFrame(this, request.frameName()));
+
+ // If the embedder is returning 0 from createChildFrame(), it has not been
+ // updated to the new ownership semantics where the embedder creates the
+ // WebFrame. In that case, fall back to the old logic where the
+ // WebFrameImpl is created here and published back to the embedder. To
+ // bridge between the two ownership semantics, webframeLifetimeHack is
+ // needeed to balance out the refcounting.
+ //
+ // FIXME: Remove once all embedders return non-null from createChildFrame().
+ RefPtr<WebFrameImpl> webframeLifetimeHack;
+ bool mustCallDidCreateFrame = false;
+ if (!webframe) {
+ mustCallDidCreateFrame = true;
+ webframeLifetimeHack = adoptRef(WebFrameImpl::create(m_client));
+ webframe = webframeLifetimeHack.get();
+ }
- // Add an extra ref on behalf of the Frame/FrameLoader, which references the
+ // Add an extra ref on behalf of the page/FrameLoader, which references the
// WebFrame via the FrameLoaderClient interface. See the comment at the top
// of this file for more info.
webframe->ref();
@@ -2134,6 +2174,10 @@ PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request
frame()->tree()->appendChild(childFrame);
+ // FIXME: Remove once all embedders return non-null from createChildFrame().
+ if (mustCallDidCreateFrame)
+ m_client->didCreateFrame(this, webframe);
+
// Frame::init() can trigger onload event in the parent frame,
// which may detach this frame and trigger a null-pointer access
// in FrameTree::removeChild. Move init() after appendChild call
@@ -2142,6 +2186,7 @@ PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request
// Because the event handler may set webframe->mFrame to null,
// it is necessary to check the value after calling init() and
// return without loading URL.
+ // NOTE: m_client will be null if this frame has been detached.
// (b:791612)
childFrame->init(); // create an empty document
if (!childFrame->tree()->parent())
@@ -2162,12 +2207,10 @@ PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request
// A synchronous navigation (about:blank) would have already processed
// onload, so it is possible for the frame to have already been destroyed by
// script in the page.
+ // NOTE: m_client will be null if this frame has been detached.
if (!childFrame->tree()->parent())
return 0;
- if (m_client)
- m_client->didCreateFrame(this, webframe.get());
-
return childFrame.release();
}
@@ -2195,18 +2238,17 @@ void WebFrameImpl::createFrameView()
if (webView->shouldAutoResize() && isMainFrame)
frame()->view()->enableAutoSizeMode(true, webView->minAutoSize(), webView->maxAutoSize());
+ frame()->view()->setInputEventsScaleFactorForEmulation(m_inputEventsScaleFactorForEmulation);
+
if (isMainFrame)
webView->suppressInvalidations(false);
-
- if (isMainFrame && webView->devToolsAgentPrivate())
- webView->devToolsAgentPrivate()->mainFrameViewCreated(this);
}
WebFrameImpl* WebFrameImpl::fromFrame(Frame* frame)
{
if (!frame)
return 0;
- return static_cast<FrameLoaderClientImpl*>(frame->loader()->client())->webFrame();
+ return toFrameLoaderClientImpl(frame->loader()->client())->webFrame();
}
WebFrameImpl* WebFrameImpl::fromFrameOwnerElement(Element* element)
@@ -2314,6 +2356,13 @@ void WebFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars)
frame()->view()->setCanHaveScrollbars(canHaveScrollbars);
}
+void WebFrameImpl::setInputEventsScaleFactorForEmulation(float contentScaleFactor)
+{
+ m_inputEventsScaleFactorForEmulation = contentScaleFactor;
+ if (frame()->view())
+ frame()->view()->setInputEventsScaleFactorForEmulation(m_inputEventsScaleFactorForEmulation);
+}
+
void WebFrameImpl::invalidateArea(AreaToInvalidate area)
{
ASSERT(frame() && frame()->view());
@@ -2443,7 +2492,8 @@ void WebFrameImpl::loadJavaScriptURL(const KURL& url)
return;
String script = decodeURLEscapeSequences(url.string().substring(strlen("javascript:")));
- ScriptValue result = frame()->script()->executeScript(script, true);
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
+ ScriptValue result = frame()->script()->executeScriptInMainWorldAndReturnValue(ScriptSourceCode(script));
String scriptResult;
if (!result.getString(scriptResult))