summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-30 04:19:34 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-30 04:19:34 +0000
commit42b7289e9b7667a34c82a1395d380a00643f0c28 (patch)
tree50dae4af6a888936c5b6d893d97d9f7d03696c55
parent29672abd046612aa325fcfc0e69e1cc4d91c299c (diff)
downloadchromium_src-42b7289e9b7667a34c82a1395d380a00643f0c28.zip
chromium_src-42b7289e9b7667a34c82a1395d380a00643f0c28.tar.gz
chromium_src-42b7289e9b7667a34c82a1395d380a00643f0c28.tar.bz2
Moves webview_impl.cc, webframe_impl.cc and webframeloaderclient_impl.cc into
webkit/api/src. R=yaar BUG=25896,25897,25902 TEST=none Review URL: http://codereview.chromium.org/341030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30558 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--webkit/api/src/AutocompletePopupMenuClient.cpp178
-rw-r--r--webkit/api/src/AutocompletePopupMenuClient.h96
-rw-r--r--webkit/api/src/BackForwardListClientImpl.cpp10
-rw-r--r--webkit/api/src/BackForwardListClientImpl.h7
-rw-r--r--webkit/api/src/ChromeClientImpl.cpp43
-rw-r--r--webkit/api/src/ChromeClientImpl.h3
-rw-r--r--webkit/api/src/ContextMenuClientImpl.cpp31
-rw-r--r--webkit/api/src/ContextMenuClientImpl.h3
-rw-r--r--webkit/api/src/DragClientImpl.cpp6
-rw-r--r--webkit/api/src/DragClientImpl.h3
-rw-r--r--webkit/api/src/EditorClientImpl.cpp27
-rw-r--r--webkit/api/src/EditorClientImpl.h3
-rw-r--r--webkit/api/src/FrameLoaderClientImpl.cpp1405
-rw-r--r--webkit/api/src/FrameLoaderClientImpl.h230
-rw-r--r--webkit/api/src/InspectorClientImpl.cpp6
-rw-r--r--webkit/api/src/InspectorClientImpl.h3
-rw-r--r--webkit/api/src/WebFrameImpl.cpp1890
-rw-r--r--webkit/api/src/WebFrameImpl.h376
-rw-r--r--webkit/api/src/WebStorageEventDispatcherImpl.cpp4
-rw-r--r--webkit/api/src/WebViewImpl.cpp1767
-rw-r--r--webkit/api/src/WebViewImpl.h419
-rw-r--r--webkit/api/src/WebWorkerClientImpl.cpp10
-rw-r--r--webkit/api/src/WebWorkerImpl.cpp3
-rw-r--r--webkit/glue/devtools/debugger_agent_impl.cc4
-rw-r--r--webkit/glue/devtools/debugger_agent_impl.h11
-rw-r--r--webkit/glue/devtools/debugger_agent_manager.cc9
-rw-r--r--webkit/glue/devtools/debugger_agent_manager.h13
-rw-r--r--webkit/glue/dom_operations.cc18
-rw-r--r--webkit/glue/dom_operations.h1
-rw-r--r--webkit/glue/dom_operations_private.h10
-rw-r--r--webkit/glue/dom_serializer.cc3
-rw-r--r--webkit/glue/dom_serializer.h7
-rw-r--r--webkit/glue/dom_serializer_unittest.cc4
-rw-r--r--webkit/glue/image_resource_fetcher.h3
-rw-r--r--webkit/glue/password_autocomplete_listener_impl.cc11
-rw-r--r--webkit/glue/webaccessibilitymanager_impl.cc5
-rw-r--r--webkit/glue/webdevtoolsagent_impl.cc5
-rw-r--r--webkit/glue/webdevtoolsagent_impl.h12
-rw-r--r--webkit/glue/webdevtoolsfrontend_impl.cc11
-rw-r--r--webkit/glue/webdevtoolsfrontend_impl.h9
-rw-r--r--webkit/glue/webframe_impl.cc1921
-rw-r--r--webkit/glue/webframe_impl.h397
-rw-r--r--webkit/glue/webframeloaderclient_impl.cc1339
-rw-r--r--webkit/glue/webframeloaderclient_impl.h244
-rw-r--r--webkit/glue/webkit_glue.cc14
-rw-r--r--webkit/glue/webkitclient_impl.cc9
-rw-r--r--webkit/glue/webview_impl.cc1925
-rw-r--r--webkit/glue/webview_impl.h401
-rw-r--r--webkit/webkit.gyp15
49 files changed, 6537 insertions, 6387 deletions
diff --git a/webkit/api/src/AutocompletePopupMenuClient.cpp b/webkit/api/src/AutocompletePopupMenuClient.cpp
new file mode 100644
index 0000000..96cccf5
--- /dev/null
+++ b/webkit/api/src/AutocompletePopupMenuClient.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AutocompletePopupMenuClient.h"
+
+#include "CSSValueKeywords.h"
+#include "CSSStyleSelector.h"
+#include "FrameView.h"
+#include "HTMLInputElement.h"
+#include "RenderTheme.h"
+#include "WebVector.h"
+#include "WebViewImpl.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+AutocompletePopupMenuClient::AutocompletePopupMenuClient(WebViewImpl* webView)
+ : m_textField(0)
+ , m_selectedIndex(0)
+ , m_webView(webView)
+{
+}
+
+AutocompletePopupMenuClient::~AutocompletePopupMenuClient()
+{
+}
+
+void AutocompletePopupMenuClient::initialize(
+ HTMLInputElement* textField,
+ const WebVector<WebString>& suggestions,
+ int defaultSuggestionIndex)
+{
+ ASSERT(defaultSuggestionIndex < static_cast<int>(suggestions.size()));
+ m_textField = textField;
+ m_selectedIndex = defaultSuggestionIndex;
+ setSuggestions(suggestions);
+
+ FontDescription fontDescription;
+ m_webView->theme()->systemFont(CSSValueWebkitControl, fontDescription);
+ // Use a smaller font size to match IE/Firefox.
+ // FIXME: http://crbug.com/7376 use the system size instead of a
+ // fixed font size value.
+ fontDescription.setComputedSize(12.0);
+ Font font(fontDescription, 0, 0);
+ font.update(textField->document()->styleSelector()->fontSelector());
+ // The direction of text in popup menu is set the same as the direction of
+ // the input element: textField.
+ m_style.set(new PopupMenuStyle(Color::black, Color::white, font, true,
+ Length(WebCore::Fixed),
+ textField->renderer()->style()->direction()));
+}
+
+void AutocompletePopupMenuClient::valueChanged(unsigned listIndex, bool fireEvents)
+{
+ m_textField->setValue(m_suggestions[listIndex]);
+ EditorClientImpl* editor =
+ static_cast<EditorClientImpl*>(m_webView->page()->editorClient());
+ ASSERT(editor);
+ editor->onAutofillSuggestionAccepted(
+ static_cast<HTMLInputElement*>(m_textField.get()));
+}
+
+String AutocompletePopupMenuClient::itemText(unsigned listIndex) const
+{
+ return m_suggestions[listIndex];
+}
+
+PopupMenuStyle AutocompletePopupMenuClient::itemStyle(unsigned listIndex) const
+{
+ return *m_style;
+}
+
+PopupMenuStyle AutocompletePopupMenuClient::menuStyle() const
+{
+ return *m_style;
+}
+
+int AutocompletePopupMenuClient::clientPaddingLeft() const
+{
+ // Bug http://crbug.com/7708 seems to indicate the style can be NULL.
+ RenderStyle* style = textFieldStyle();
+ return style ? m_webView->theme()->popupInternalPaddingLeft(style) : 0;
+}
+
+int AutocompletePopupMenuClient::clientPaddingRight() const
+{
+ // Bug http://crbug.com/7708 seems to indicate the style can be NULL.
+ RenderStyle* style = textFieldStyle();
+ return style ? m_webView->theme()->popupInternalPaddingRight(style) : 0;
+}
+
+void AutocompletePopupMenuClient::popupDidHide()
+{
+ m_webView->autoCompletePopupDidHide();
+}
+
+void AutocompletePopupMenuClient::setTextFromItem(unsigned listIndex)
+{
+ m_textField->setValue(m_suggestions[listIndex]);
+}
+
+FontSelector* AutocompletePopupMenuClient::fontSelector() const
+{
+ return m_textField->document()->styleSelector()->fontSelector();
+}
+
+HostWindow* AutocompletePopupMenuClient::hostWindow() const
+{
+ return m_textField->document()->view()->hostWindow();
+}
+
+PassRefPtr<Scrollbar> AutocompletePopupMenuClient::createScrollbar(
+ ScrollbarClient* client,
+ ScrollbarOrientation orientation,
+ ScrollbarControlSize size)
+{
+ return Scrollbar::createNativeScrollbar(client, orientation, size);
+}
+
+void AutocompletePopupMenuClient::setSuggestions(const WebVector<WebString>& suggestions)
+{
+ m_suggestions.clear();
+ for (size_t i = 0; i < suggestions.size(); ++i)
+ m_suggestions.append(suggestions[i]);
+ // Try to preserve selection if possible.
+ if (m_selectedIndex >= static_cast<int>(suggestions.size()))
+ m_selectedIndex = -1;
+}
+
+void AutocompletePopupMenuClient::removeItemAtIndex(int index)
+{
+ ASSERT(index >= 0 && index < static_cast<int>(m_suggestions.size()));
+ m_suggestions.remove(index);
+}
+
+RenderStyle* AutocompletePopupMenuClient::textFieldStyle() const
+{
+ RenderStyle* style = m_textField->computedStyle();
+ if (!style) {
+ // It seems we can only have an NULL style in a TextField if the
+ // node is dettached, in which case we the popup shoud not be
+ // showing. Please report this in http://crbug.com/7708 and
+ // include the page you were visiting.
+ ASSERT_NOT_REACHED();
+ }
+ return style;
+}
+
+} // namespace WebKit
diff --git a/webkit/api/src/AutocompletePopupMenuClient.h b/webkit/api/src/AutocompletePopupMenuClient.h
new file mode 100644
index 0000000..ad24e54
--- /dev/null
+++ b/webkit/api/src/AutocompletePopupMenuClient.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PopupMenuClient.h"
+
+namespace WebCore {
+class HTMLInputElement;
+class PopupMenuStyle;
+class RenderStyle;
+}
+
+namespace WebKit {
+class WebString;
+class WebViewImpl;
+template <typename T> class WebVector;
+
+// AutocompletePopupMenuClient
+class AutocompletePopupMenuClient : public WebCore::PopupMenuClient {
+public:
+ AutocompletePopupMenuClient(WebViewImpl* webview);
+ ~AutocompletePopupMenuClient();
+
+ void initialize(WebCore::HTMLInputElement*,
+ const WebVector<WebString>& suggestions,
+ int defaultSuggestionIndex);
+
+ WebCore::HTMLInputElement* textField() const { return m_textField.get(); }
+
+ void setSuggestions(const WebVector<WebString>&);
+ void removeItemAtIndex(int index);
+
+ // WebCore::PopupMenuClient methods:
+ virtual void valueChanged(unsigned listIndex, bool fireEvents = true);
+ virtual WebCore::String itemText(unsigned listIndex) const;
+ virtual WebCore::String itemToolTip(unsigned lastIndex) const { return WebCore::String(); }
+ virtual bool itemIsEnabled(unsigned listIndex) const { return true; }
+ virtual WebCore::PopupMenuStyle itemStyle(unsigned listIndex) const;
+ virtual WebCore::PopupMenuStyle menuStyle() const;
+ virtual int clientInsetLeft() const { return 0; }
+ virtual int clientInsetRight() const { return 0; }
+ virtual int clientPaddingLeft() const;
+ virtual int clientPaddingRight() const;
+ virtual int listSize() const { return m_suggestions.size(); }
+ virtual int selectedIndex() const { return m_selectedIndex; }
+ virtual void popupDidHide();
+ virtual bool itemIsSeparator(unsigned listIndex) const { return false; }
+ virtual bool itemIsLabel(unsigned listIndex) const { return false; }
+ virtual bool itemIsSelected(unsigned listIndex) const { return false; }
+ virtual bool shouldPopOver() const { return false; }
+ virtual bool valueShouldChangeOnHotTrack() const { return false; }
+ virtual void setTextFromItem(unsigned listIndex);
+ virtual WebCore::FontSelector* fontSelector() const;
+ virtual WebCore::HostWindow* hostWindow() const;
+ virtual PassRefPtr<WebCore::Scrollbar> createScrollbar(
+ WebCore::ScrollbarClient* client,
+ WebCore::ScrollbarOrientation orientation,
+ WebCore::ScrollbarControlSize size);
+
+private:
+ WebCore::RenderStyle* textFieldStyle() const;
+
+ RefPtr<WebCore::HTMLInputElement> m_textField;
+ Vector<WebCore::String> m_suggestions;
+ int m_selectedIndex;
+ WebViewImpl* m_webView;
+ OwnPtr<WebCore::PopupMenuStyle> m_style;
+};
+
+} // namespace WebKit
diff --git a/webkit/api/src/BackForwardListClientImpl.cpp b/webkit/api/src/BackForwardListClientImpl.cpp
index fc6defd..8feae32 100644
--- a/webkit/api/src/BackForwardListClientImpl.cpp
+++ b/webkit/api/src/BackForwardListClientImpl.cpp
@@ -33,9 +33,7 @@
#include "HistoryItem.h"
#include "WebViewClient.h"
-
-// FIXME: Remove this once WebViewImpl moves out of glue/.
-#include "webkit/glue/webview_impl.h"
+#include "WebViewImpl.h"
using namespace WebCore;
@@ -52,13 +50,13 @@ BackForwardListClientImpl::~BackForwardListClientImpl()
{
}
-void BackForwardListClientImpl::SetCurrentHistoryItem(HistoryItem* item)
+void BackForwardListClientImpl::setCurrentHistoryItem(HistoryItem* item)
{
m_previousItem = m_currentItem;
m_currentItem = item;
}
-HistoryItem* BackForwardListClientImpl::GetPreviousHistoryItem() const
+HistoryItem* BackForwardListClientImpl::previousHistoryItem() const
{
return m_previousItem.get();
}
@@ -70,7 +68,7 @@ void BackForwardListClientImpl::addItem(PassRefPtr<HistoryItem> item)
// If WebCore adds a new HistoryItem, it means this is a new navigation (ie,
// not a reload or back/forward).
- m_webView->ObserveNewNavigation();
+ m_webView->observeNewNavigation();
if (m_webView->client())
m_webView->client()->didAddHistoryItem();
diff --git a/webkit/api/src/BackForwardListClientImpl.h b/webkit/api/src/BackForwardListClientImpl.h
index e498ea0..1d8beb0 100644
--- a/webkit/api/src/BackForwardListClientImpl.h
+++ b/webkit/api/src/BackForwardListClientImpl.h
@@ -33,9 +33,8 @@
#include "BackForwardList.h"
-class WebViewImpl;
-
namespace WebKit {
+class WebViewImpl;
extern const char backForwardNavigationScheme[];
@@ -44,8 +43,8 @@ public:
BackForwardListClientImpl(WebViewImpl* webview);
~BackForwardListClientImpl();
- void SetCurrentHistoryItem(WebCore::HistoryItem* item);
- WebCore::HistoryItem* GetPreviousHistoryItem() const;
+ void setCurrentHistoryItem(WebCore::HistoryItem* item);
+ WebCore::HistoryItem* previousHistoryItem() const;
private:
// WebCore::BackForwardListClient methods:
diff --git a/webkit/api/src/ChromeClientImpl.cpp b/webkit/api/src/ChromeClientImpl.cpp
index a81c3aa..a28589c 100644
--- a/webkit/api/src/ChromeClientImpl.cpp
+++ b/webkit/api/src/ChromeClientImpl.cpp
@@ -56,24 +56,21 @@
#include "WebAccessibilityObject.h"
#include "WebConsoleMessage.h"
#include "WebCursorInfo.h"
-#include "WebFileChooserCompletion.h"
+#include "WebFileChooserCompletionImpl.h"
#include "WebFrameClient.h"
+#include "WebFrameImpl.h"
#include "WebInputEvent.h"
#include "WebKit.h"
+#include "WebPopupMenuImpl.h"
#include "WebPopupMenuInfo.h"
#include "WebRect.h"
#include "WebTextDirection.h"
#include "WebURLRequest.h"
#include "WebViewClient.h"
-#include "WebFileChooserCompletionImpl.h"
-#include "WebPopupMenuImpl.h"
+#include "WebViewImpl.h"
#include "WindowFeatures.h"
#include "WrappedResourceRequest.h"
-// FIXME: Remove these once they move out of glue/.
-#include "webkit/glue/webframe_impl.h"
-#include "webkit/glue/webview_impl.h"
-
using namespace WebCore;
namespace WebKit {
@@ -148,14 +145,14 @@ void ChromeClientImpl::focus()
// If accessibility is enabled, we should notify assistive technology that
// the active AccessibilityObject changed.
- const Frame* frame = m_webView->GetFocusedWebCoreFrame();
+ const Frame* frame = m_webView->focusedWebCoreFrame();
if (!frame)
return;
Document* doc = frame->document();
if (doc && doc->axObjectCache()->accessibilityEnabled()) {
- Node* focusedNode = m_webView->GetFocusedNode();
+ Node* focusedNode = m_webView->focusedWebCoreNode();
if (!focusedNode) {
// Could not retrieve focused Node.
@@ -202,7 +199,7 @@ Page* ChromeClientImpl::createWindow(
return 0;
WebViewImpl* newView = static_cast<WebViewImpl*>(
- m_webView->client()->createView(WebFrameImpl::FromFrame(frame)));
+ m_webView->client()->createView(WebFrameImpl::fromFrame(frame)));
if (!newView)
return 0;
@@ -210,13 +207,13 @@ Page* ChromeClientImpl::createWindow(
// This corresponds to window.open(""), for example.
if (!r.resourceRequest().isEmpty()) {
WrappedResourceRequest request(r.resourceRequest());
- newView->main_frame()->loadRequest(request);
+ newView->mainFrame()->loadRequest(request);
}
return newView->page();
}
-static inline bool CurrentEventShouldCauseBackgroundTab(const WebInputEvent* inputEvent)
+static inline bool currentEventShouldCauseBackgroundTab(const WebInputEvent* inputEvent)
{
if (!inputEvent)
return false;
@@ -246,7 +243,7 @@ static inline bool CurrentEventShouldCauseBackgroundTab(const WebInputEvent* inp
bool alt = mouseEvent->modifiers & WebMouseEvent::AltKey;
bool meta = mouseEvent->modifiers & WebMouseEvent::MetaKey;
- if (!WebViewImpl::NavigationPolicyFromMouseEvent(buttonNumber, ctrl, shift, alt, meta, &policy))
+ if (!WebViewImpl::navigationPolicyFromMouseEvent(buttonNumber, ctrl, shift, alt, meta, &policy))
return false;
return policy == WebNavigationPolicyNewBackgroundTab;
@@ -270,7 +267,7 @@ void ChromeClientImpl::show()
WebNavigationPolicy policy = WebNavigationPolicyNewForegroundTab;
if (asPopup)
policy = WebNavigationPolicyNewPopup;
- if (CurrentEventShouldCauseBackgroundTab(WebViewImpl::current_input_event()))
+ if (currentEventShouldCauseBackgroundTab(WebViewImpl::currentInputEvent()))
policy = WebNavigationPolicyNewBackgroundTab;
m_webView->client()->show(policy);
@@ -312,7 +309,7 @@ void ChromeClientImpl::setScrollbarsVisible(bool value)
m_scrollbarsVisible = value;
WebFrameImpl* web_frame = static_cast<WebFrameImpl*>(m_webView->mainFrame());
if (web_frame)
- web_frame->SetAllowsScrolling(value);
+ web_frame->setAllowsScrolling(value);
}
bool ChromeClientImpl::scrollbarsVisible()
@@ -359,7 +356,7 @@ bool ChromeClientImpl::runBeforeUnloadConfirmPanel(const String& message, Frame*
{
if (m_webView->client()) {
return m_webView->client()->runModalBeforeUnloadDialog(
- WebFrameImpl::FromFrame(frame), message);
+ WebFrameImpl::fromFrame(frame), message);
}
return false;
}
@@ -387,7 +384,7 @@ void ChromeClientImpl::runJavaScriptAlert(Frame* frame, const String& message)
V8Proxy::processConsoleMessages();
#endif
m_webView->client()->runModalAlertDialog(
- WebFrameImpl::FromFrame(frame), message);
+ WebFrameImpl::fromFrame(frame), message);
}
}
@@ -396,7 +393,7 @@ bool ChromeClientImpl::runJavaScriptConfirm(Frame* frame, const String& message)
{
if (m_webView->client()) {
return m_webView->client()->runModalConfirmDialog(
- WebFrameImpl::FromFrame(frame), message);
+ WebFrameImpl::fromFrame(frame), message);
}
return false;
}
@@ -410,7 +407,7 @@ bool ChromeClientImpl::runJavaScriptPrompt(Frame* frame,
if (m_webView->client()) {
WebString actualValue;
bool ok = m_webView->client()->runModalPromptDialog(
- WebFrameImpl::FromFrame(frame),
+ WebFrameImpl::fromFrame(frame),
message,
defaultValue,
&actualValue);
@@ -492,7 +489,7 @@ IntRect ChromeClientImpl::windowToScreen(const IntRect& rect) const {
void ChromeClientImpl::contentsSizeChanged(Frame* frame, const IntSize& size) const
{
- WebFrameImpl* webframe = WebFrameImpl::FromFrame(frame);
+ WebFrameImpl* webframe = WebFrameImpl::fromFrame(frame);
if (webframe->client())
webframe->client()->didChangeContentsSize(webframe, size);
}
@@ -527,7 +524,7 @@ void ChromeClientImpl::setToolTip(const String& tooltipText, TextDirection dir)
void ChromeClientImpl::print(Frame* frame)
{
if (m_webView->client())
- m_webView->client()->printPage(WebFrameImpl::FromFrame(frame));
+ m_webView->client()->printPage(WebFrameImpl::fromFrame(frame));
}
void ChromeClientImpl::exceededDatabaseQuota(Frame* frame, const String& databaseName)
@@ -613,7 +610,7 @@ void ChromeClientImpl::formStateDidChange(const Node* node)
{
// The current history item is not updated yet. That happens lazily when
// WebFrame::currentHistoryItem is requested.
- WebFrameImpl* webframe = WebFrameImpl::FromFrame(node->document()->frame());
+ WebFrameImpl* webframe = WebFrameImpl::fromFrame(node->document()->frame());
if (webframe->client())
webframe->client()->didUpdateCurrentHistoryItem(webframe);
}
@@ -655,7 +652,7 @@ void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer,
#if ENABLE(NOTIFICATIONS)
NotificationPresenter* ChromeClientImpl::notificationPresenter() const
{
- return m_webView->GetNotificationPresenter();
+ return m_webView->notificationPresenterImpl();
}
#endif
diff --git a/webkit/api/src/ChromeClientImpl.h b/webkit/api/src/ChromeClientImpl.h
index 427390a..9a1e443 100644
--- a/webkit/api/src/ChromeClientImpl.h
+++ b/webkit/api/src/ChromeClientImpl.h
@@ -33,8 +33,6 @@
#include "ChromeClientChromium.h"
-class WebViewImpl;
-
namespace WebCore {
class HTMLParserQuirks;
class PopupContainer;
@@ -43,6 +41,7 @@ struct WindowFeatures;
}
namespace WebKit {
+class WebViewImpl;
struct WebCursorInfo;
struct WebPopupMenuInfo;
diff --git a/webkit/api/src/ContextMenuClientImpl.cpp b/webkit/api/src/ContextMenuClientImpl.cpp
index fd2a7a8..f32c72f 100644
--- a/webkit/api/src/ContextMenuClientImpl.cpp
+++ b/webkit/api/src/ContextMenuClientImpl.cpp
@@ -48,17 +48,14 @@
#include "Widget.h"
#include "WebContextMenuData.h"
-#include "WebFrame.h"
+#include "WebDataSourceImpl.h"
+#include "WebFrameImpl.h"
#include "WebPoint.h"
#include "WebString.h"
#include "WebURL.h"
#include "WebURLResponse.h"
#include "WebViewClient.h"
-#include "WebDataSourceImpl.h"
-#undef LOG
-
-// FIXME: Temporary hack until WebViewImpl is in api/src.
-#include "webkit/glue/webview_impl.h"
+#include "WebViewImpl.h"
using namespace WebCore;
@@ -143,7 +140,7 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems(
// response to user input (Mouse event WM_RBUTTONDOWN,
// Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked
// in response to the above input events before popping up the context menu.
- if (!m_webView->context_menu_allowed())
+ if (!m_webView->contextMenuAllowed())
return 0;
HitTestResult r = defaultMenu->hitTestResult();
@@ -192,8 +189,8 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems(
data.frameEncoding = selectedFrame->loader()->encoding();
// Send the frame and page URLs in any case.
- data.pageURL = urlFromFrame(m_webView->main_frame()->frame());
- if (selectedFrame != m_webView->main_frame()->frame())
+ data.pageURL = urlFromFrame(m_webView->mainFrameImpl()->frame());
+ if (selectedFrame != m_webView->mainFrameImpl()->frame())
data.frameURL = urlFromFrame(selectedFrame);
if (r.isSelected())
@@ -202,7 +199,7 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems(
data.isEditable = false;
if (r.isContentEditable()) {
data.isEditable = true;
- if (m_webView->GetFocusedWebCoreFrame()->editor()->isContinuousSpellCheckingEnabled()) {
+ if (m_webView->focusedWebCoreFrame()->editor()->isContinuousSpellCheckingEnabled()) {
data.isSpellCheckingEnabled = true;
data.misspelledWord = selectMisspelledWord(defaultMenu, selectedFrame);
}
@@ -216,22 +213,22 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems(
// Compute edit flags.
data.editFlags = WebContextMenuData::CanDoNone;
- if (m_webView->GetFocusedWebCoreFrame()->editor()->canUndo())
+ if (m_webView->focusedWebCoreFrame()->editor()->canUndo())
data.editFlags |= WebContextMenuData::CanUndo;
- if (m_webView->GetFocusedWebCoreFrame()->editor()->canRedo())
+ if (m_webView->focusedWebCoreFrame()->editor()->canRedo())
data.editFlags |= WebContextMenuData::CanRedo;
- if (m_webView->GetFocusedWebCoreFrame()->editor()->canCut())
+ if (m_webView->focusedWebCoreFrame()->editor()->canCut())
data.editFlags |= WebContextMenuData::CanCut;
- if (m_webView->GetFocusedWebCoreFrame()->editor()->canCopy())
+ if (m_webView->focusedWebCoreFrame()->editor()->canCopy())
data.editFlags |= WebContextMenuData::CanCopy;
- if (m_webView->GetFocusedWebCoreFrame()->editor()->canPaste())
+ if (m_webView->focusedWebCoreFrame()->editor()->canPaste())
data.editFlags |= WebContextMenuData::CanPaste;
- if (m_webView->GetFocusedWebCoreFrame()->editor()->canDelete())
+ if (m_webView->focusedWebCoreFrame()->editor()->canDelete())
data.editFlags |= WebContextMenuData::CanDelete;
// We can always select all...
data.editFlags |= WebContextMenuData::CanSelectAll;
- WebFrame* selected_web_frame = WebFrameImpl::FromFrame(selectedFrame);
+ WebFrame* selected_web_frame = WebFrameImpl::fromFrame(selectedFrame);
if (m_webView->client())
m_webView->client()->showContextMenu(selected_web_frame, data);
diff --git a/webkit/api/src/ContextMenuClientImpl.h b/webkit/api/src/ContextMenuClientImpl.h
index 712891c..a19b247 100644
--- a/webkit/api/src/ContextMenuClientImpl.h
+++ b/webkit/api/src/ContextMenuClientImpl.h
@@ -33,9 +33,8 @@
#include "ContextMenuClient.h"
-class WebViewImpl;
-
namespace WebKit {
+ class WebViewImpl;
class ContextMenuClientImpl : public WebCore::ContextMenuClient {
public:
diff --git a/webkit/api/src/DragClientImpl.cpp b/webkit/api/src/DragClientImpl.cpp
index 77c5ad8..5d8a9c3 100644
--- a/webkit/api/src/DragClientImpl.cpp
+++ b/webkit/api/src/DragClientImpl.cpp
@@ -36,9 +36,7 @@
#include "Frame.h"
#include "WebDragData.h"
#include "WebViewClient.h"
-
-// FIXME: Remove this once WebViewImpl moves out of glue/.
-#include "webkit/glue/webview_impl.h"
+#include "WebViewImpl.h"
using namespace WebCore;
@@ -85,7 +83,7 @@ void DragClientImpl::startDrag(DragImageRef dragImage,
if (!clipboard->sourceOperation(dragOperationMask))
dragOperationMask = DragOperationEvery;
- m_webView->StartDragging(
+ m_webView->startDragging(
eventPos, dragData, static_cast<WebDragOperationsMask>(dragOperationMask));
}
diff --git a/webkit/api/src/DragClientImpl.h b/webkit/api/src/DragClientImpl.h
index 6eea773..7012370 100644
--- a/webkit/api/src/DragClientImpl.h
+++ b/webkit/api/src/DragClientImpl.h
@@ -41,9 +41,8 @@ class IntPoint;
class KURL;
}
-class WebViewImpl;
-
namespace WebKit {
+class WebViewImpl;
class DragClientImpl : public WebCore::DragClient {
public:
diff --git a/webkit/api/src/EditorClientImpl.cpp b/webkit/api/src/EditorClientImpl.cpp
index 058b892..d604d68 100644
--- a/webkit/api/src/EditorClientImpl.cpp
+++ b/webkit/api/src/EditorClientImpl.cpp
@@ -41,15 +41,16 @@
#include "PlatformString.h"
#include "RenderObject.h"
+#include "DOMUtilitiesPrivate.h"
+#include "PasswordAutocompleteListener.h"
#include "WebEditingAction.h"
+#include "WebFrameImpl.h"
#include "WebKit.h"
#include "WebNode.h"
#include "WebRange.h"
#include "WebTextAffinity.h"
#include "WebViewClient.h"
-#include "DOMUtilitiesPrivate.h"
-#include "PasswordAutocompleteListener.h"
-#include "webkit/glue/webview_impl.h"
+#include "WebViewImpl.h"
using namespace WebCore;
@@ -114,7 +115,7 @@ bool EditorClientImpl::shouldSpellcheckByDefault()
{
// Spellcheck should be enabled for all editable areas (such as textareas,
// contentEditable regions, and designMode docs), except text inputs.
- const Frame* frame = m_webView->GetFocusedWebCoreFrame();
+ const Frame* frame = m_webView->focusedWebCoreFrame();
if (!frame)
return false;
const Editor* editor = frame->editor();
@@ -265,7 +266,7 @@ void EditorClientImpl::didBeginEditing()
void EditorClientImpl::respondToChangedSelection()
{
if (m_webView->client()) {
- Frame* frame = m_webView->GetFocusedWebCoreFrame();
+ Frame* frame = m_webView->focusedWebCoreFrame();
if (frame)
m_webView->client()->didChangeSelection(!frame->selection()->isRange());
}
@@ -653,7 +654,7 @@ void EditorClientImpl::textFieldDidEndEditing(Element* element)
m_autofillTimer.stop();
// Hide any showing popup.
- m_webView->HideAutoCompletePopup();
+ m_webView->hideAutoCompletePopup();
if (!m_webView->client())
return; // The page is getting closed, don't fill the password.
@@ -663,8 +664,8 @@ void EditorClientImpl::textFieldDidEndEditing(Element* element)
if (!inputElement)
return;
- WebFrameImpl* webframe = WebFrameImpl::FromFrame(inputElement->document()->frame());
- PasswordAutocompleteListener* listener = webframe->GetPasswordListener(inputElement);
+ WebFrameImpl* webframe = WebFrameImpl::fromFrame(inputElement->document()->frame());
+ PasswordAutocompleteListener* listener = webframe->getPasswordListener(inputElement);
if (!listener)
return;
@@ -744,15 +745,15 @@ void EditorClientImpl::doAutofill(Timer<EditorClientImpl>* timer)
&& inputElement->selectionEnd() == static_cast<int>(value.length());
if ((!args->autofillOnEmptyValue && value.isEmpty()) || !isCaretAtEnd) {
- m_webView->HideAutoCompletePopup();
+ m_webView->hideAutoCompletePopup();
return;
}
// First let's see if there is a password listener for that element.
// We won't trigger form autofill in that case, as having both behavior on
// a node would be confusing.
- WebFrameImpl* webframe = WebFrameImpl::FromFrame(inputElement->document()->frame());
- PasswordAutocompleteListener* listener = webframe->GetPasswordListener(inputElement);
+ WebFrameImpl* webframe = WebFrameImpl::fromFrame(inputElement->document()->frame());
+ PasswordAutocompleteListener* listener = webframe->getPasswordListener(inputElement);
if (listener) {
if (args->autofillFormOnly)
return;
@@ -780,8 +781,8 @@ void EditorClientImpl::cancelPendingAutofill()
void EditorClientImpl::onAutofillSuggestionAccepted(HTMLInputElement* textField)
{
- WebFrameImpl* webframe = WebFrameImpl::FromFrame(textField->document()->frame());
- PasswordAutocompleteListener* listener = webframe->GetPasswordListener(textField);
+ WebFrameImpl* webframe = WebFrameImpl::fromFrame(textField->document()->frame());
+ PasswordAutocompleteListener* listener = webframe->getPasswordListener(textField);
// Password listeners need to autocomplete other fields that depend on the
// input element with autofill suggestions.
if (listener)
diff --git a/webkit/api/src/EditorClientImpl.h b/webkit/api/src/EditorClientImpl.h
index 55cd0b7..fd08b4d 100644
--- a/webkit/api/src/EditorClientImpl.h
+++ b/webkit/api/src/EditorClientImpl.h
@@ -39,9 +39,8 @@ namespace WebCore {
class HTMLInputElement;
}
-class WebViewImpl;
-
namespace WebKit {
+class WebViewImpl;
class EditorClientImpl : public WebCore::EditorClient {
public:
diff --git a/webkit/api/src/FrameLoaderClientImpl.cpp b/webkit/api/src/FrameLoaderClientImpl.cpp
new file mode 100644
index 0000000..3b7a906
--- /dev/null
+++ b/webkit/api/src/FrameLoaderClientImpl.cpp
@@ -0,0 +1,1405 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FrameLoaderClientImpl.h"
+
+#include "Chrome.h"
+#include "CString.h"
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "HTMLAppletElement.h"
+#include "HTMLFormElement.h" // needed by FormState.h
+#include "HTMLNames.h"
+#include "FormState.h"
+#include "FrameLoader.h"
+#include "FrameLoadRequest.h"
+#include "HitTestResult.h"
+#include "MIMETypeRegistry.h"
+#include "MouseEvent.h"
+#include "Page.h"
+#include "PlatformString.h"
+#include "PluginData.h"
+#include "StringExtras.h"
+#include "WebForm.h"
+#include "WebFrameClient.h"
+#include "WebFrameImpl.h"
+#include "WebNode.h"
+#include "WebPlugin.h"
+#include "WebPluginParams.h"
+#include "WebSecurityOrigin.h"
+#include "WebURL.h"
+#include "WebURLError.h"
+#include "WebVector.h"
+#include "WebViewClient.h"
+#include "WebViewImpl.h"
+#include "WebDataSourceImpl.h"
+#include "WebPluginContainerImpl.h"
+#include "WebPluginLoadObserver.h"
+#include "WindowFeatures.h"
+#include "WrappedResourceRequest.h"
+#include "WrappedResourceResponse.h"
+
+// FIXME: remove these
+#include "googleurl/src/gurl.h"
+#include "net/base/mime_util.h"
+#include "webkit/glue/glue_util.h"
+#include "webkit/glue/webdevtoolsagent_impl.h"
+#include "webkit/glue/webkit_glue.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// Domain for internal error codes.
+static const char internalErrorDomain[] = "WebKit";
+
+// An internal error code. Used to note a policy change error resulting from
+// dispatchDecidePolicyForMIMEType not passing the PolicyUse option.
+enum {
+ PolicyChangeError = -10000,
+};
+
+FrameLoaderClientImpl::FrameLoaderClientImpl(WebFrameImpl* frame)
+ : m_webFrame(frame)
+ , m_hasRepresentation(false)
+ , m_sentInitialResponseToPlugin(false)
+ , m_nextNavigationPolicy(WebNavigationPolicyIgnore) {
+}
+
+FrameLoaderClientImpl::~FrameLoaderClientImpl() {
+}
+
+void FrameLoaderClientImpl::frameLoaderDestroyed()
+{
+ // When the WebFrame was created, it had an extra reference given to it on
+ // behalf of the Frame. Since the WebFrame owns us, this extra ref also
+ // serves to keep us alive until the FrameLoader is done with us. The
+ // FrameLoader calls this method when it's going away. Therefore, we balance
+ // out that extra reference, which may cause 'this' to be deleted.
+ m_webFrame->closing();
+ m_webFrame->deref();
+}
+
+void FrameLoaderClientImpl::windowObjectCleared()
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didClearWindowObject(m_webFrame);
+
+ WebViewImpl* webview = m_webFrame->viewImpl();
+ if (webview) {
+ WebDevToolsAgentImpl* toolsAgent = webview->devToolsAgentImpl();
+ if (toolsAgent)
+ toolsAgent->WindowObjectCleared(m_webFrame);
+ }
+}
+
+void FrameLoaderClientImpl::documentElementAvailable()
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didCreateDocumentElement(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didCreateScriptContextForFrame()
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didCreateScriptContext(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didDestroyScriptContextForFrame()
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didDestroyScriptContext(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didCreateIsolatedScriptContext()
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didCreateIsolatedScriptContext(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didPerformFirstNavigation() const
+{
+}
+
+void FrameLoaderClientImpl::registerForIconNotification(bool)
+{
+}
+
+bool FrameLoaderClientImpl::hasWebView() const
+{
+ return m_webFrame->viewImpl() != 0;
+}
+
+bool FrameLoaderClientImpl::hasFrameView() const
+{
+ // The Mac port has this notion of a WebFrameView, which seems to be
+ // some wrapper around an NSView. Since our equivalent is HWND, I guess
+ // we have a "frameview" whenever we have the toplevel HWND.
+ return m_webFrame->viewImpl() != 0;
+}
+
+void FrameLoaderClientImpl::makeDocumentView()
+{
+ m_webFrame->createFrameView();
+}
+
+void FrameLoaderClientImpl::makeRepresentation(DocumentLoader*)
+{
+ m_hasRepresentation = true;
+}
+
+void FrameLoaderClientImpl::forceLayout()
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::forceLayoutForNonHTML()
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::setCopiesOnScroll()
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::detachedFromParent2()
+{
+ // Nothing to do here.
+}
+
+void FrameLoaderClientImpl::detachedFromParent3()
+{
+ // Close down the proxy. The purpose of this change is to make the
+ // call to ScriptController::clearWindowShell a no-op when called from
+ // Frame::pageDestroyed. Without this change, this call to clearWindowShell
+ // will cause a crash. If you remove/modify this, just ensure that you can
+ // go to a page and then navigate to a new page without getting any asserts
+ // or crashes.
+ m_webFrame->frame()->script()->proxy()->clearForClose();
+}
+
+// This function is responsible for associating the |identifier| with a given
+// subresource load. The following functions that accept an |identifier| are
+// called for each subresource, so they should not be dispatched to the
+// WebFrame.
+void FrameLoaderClientImpl::assignIdentifierToInitialRequest(
+ unsigned long identifier, DocumentLoader* loader,
+ const ResourceRequest& request)
+{
+ if (m_webFrame->client()) {
+ WrappedResourceRequest webreq(request);
+ m_webFrame->client()->assignIdentifierToRequest(
+ m_webFrame, identifier, webreq);
+ }
+}
+
+// Determines whether the request being loaded by |loader| is a frame or a
+// subresource. A subresource in this context is anything other than a frame --
+// this includes images and xmlhttp requests. It is important to note that a
+// subresource is NOT limited to stuff loaded through the frame's subresource
+// loader. Synchronous xmlhttp requests for example, do not go through the
+// subresource loader, but we still label them as TargetIsSubResource.
+//
+// The important edge cases to consider when modifying this function are
+// how synchronous resource loads are treated during load/unload threshold.
+static ResourceRequest::TargetType determineTargetTypeFromLoader(
+ DocumentLoader* loader)
+{
+ if (loader == loader->frameLoader()->provisionalDocumentLoader()) {
+ if (loader->frameLoader()->isLoadingMainFrame())
+ return ResourceRequest::TargetIsMainFrame;
+ else
+ return ResourceRequest::TargetIsSubFrame;
+ }
+ return ResourceRequest::TargetIsSubResource;
+}
+
+void FrameLoaderClientImpl::dispatchWillSendRequest(
+ DocumentLoader* loader, unsigned long identifier, ResourceRequest& request,
+ const ResourceResponse& redirectResponse)
+{
+ if (loader) {
+ // We want to distinguish between a request for a document to be loaded into
+ // the main frame, a sub-frame, or the sub-objects in that document.
+ request.setTargetType(determineTargetTypeFromLoader(loader));
+ }
+
+ // FrameLoader::loadEmptyDocumentSynchronously() creates an empty document
+ // with no URL. We don't like that, so we'll rename it to about:blank.
+ if (request.url().isEmpty())
+ request.setURL(KURL(ParsedURLString, "about:blank"));
+ if (request.firstPartyForCookies().isEmpty())
+ request.setFirstPartyForCookies(KURL(ParsedURLString, "about:blank"));
+
+ // Give the WebFrameClient a crack at the request.
+ if (m_webFrame->client()) {
+ WrappedResourceRequest webreq(request);
+ WrappedResourceResponse webresp(redirectResponse);
+ m_webFrame->client()->willSendRequest(
+ m_webFrame, identifier, webreq, webresp);
+ }
+}
+
+bool FrameLoaderClientImpl::shouldUseCredentialStorage(
+ DocumentLoader*, unsigned long identifier)
+{
+ // FIXME
+ // Intended to pass through to a method on the resource load delegate.
+ // If implemented, that method controls whether the browser should ask the
+ // networking layer for a stored default credential for the page (say from
+ // the Mac OS keychain). If the method returns false, the user should be
+ // presented with an authentication challenge whether or not the networking
+ // layer has a credential stored.
+ // This returns true for backward compatibility: the ability to override the
+ // system credential store is new. (Actually, not yet fully implemented in
+ // WebKit, as of this writing.)
+ return true;
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveAuthenticationChallenge(
+ DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::dispatchDidCancelAuthenticationChallenge(
+ DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveResponse(DocumentLoader* loader,
+ unsigned long identifier,
+ const ResourceResponse& response)
+{
+ if (m_webFrame->client()) {
+ WrappedResourceResponse webresp(response);
+ m_webFrame->client()->didReceiveResponse(m_webFrame, identifier, webresp);
+ }
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveContentLength(
+ DocumentLoader* loader,
+ unsigned long identifier,
+ int lengthReceived)
+{
+}
+
+// Called when a particular resource load completes
+void FrameLoaderClientImpl::dispatchDidFinishLoading(DocumentLoader* loader,
+ unsigned long identifier)
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didFinishResourceLoad(m_webFrame, identifier);
+}
+
+void FrameLoaderClientImpl::dispatchDidFailLoading(DocumentLoader* loader,
+ unsigned long identifier,
+ const ResourceError& error)
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didFailResourceLoad(m_webFrame, identifier, error);
+}
+
+void FrameLoaderClientImpl::dispatchDidFinishDocumentLoad()
+{
+ // A frame may be reused. This call ensures we don't hold on to our password
+ // listeners and their associated HTMLInputElements.
+ m_webFrame->clearPasswordListeners();
+
+ if (m_webFrame->client())
+ m_webFrame->client()->didFinishDocumentLoad(m_webFrame);
+}
+
+bool FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache(
+ DocumentLoader* loader,
+ const ResourceRequest& request,
+ const ResourceResponse& response,
+ int length)
+{
+ if (m_webFrame->client()) {
+ WrappedResourceRequest webreq(request);
+ WrappedResourceResponse webresp(response);
+ m_webFrame->client()->didLoadResourceFromMemoryCache(
+ m_webFrame, webreq, webresp);
+ }
+ return false; // Do not suppress remaining notifications
+}
+
+void FrameLoaderClientImpl::dispatchDidLoadResourceByXMLHttpRequest(
+ unsigned long identifier,
+ const ScriptString& source)
+{
+}
+
+void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents()
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didHandleOnloadEvents(m_webFrame);
+}
+
+// Redirect Tracking
+// =================
+// We want to keep track of the chain of redirects that occur during page
+// loading. There are two types of redirects, server redirects which are HTTP
+// response codes, and client redirects which are document.location= and meta
+// refreshes.
+//
+// This outlines the callbacks that we get in different redirect situations,
+// and how each call modifies the redirect chain.
+//
+// Normal page load
+// ----------------
+// dispatchDidStartProvisionalLoad() -> adds URL to the redirect list
+// dispatchDidCommitLoad() -> DISPATCHES & clears list
+//
+// Server redirect (success)
+// -------------------------
+// dispatchDidStartProvisionalLoad() -> adds source URL
+// dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL
+// dispatchDidCommitLoad() -> DISPATCHES
+//
+// Client redirect (success)
+// -------------------------
+// (on page)
+// dispatchWillPerformClientRedirect() -> saves expected redirect
+// dispatchDidStartProvisionalLoad() -> appends redirect source (since
+// it matches the expected redirect)
+// and the current page as the dest)
+// dispatchDidCancelClientRedirect() -> clears expected redirect
+// dispatchDidCommitLoad() -> DISPATCHES
+//
+// Client redirect (cancelled)
+// (e.g meta-refresh trumped by manual doc.location change, or just cancelled
+// because a link was clicked that requires the meta refresh to be rescheduled
+// (the SOURCE URL may have changed).
+// ---------------------------
+// dispatchDidCancelClientRedirect() -> clears expected redirect
+// dispatchDidStartProvisionalLoad() -> adds only URL to redirect list
+// dispatchDidCommitLoad() -> DISPATCHES & clears list
+// rescheduled ? dispatchWillPerformClientRedirect() -> saves expected redirect
+// : nothing
+
+// Client redirect (failure)
+// -------------------------
+// (on page)
+// dispatchWillPerformClientRedirect() -> saves expected redirect
+// dispatchDidStartProvisionalLoad() -> appends redirect source (since
+// it matches the expected redirect)
+// and the current page as the dest)
+// dispatchDidCancelClientRedirect()
+// dispatchDidFailProvisionalLoad()
+//
+// Load 1 -> Server redirect to 2 -> client redirect to 3 -> server redirect to 4
+// ------------------------------------------------------------------------------
+// dispatchDidStartProvisionalLoad() -> adds source URL 1
+// dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL 2
+// dispatchDidCommitLoad() -> DISPATCHES 1+2
+// -- begin client redirect and NEW DATA SOURCE
+// dispatchWillPerformClientRedirect() -> saves expected redirect
+// dispatchDidStartProvisionalLoad() -> appends URL 2 and URL 3
+// dispatchDidReceiveServerRedirectForProvisionalLoad() -> appends destination URL 4
+// dispatchDidCancelClientRedirect() -> clears expected redirect
+// dispatchDidCommitLoad() -> DISPATCHES
+//
+// Interesting case with multiple location changes involving anchors.
+// Load page 1 containing future client-redirect (back to 1, e.g meta refresh) > Click
+// on a link back to the same page (i.e an anchor href) >
+// client-redirect finally fires (with new source, set to 1#anchor)
+// -----------------------------------------------------------------------------
+// dispatchWillPerformClientRedirect(non-zero 'interval' param) -> saves expected redirect
+// -- click on anchor href
+// dispatchDidCancelClientRedirect() -> clears expected redirect
+// dispatchDidStartProvisionalLoad() -> adds 1#anchor source
+// dispatchDidCommitLoad() -> DISPATCHES 1#anchor
+// dispatchWillPerformClientRedirect() -> saves exp. source (1#anchor)
+// -- redirect timer fires
+// dispatchDidStartProvisionalLoad() -> appends 1#anchor (src) and 1 (dest)
+// dispatchDidCancelClientRedirect() -> clears expected redirect
+// dispatchDidCommitLoad() -> DISPATCHES 1#anchor + 1
+//
+void FrameLoaderClientImpl::dispatchDidReceiveServerRedirectForProvisionalLoad()
+{
+ WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
+ if (!ds) {
+ // Got a server redirect when there is no provisional DS!
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ // The server redirect may have been blocked.
+ if (ds->request().isNull())
+ return;
+
+ // A provisional load should have started already, which should have put an
+ // entry in our redirect chain.
+ ASSERT(ds->hasRedirectChain());
+
+ // The URL of the destination is on the provisional data source. We also need
+ // to update the redirect chain to account for this addition (we do this
+ // before the callback so the callback can look at the redirect chain to see
+ // what happened).
+ ds->appendRedirect(ds->request().url());
+
+ if (m_webFrame->client())
+ m_webFrame->client()->didReceiveServerRedirectForProvisionalLoad(m_webFrame);
+}
+
+// Called on both success and failure of a client redirect.
+void FrameLoaderClientImpl::dispatchDidCancelClientRedirect()
+{
+ // No longer expecting a client redirect.
+ if (m_webFrame->client()) {
+ m_expectedClientRedirectSrc = KURL();
+ m_expectedClientRedirectDest = KURL();
+ m_webFrame->client()->didCancelClientRedirect(m_webFrame);
+ }
+
+ // No need to clear the redirect chain, since that data source has already
+ // been deleted by the time this function is called.
+}
+
+void FrameLoaderClientImpl::dispatchWillPerformClientRedirect(
+ const KURL& url,
+ double interval,
+ double fireDate)
+{
+ // Tells dispatchDidStartProvisionalLoad that if it sees this item it is a
+ // redirect and the source item should be added as the start of the chain.
+ m_expectedClientRedirectSrc = m_webFrame->url();
+ m_expectedClientRedirectDest = url;
+
+ // FIXME: bug 1135512. Webkit does not properly notify us of cancelling
+ // http > file client redirects. Since the FrameLoader's policy is to never
+ // carry out such a navigation anyway, the best thing we can do for now to
+ // not get confused is ignore this notification.
+ if (m_expectedClientRedirectDest.isLocalFile()
+ && m_expectedClientRedirectSrc.protocolInHTTPFamily()) {
+ m_expectedClientRedirectSrc = KURL();
+ m_expectedClientRedirectDest = KURL();
+ return;
+ }
+
+ if (m_webFrame->client()) {
+ m_webFrame->client()->willPerformClientRedirect(
+ m_webFrame,
+ m_expectedClientRedirectSrc,
+ m_expectedClientRedirectDest,
+ static_cast<unsigned int>(interval),
+ static_cast<unsigned int>(fireDate));
+ }
+}
+
+void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage()
+{
+ // Anchor fragment navigations are not normal loads, so we need to synthesize
+ // some events for our delegate.
+ WebViewImpl* webView = m_webFrame->viewImpl();
+ if (webView->client())
+ webView->client()->didStartLoading();
+
+ WebDataSourceImpl* ds = m_webFrame->dataSourceImpl();
+ ASSERT(ds); // Should not be null when navigating to a reference fragment!
+ if (ds) {
+ KURL url = ds->request().url();
+ KURL chainEnd;
+ if (ds->hasRedirectChain()) {
+ chainEnd = ds->endOfRedirectChain();
+ ds->clearRedirectChain();
+ }
+
+ // Figure out if this location change is because of a JS-initiated
+ // client redirect (e.g onload/setTimeout document.location.href=).
+ // FIXME: (bugs 1085325, 1046841) We don't get proper redirect
+ // performed/cancelled notifications across anchor navigations, so the
+ // other redirect-tracking code in this class (see
+ // dispatch*ClientRedirect() and dispatchDidStartProvisionalLoad) is
+ // insufficient to catch and properly flag these transitions. Once a
+ // proper fix for this bug is identified and applied the following
+ // block may no longer be required.
+ bool wasClientRedirect =
+ (url == m_expectedClientRedirectDest && chainEnd == m_expectedClientRedirectSrc)
+ || !m_webFrame->isProcessingUserGesture();
+
+ if (wasClientRedirect) {
+ if (m_webFrame->client())
+ m_webFrame->client()->didCompleteClientRedirect(m_webFrame, chainEnd);
+ ds->appendRedirect(chainEnd);
+ // Make sure we clear the expected redirect since we just effectively
+ // completed it.
+ m_expectedClientRedirectSrc = KURL();
+ m_expectedClientRedirectDest = KURL();
+ }
+
+ // Regardless of how we got here, we are navigating to a URL so we need to
+ // add it to the redirect chain.
+ ds->appendRedirect(url);
+ }
+
+ bool isNewNavigation;
+ webView->didCommitLoad(&isNewNavigation);
+ if (m_webFrame->client())
+ m_webFrame->client()->didChangeLocationWithinPage(m_webFrame, isNewNavigation);
+
+ if (webView->client())
+ webView->client()->didStopLoading();
+}
+
+void FrameLoaderClientImpl::dispatchWillClose()
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->willClose(m_webFrame);
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveIcon()
+{
+ // The icon database is disabled, so this should never be called.
+ ASSERT_NOT_REACHED();
+}
+
+void FrameLoaderClientImpl::dispatchDidStartProvisionalLoad() {
+ // In case a redirect occurs, we need this to be set so that the redirect
+ // handling code can tell where the redirect came from. Server redirects
+ // will occur on the provisional load, so we need to keep track of the most
+ // recent provisional load URL.
+ // See dispatchDidReceiveServerRedirectForProvisionalLoad.
+ WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
+ if (!ds) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ KURL url = ds->request().url();
+
+ // Since the provisional load just started, we should have not gotten
+ // any redirects yet.
+ ASSERT(!ds->hasRedirectChain());
+
+ // If this load is what we expected from a client redirect, treat it as a
+ // redirect from that original page. The expected redirect urls will be
+ // cleared by DidCancelClientRedirect.
+ bool completingClientRedirect = false;
+ if (m_expectedClientRedirectSrc.isValid()) {
+ // m_expectedClientRedirectDest could be something like
+ // "javascript:history.go(-1)" thus we need to exclude url starts with
+ // "javascript:". See bug: 1080873
+ ASSERT(m_expectedClientRedirectDest.protocolIs("javascript")
+ || m_expectedClientRedirectDest == url);
+ ds->appendRedirect(m_expectedClientRedirectSrc);
+ completingClientRedirect = true;
+ }
+ ds->appendRedirect(url);
+
+ if (m_webFrame->client()) {
+ // Whatever information didCompleteClientRedirect contains should only
+ // be considered relevant until the next provisional load has started.
+ // So we first tell the client that the load started, and then tell it
+ // about the client redirect the load is responsible for completing.
+ m_webFrame->client()->didStartProvisionalLoad(m_webFrame);
+ if (completingClientRedirect) {
+ m_webFrame->client()->didCompleteClientRedirect(
+ m_webFrame, m_expectedClientRedirectSrc);
+ }
+ }
+}
+
+void FrameLoaderClientImpl::dispatchDidReceiveTitle(const String& title)
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didReceiveTitle(m_webFrame, title);
+}
+
+void FrameLoaderClientImpl::dispatchDidCommitLoad()
+{
+ WebViewImpl* webview = m_webFrame->viewImpl();
+ bool isNewNavigation;
+ webview->didCommitLoad(&isNewNavigation);
+
+ if (m_webFrame->client())
+ m_webFrame->client()->didCommitProvisionalLoad(m_webFrame, isNewNavigation);
+
+ WebDevToolsAgentImpl* toolsAgent = webview->devToolsAgentImpl();
+ if (toolsAgent)
+ toolsAgent->DidCommitLoadForFrame(webview, m_webFrame, isNewNavigation);
+}
+
+void FrameLoaderClientImpl::dispatchDidFailProvisionalLoad(
+ const ResourceError& error)
+{
+
+ // If a policy change occured, then we do not want to inform the plugin
+ // delegate. See http://b/907789 for details. FIXME: This means the
+ // plugin won't receive NPP_URLNotify, which seems like it could result in
+ // a memory leak in the plugin!!
+ if (error.domain() == internalErrorDomain
+ && error.errorCode() == PolicyChangeError) {
+ m_webFrame->didFail(cancelledError(error.failingURL()), true);
+ return;
+ }
+
+ OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
+ m_webFrame->didFail(error, true);
+ if (observer)
+ observer->didFailLoading(error);
+}
+
+void FrameLoaderClientImpl::dispatchDidFailLoad(const ResourceError& error)
+{
+ OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
+ m_webFrame->didFail(error, false);
+ if (observer)
+ observer->didFailLoading(error);
+
+ // Don't clear the redirect chain, this will happen in the middle of client
+ // redirects, and we need the context. The chain will be cleared when the
+ // provisional load succeeds or fails, not the "real" one.
+}
+
+void FrameLoaderClientImpl::dispatchDidFinishLoad()
+{
+ OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
+
+ if (m_webFrame->client())
+ m_webFrame->client()->didFinishLoad(m_webFrame);
+
+ if (observer)
+ observer->didFinishLoading();
+
+ // Don't clear the redirect chain, this will happen in the middle of client
+ // redirects, and we need the context. The chain will be cleared when the
+ // provisional load succeeds or fails, not the "real" one.
+}
+
+void FrameLoaderClientImpl::dispatchDidFirstLayout()
+{
+}
+
+void FrameLoaderClientImpl::dispatchDidFirstVisuallyNonEmptyLayout()
+{
+ // FIXME: called when webkit finished layout of a page that was visually
+ // non-empty.
+ // All resources have not necessarily finished loading.
+}
+
+Frame* FrameLoaderClientImpl::dispatchCreatePage()
+{
+ struct WindowFeatures features;
+ Page* newPage = m_webFrame->frame()->page()->chrome()->createWindow(
+ m_webFrame->frame(), FrameLoadRequest(), features);
+
+ // Make sure that we have a valid disposition. This should have been set in
+ // the preceeding call to dispatchDecidePolicyForNewWindowAction.
+ ASSERT(m_nextNavigationPolicy != WebNavigationPolicyIgnore);
+ WebNavigationPolicy policy = m_nextNavigationPolicy;
+ m_nextNavigationPolicy = WebNavigationPolicyIgnore;
+
+ // createWindow can return null (e.g., popup blocker denies the window).
+ if (!newPage)
+ return 0;
+
+ WebViewImpl::fromPage(newPage)->setInitialNavigationPolicy(policy);
+ return newPage->mainFrame();
+}
+
+void FrameLoaderClientImpl::dispatchShow()
+{
+ WebViewImpl* webView = m_webFrame->viewImpl();
+ if (webView && webView->client())
+ webView->client()->show(webView->initialNavigationPolicy());
+}
+
+static bool shouldTreatAsAttachment(const ResourceResponse& response)
+{
+ const String& contentDisposition =
+ response.httpHeaderField("Content-Disposition");
+ if (contentDisposition.isEmpty())
+ return false;
+
+ // Some broken sites just send
+ // Content-Disposition: ; filename="file"
+ // screen those out here.
+ if (contentDisposition.startsWith(";"))
+ return false;
+
+ if (contentDisposition.startsWith("inline", false))
+ return false;
+
+ // Some broken sites just send
+ // Content-Disposition: filename="file"
+ // without a disposition token... screen those out.
+ if (contentDisposition.startsWith("filename", false))
+ return false;
+
+ // Also in use is Content-Disposition: name="file"
+ if (contentDisposition.startsWith("name", false))
+ return false;
+
+ // We have a content-disposition of "attachment" or unknown.
+ // RFC 2183, section 2.8 says that an unknown disposition
+ // value should be treated as "attachment"
+ return true;
+}
+
+void FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType(
+ FramePolicyFunction function,
+ const String& mimeType,
+ const ResourceRequest&)
+{
+ const ResourceResponse& response =
+ m_webFrame->frame()->loader()->activeDocumentLoader()->response();
+
+ PolicyAction action;
+
+ int statusCode = response.httpStatusCode();
+ if (statusCode == 204 || statusCode == 205) {
+ // The server does not want us to replace the page contents.
+ action = PolicyIgnore;
+ } else if (shouldTreatAsAttachment(response)) {
+ // The server wants us to download instead of replacing the page contents.
+ // Downloading is handled by the embedder, but we still get the initial
+ // response so that we can ignore it and clean up properly.
+ action = PolicyIgnore;
+ } else if (!canShowMIMEType(mimeType)) {
+ // Make sure that we can actually handle this type internally.
+ action = PolicyIgnore;
+ } else {
+ // OK, we will render this page.
+ action = PolicyUse;
+ }
+
+ // NOTE: PolicyChangeError will be generated when action is not PolicyUse.
+ (m_webFrame->frame()->loader()->policyChecker()->*function)(action);
+}
+
+void FrameLoaderClientImpl::dispatchDecidePolicyForNewWindowAction(
+ FramePolicyFunction function,
+ const NavigationAction& action,
+ const ResourceRequest& request,
+ PassRefPtr<FormState> formState,
+ const String& frameName)
+{
+ WebNavigationPolicy navigationPolicy;
+ if (!actionSpecifiesNavigationPolicy(action, &navigationPolicy))
+ navigationPolicy = WebNavigationPolicyNewForegroundTab;
+
+ PolicyAction policyAction;
+ if (navigationPolicy == WebNavigationPolicyDownload)
+ policyAction = PolicyDownload;
+ else {
+ policyAction = PolicyUse;
+
+ // Remember the disposition for when dispatchCreatePage is called. It is
+ // unfortunate that WebCore does not provide us with any context when
+ // creating or showing the new window that would allow us to avoid having
+ // to keep this state.
+ m_nextNavigationPolicy = navigationPolicy;
+ }
+ (m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction);
+}
+
+void FrameLoaderClientImpl::dispatchDecidePolicyForNavigationAction(
+ FramePolicyFunction function,
+ const NavigationAction& action,
+ const ResourceRequest& request,
+ PassRefPtr<FormState> formState) {
+ PolicyAction policyAction = PolicyIgnore;
+
+ // It is valid for this function to be invoked in code paths where the
+ // the webview is closed.
+ // The null check here is to fix a crash that seems strange
+ // (see - https://bugs.webkit.org/show_bug.cgi?id=23554).
+ if (m_webFrame->client() && !request.url().isNull()) {
+ WebNavigationPolicy navigationPolicy = WebNavigationPolicyCurrentTab;
+ actionSpecifiesNavigationPolicy(action, &navigationPolicy);
+
+ // Give the delegate a chance to change the navigation policy.
+ const WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl();
+ if (ds) {
+ KURL url = ds->request().url();
+ if (url.protocolIs(backForwardNavigationScheme)) {
+ handleBackForwardNavigation(url);
+ navigationPolicy = WebNavigationPolicyIgnore;
+ } else {
+ bool isRedirect = ds->hasRedirectChain();
+
+ WebNavigationType webnavType =
+ WebDataSourceImpl::toWebNavigationType(action.type());
+
+ RefPtr<Node> node;
+ for (const Event* event = action.event(); event; event = event->underlyingEvent()) {
+ if (event->isMouseEvent()) {
+ const MouseEvent* mouseEvent =
+ static_cast<const MouseEvent*>(event);
+ node = m_webFrame->frame()->eventHandler()->hitTestResultAtPoint(
+ mouseEvent->absoluteLocation(), false).innerNonSharedNode();
+ break;
+ }
+ }
+ WebNode originatingNode(node);
+
+ navigationPolicy = m_webFrame->client()->decidePolicyForNavigation(
+ m_webFrame, ds->request(), webnavType, originatingNode,
+ navigationPolicy, isRedirect);
+ }
+ }
+
+ if (navigationPolicy == WebNavigationPolicyCurrentTab)
+ policyAction = PolicyUse;
+ else if (navigationPolicy == WebNavigationPolicyDownload)
+ policyAction = PolicyDownload;
+ else {
+ if (navigationPolicy != WebNavigationPolicyIgnore) {
+ WrappedResourceRequest webreq(request);
+ m_webFrame->client()->loadURLExternally(m_webFrame, webreq, navigationPolicy);
+ }
+ policyAction = PolicyIgnore;
+ }
+ }
+
+ (m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction);
+}
+
+void FrameLoaderClientImpl::cancelPolicyCheck()
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::dispatchUnableToImplementPolicy(const ResourceError& error)
+{
+ m_webFrame->client()->unableToImplementPolicyWithError(m_webFrame, error);
+}
+
+void FrameLoaderClientImpl::dispatchWillSubmitForm(FramePolicyFunction function,
+ PassRefPtr<FormState> formState)
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->willSubmitForm(m_webFrame, WebForm(formState->form()));
+ (m_webFrame->frame()->loader()->policyChecker()->*function)(PolicyUse);
+}
+
+void FrameLoaderClientImpl::dispatchDidLoadMainResource(DocumentLoader*)
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::revertToProvisionalState(DocumentLoader*)
+{
+ m_hasRepresentation = true;
+}
+
+void FrameLoaderClientImpl::setMainDocumentError(DocumentLoader*,
+ const ResourceError& error)
+{
+ if (m_pluginWidget.get()) {
+ if (m_sentInitialResponseToPlugin) {
+ m_pluginWidget->didFailLoading(error);
+ m_sentInitialResponseToPlugin = false;
+ }
+ m_pluginWidget = 0;
+ }
+}
+
+void FrameLoaderClientImpl::postProgressStartedNotification()
+{
+ WebViewImpl* webview = m_webFrame->viewImpl();
+ if (webview && webview->client())
+ webview->client()->didStartLoading();
+}
+
+void FrameLoaderClientImpl::postProgressEstimateChangedNotification()
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::postProgressFinishedNotification()
+{
+ // FIXME: why might the webview be null? http://b/1234461
+ WebViewImpl* webview = m_webFrame->viewImpl();
+ if (webview && webview->client())
+ webview->client()->didStopLoading();
+}
+
+void FrameLoaderClientImpl::setMainFrameDocumentReady(bool ready)
+{
+ // FIXME
+}
+
+// Creates a new connection and begins downloading from that (contrast this
+// with |download|).
+void FrameLoaderClientImpl::startDownload(const ResourceRequest& request)
+{
+ if (m_webFrame->client()) {
+ WrappedResourceRequest webreq(request);
+ m_webFrame->client()->loadURLExternally(
+ m_webFrame, webreq, WebNavigationPolicyDownload);
+ }
+}
+
+void FrameLoaderClientImpl::willChangeTitle(DocumentLoader*)
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::didChangeTitle(DocumentLoader*)
+{
+ // FIXME
+}
+
+// Called whenever data is received.
+void FrameLoaderClientImpl::committedLoad(DocumentLoader* loader, const char* data, int length) {
+ if (!m_pluginWidget.get()) {
+ if (m_webFrame->client()) {
+ bool preventDefault = false;
+ m_webFrame->client()->didReceiveDocumentData(m_webFrame, data, length, preventDefault);
+ if (!preventDefault)
+ m_webFrame->commitDocumentData(data, length);
+ }
+ }
+
+ // If we are sending data to MediaDocument, we should stop here
+ // and cancel the request.
+ if (m_webFrame->frame()->document()
+ && m_webFrame->frame()->document()->isMediaDocument())
+ loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
+
+ // The plugin widget could have been created in the m_webFrame->DidReceiveData
+ // function.
+ if (m_pluginWidget.get()) {
+ if (!m_sentInitialResponseToPlugin) {
+ m_sentInitialResponseToPlugin = true;
+ m_pluginWidget->didReceiveResponse(
+ m_webFrame->frame()->loader()->activeDocumentLoader()->response());
+ }
+ m_pluginWidget->didReceiveData(data, length);
+ }
+}
+
+void FrameLoaderClientImpl::finishedLoading(DocumentLoader* dl)
+{
+ if (m_pluginWidget.get()) {
+ m_pluginWidget->didFinishLoading();
+ m_pluginWidget = 0;
+ m_sentInitialResponseToPlugin = false;
+ } else {
+ // This is necessary to create an empty document. See bug 634004.
+ // However, we only want to do this if makeRepresentation has been called, to
+ // match the behavior on the Mac.
+ if (m_hasRepresentation)
+ dl->frameLoader()->setEncoding("", false);
+ }
+}
+
+void FrameLoaderClientImpl::updateGlobalHistory()
+{
+}
+
+void FrameLoaderClientImpl::updateGlobalHistoryRedirectLinks()
+{
+}
+
+bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem*) const
+{
+ // FIXME
+ return true;
+}
+
+void FrameLoaderClientImpl::didDisplayInsecureContent()
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didDisplayInsecureContent(m_webFrame);
+}
+
+void FrameLoaderClientImpl::didRunInsecureContent(SecurityOrigin* origin)
+{
+ if (m_webFrame->client())
+ m_webFrame->client()->didRunInsecureContent(m_webFrame, WebSecurityOrigin(origin));
+}
+
+ResourceError FrameLoaderClientImpl::blockedError(const ResourceRequest&)
+{
+ // FIXME
+ return ResourceError();
+}
+
+ResourceError FrameLoaderClientImpl::cancelledError(const ResourceRequest& request)
+{
+ if (!m_webFrame->client())
+ return ResourceError();
+
+ return m_webFrame->client()->cancelledError(
+ m_webFrame, WrappedResourceRequest(request));
+}
+
+ResourceError FrameLoaderClientImpl::cannotShowURLError(const ResourceRequest& request)
+{
+ if (!m_webFrame->client())
+ return ResourceError();
+
+ return m_webFrame->client()->cannotHandleRequestError(
+ m_webFrame, WrappedResourceRequest(request));
+}
+
+ResourceError FrameLoaderClientImpl::interruptForPolicyChangeError(
+ const ResourceRequest& request)
+{
+ return ResourceError(internalErrorDomain, PolicyChangeError,
+ request.url().string(), String());
+}
+
+ResourceError FrameLoaderClientImpl::cannotShowMIMETypeError(const ResourceResponse&)
+{
+ // FIXME
+ return ResourceError();
+}
+
+ResourceError FrameLoaderClientImpl::fileDoesNotExistError(const ResourceResponse&)
+{
+ // FIXME
+ return ResourceError();
+}
+
+ResourceError FrameLoaderClientImpl::pluginWillHandleLoadError(const ResourceResponse&)
+{
+ // FIXME
+ return ResourceError();
+}
+
+bool FrameLoaderClientImpl::shouldFallBack(const ResourceError& error)
+{
+ // This method is called when we fail to load the URL for an <object> tag
+ // that has fallback content (child elements) and is being loaded as a frame.
+ // The error parameter indicates the reason for the load failure.
+ // We should let the fallback content load only if this wasn't a cancelled
+ // request.
+ // Note: The mac version also has a case for "WebKitErrorPluginWillHandleLoad"
+ ResourceError c = cancelledError(ResourceRequest());
+ return error.errorCode() != c.errorCode() || error.domain() != c.domain();
+}
+
+bool FrameLoaderClientImpl::canHandleRequest(const ResourceRequest& request) const
+{
+ return m_webFrame->client()->canHandleRequest(
+ m_webFrame, WrappedResourceRequest(request));
+}
+
+bool FrameLoaderClientImpl::canShowMIMEType(const String& mimeType) const
+{
+ // This method is called to determine if the media type can be shown
+ // "internally" (i.e. inside the browser) regardless of whether or not the
+ // browser or a plugin is doing the rendering.
+
+ // mimeType strings are supposed to be ASCII, but if they are not for some
+ // reason, then it just means that the mime type will fail all of these "is
+ // supported" checks and go down the path of an unhandled mime type.
+ if (net::IsSupportedMimeType(mimeType.latin1().data()))
+ return true;
+
+ // If Chrome is started with the --disable-plugins switch, pluginData is null.
+ PluginData* pluginData = m_webFrame->frame()->page()->pluginData();
+
+ // See if the type is handled by an installed plugin, if so, we can show it.
+ // FIXME: (http://b/1085524) This is the place to stick a preference to
+ // disable full page plugins (optionally for certain types!)
+ return !mimeType.isEmpty() && pluginData && pluginData->supportsMimeType(mimeType);
+}
+
+bool FrameLoaderClientImpl::representationExistsForURLScheme(const String&) const
+{
+ // FIXME
+ return false;
+}
+
+String FrameLoaderClientImpl::generatedMIMETypeForURLScheme(const String& scheme) const
+{
+ // This appears to generate MIME types for protocol handlers that are handled
+ // internally. The only place I can find in the WebKit code that uses this
+ // function is WebView::registerViewClass, where it is used as part of the
+ // process by which custom view classes for certain document representations
+ // are registered.
+ String mimeType("x-apple-web-kit/");
+ mimeType.append(scheme.lower());
+ return mimeType;
+}
+
+void FrameLoaderClientImpl::frameLoadCompleted()
+{
+ // FIXME: the mac port also conditionally calls setDrawsBackground:YES on
+ // it's ScrollView here.
+
+ // This comment from the Mac port:
+ // Note: Can be called multiple times.
+ // Even if already complete, we might have set a previous item on a frame that
+ // didn't do any data loading on the past transaction. Make sure to clear these out.
+
+ // FIXME: setPreviousHistoryItem() no longer exists. http://crbug.com/8566
+ // m_webFrame->frame()->loader()->setPreviousHistoryItem(0);
+}
+
+void FrameLoaderClientImpl::saveViewStateToItem(HistoryItem*)
+{
+ // FIXME
+}
+
+void FrameLoaderClientImpl::restoreViewState()
+{
+ // FIXME: probably scrolls to last position when you go back or forward
+}
+
+void FrameLoaderClientImpl::provisionalLoadStarted()
+{
+ // FIXME: On mac, this does various caching stuff
+}
+
+void FrameLoaderClientImpl::didFinishLoad()
+{
+ OwnPtr<WebPluginLoadObserver> observer = pluginLoadObserver();
+ if (observer)
+ observer->didFinishLoading();
+}
+
+void FrameLoaderClientImpl::prepareForDataSourceReplacement()
+{
+ // FIXME
+}
+
+PassRefPtr<DocumentLoader> FrameLoaderClientImpl::createDocumentLoader(
+ const ResourceRequest& request,
+ const SubstituteData& data)
+{
+ RefPtr<WebDataSourceImpl> ds = WebDataSourceImpl::create(request, data);
+ if (m_webFrame->client())
+ m_webFrame->client()->didCreateDataSource(m_webFrame, ds.get());
+ return ds.release();
+}
+
+void FrameLoaderClientImpl::setTitle(const String& title, const KURL& url)
+{
+ // FIXME: inform consumer of changes to the title.
+}
+
+String FrameLoaderClientImpl::userAgent(const KURL& url)
+{
+ // FIXME: Convert this to a WebKitClient callback.
+ return webkit_glue::StdStringToString(
+ webkit_glue::GetUserAgent(webkit_glue::KURLToGURL(url)));
+}
+
+void FrameLoaderClientImpl::savePlatformDataToCachedFrame(CachedFrame*)
+{
+ // The page cache should be disabled.
+ ASSERT_NOT_REACHED();
+}
+
+void FrameLoaderClientImpl::transitionToCommittedFromCachedFrame(CachedFrame*)
+{
+ ASSERT_NOT_REACHED();
+}
+
+// Called when the FrameLoader goes into a state in which a new page load
+// will occur.
+void FrameLoaderClientImpl::transitionToCommittedForNewPage()
+{
+ makeDocumentView();
+}
+
+bool FrameLoaderClientImpl::canCachePage() const
+{
+ // Since we manage the cache, always report this page as non-cacheable to
+ // FrameLoader.
+ return false;
+}
+
+// Downloading is handled in the browser process, not WebKit. If we get to this
+// point, our download detection code in the ResourceDispatcherHost is broken!
+void FrameLoaderClientImpl::download(ResourceHandle* handle,
+ const ResourceRequest& request,
+ const ResourceRequest& initialRequest,
+ const ResourceResponse& response)
+{
+ ASSERT_NOT_REACHED();
+}
+
+PassRefPtr<Frame> FrameLoaderClientImpl::createFrame(
+ const KURL& url,
+ const String& name,
+ HTMLFrameOwnerElement* ownerElement,
+ const String& referrer,
+ bool allowsScrolling,
+ int marginWidth,
+ int marginHeight)
+{
+ FrameLoadRequest frameRequest(ResourceRequest(url, referrer), name);
+ return m_webFrame->createChildFrame(frameRequest, ownerElement);
+}
+
+PassRefPtr<Widget> FrameLoaderClientImpl::createPlugin(
+ const IntSize& size, // FIXME: how do we use this?
+ HTMLPlugInElement* element,
+ const KURL& url,
+ const Vector<String>& paramNames,
+ const Vector<String>& paramValues,
+ const String& mimeType,
+ bool loadManually)
+{
+#if !PLATFORM(WIN_OS)
+ // WebCore asks us to make a plugin even if we don't have a
+ // registered handler, with a comment saying it's so we can display
+ // the broken plugin icon. In Chromium, we normally register a
+ // fallback plugin handler that allows you to install a missing
+ // plugin. Since we don't yet have a default plugin handler, we
+ // need to return null here rather than going through all the
+ // plugin-creation IPCs only to discover we don't have a plugin
+ // registered, which causes a crash.
+ // FIXME: remove me once we have a default plugin.
+ if (objectContentType(url, mimeType) != ObjectContentNetscapePlugin)
+ return 0;
+#endif
+
+ if (!m_webFrame->client())
+ return 0;
+
+ WebPluginParams params;
+ params.url = url;
+ params.mimeType = mimeType;
+ params.attributeNames = paramNames;
+ params.attributeValues = paramValues;
+ params.loadManually = loadManually;
+
+ WebPlugin* webPlugin = m_webFrame->client()->createPlugin(m_webFrame, params);
+ if (!webPlugin)
+ return 0;
+
+ // The container takes ownership of the WebPlugin.
+ RefPtr<WebPluginContainerImpl> container =
+ WebPluginContainerImpl::create(element, webPlugin);
+
+ if (!webPlugin->initialize(container.get()))
+ return 0;
+
+ // The element might have been removed during plugin initialization!
+ if (!element->renderer())
+ return 0;
+
+ return container;
+}
+
+// This method gets called when a plugin is put in place of html content
+// (e.g., acrobat reader).
+void FrameLoaderClientImpl::redirectDataToPlugin(Widget* pluginWidget) {
+ m_pluginWidget = static_cast<WebPluginContainerImpl*>(pluginWidget);
+ ASSERT(m_pluginWidget.get());
+}
+
+PassRefPtr<Widget> FrameLoaderClientImpl::createJavaAppletWidget(
+ const IntSize& size,
+ HTMLAppletElement* element,
+ const KURL& /* baseURL */,
+ const Vector<String>& paramNames,
+ const Vector<String>& paramValues)
+{
+ return createPlugin(size, element, KURL(), paramNames, paramValues,
+ "application/x-java-applet", false);
+}
+
+ObjectContentType FrameLoaderClientImpl::objectContentType(
+ const KURL& url,
+ const String& explicitMimeType)
+{
+ // This code is based on Apple's implementation from
+ // WebCoreSupport/WebFrameBridge.mm.
+
+ String mimeType = explicitMimeType;
+ if (mimeType.isEmpty()) {
+ // Try to guess the MIME type based off the extension.
+ String filename = url.lastPathComponent();
+ int extensionPos = filename.reverseFind('.');
+ if (extensionPos >= 0)
+ mimeType = MIMETypeRegistry::getMIMETypeForPath(url.path());
+
+ if (mimeType.isEmpty())
+ return ObjectContentFrame;
+ }
+
+ if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
+ return ObjectContentImage;
+
+ // If Chrome is started with the --disable-plugins switch, pluginData is 0.
+ PluginData* pluginData = m_webFrame->frame()->page()->pluginData();
+ if (pluginData && pluginData->supportsMimeType(mimeType))
+ return ObjectContentNetscapePlugin;
+
+ if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
+ return ObjectContentFrame;
+
+ return ObjectContentNone;
+}
+
+String FrameLoaderClientImpl::overrideMediaType() const
+{
+ // FIXME
+ return String();
+}
+
+bool FrameLoaderClientImpl::actionSpecifiesNavigationPolicy(
+ const NavigationAction& action,
+ WebNavigationPolicy* policy)
+{
+ if ((action.type() != NavigationTypeLinkClicked) || !action.event()->isMouseEvent())
+ return false;
+
+ const MouseEvent* event = static_cast<const MouseEvent*>(action.event());
+ return WebViewImpl::navigationPolicyFromMouseEvent(
+ event->button(), event->ctrlKey(), event->shiftKey(), event->altKey(),
+ event->metaKey(), policy);
+}
+
+void FrameLoaderClientImpl::handleBackForwardNavigation(const KURL& url)
+{
+ ASSERT(url.protocolIs(backForwardNavigationScheme));
+
+ bool ok;
+ int offset = url.lastPathComponent().toIntStrict(&ok);
+ if (!ok)
+ return;
+
+ WebViewImpl* webview = m_webFrame->viewImpl();
+ if (webview->client())
+ webview->client()->navigateBackForwardSoon(offset);
+}
+
+PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver()
+{
+ WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader(
+ m_webFrame->frame()->loader()->activeDocumentLoader());
+ return ds->releasePluginLoadObserver();
+}
+
+} // namespace WebKit
diff --git a/webkit/api/src/FrameLoaderClientImpl.h b/webkit/api/src/FrameLoaderClientImpl.h
new file mode 100644
index 0000000..a3e7f18
--- /dev/null
+++ b/webkit/api/src/FrameLoaderClientImpl.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FrameLoaderClientImpl_h
+#define FrameLoaderClientImpl_h
+
+#include "FrameLoaderClient.h"
+#include "KURL.h"
+// FIXME: remove this relative path once consumers from glue are removed.
+#include "../public/WebNavigationPolicy.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebKit {
+class WebFrameImpl;
+class WebPluginContainerImpl;
+class WebPluginLoadObserver;
+
+class FrameLoaderClientImpl : public WebCore::FrameLoaderClient {
+public:
+ FrameLoaderClientImpl(WebFrameImpl* webFrame);
+ ~FrameLoaderClientImpl();
+
+ WebFrameImpl* webFrame() const { return m_webFrame; }
+
+ // WebCore::FrameLoaderClient ----------------------------------------------
+
+ virtual void frameLoaderDestroyed();
+
+ // Notifies the WebView delegate that the JS window object has been cleared,
+ // giving it a chance to bind native objects to the window before script
+ // parsing begins.
+ virtual void windowObjectCleared();
+ virtual void documentElementAvailable();
+
+ // A frame's V8 context was created or destroyed.
+ virtual void didCreateScriptContextForFrame();
+ virtual void didDestroyScriptContextForFrame();
+
+ // A context untied to a frame was created (through evaluateInNewContext).
+ // This context is not tied to the lifetime of its frame, and is destroyed
+ // in garbage collection.
+ virtual void didCreateIsolatedScriptContext();
+
+ virtual bool hasWebView() const;
+ virtual bool hasFrameView() const;
+ virtual void makeRepresentation(WebCore::DocumentLoader*);
+ virtual void forceLayout();
+ virtual void forceLayoutForNonHTML();
+ virtual void setCopiesOnScroll();
+ virtual void detachedFromParent2();
+ virtual void detachedFromParent3();
+ virtual void assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest&);
+ virtual void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse);
+ virtual bool shouldUseCredentialStorage(WebCore::DocumentLoader*, unsigned long identifier);
+ virtual void dispatchDidReceiveAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&);
+ virtual void dispatchDidCancelAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&);
+ virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&);
+ virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int lengthReceived);
+ virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier);
+ virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&);
+ virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int length);
+ virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const WebCore::ScriptString&);
+ virtual void dispatchDidHandleOnloadEvents();
+ virtual void dispatchDidReceiveServerRedirectForProvisionalLoad();
+ virtual void dispatchDidCancelClientRedirect();
+ virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate);
+ virtual void dispatchDidChangeLocationWithinPage();
+ virtual void dispatchWillClose();
+ virtual void dispatchDidReceiveIcon();
+ virtual void dispatchDidStartProvisionalLoad();
+ virtual void dispatchDidReceiveTitle(const WebCore::String& title);
+ virtual void dispatchDidCommitLoad();
+ virtual void dispatchDidFailProvisionalLoad(const WebCore::ResourceError&);
+ virtual void dispatchDidFailLoad(const WebCore::ResourceError&);
+ virtual void dispatchDidFinishDocumentLoad();
+ virtual void dispatchDidFinishLoad();
+ virtual void dispatchDidFirstLayout();
+ virtual void dispatchDidFirstVisuallyNonEmptyLayout();
+ virtual WebCore::Frame* dispatchCreatePage();
+ virtual void dispatchShow();
+ virtual void dispatchDecidePolicyForMIMEType(WebCore::FramePolicyFunction function, const WebCore::String& mime_type, const WebCore::ResourceRequest&);
+ virtual void dispatchDecidePolicyForNewWindowAction(WebCore::FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState> form_state, const WebCore::String& frame_name);
+ virtual void dispatchDecidePolicyForNavigationAction(WebCore::FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState> form_state);
+ virtual void cancelPolicyCheck();
+ virtual void dispatchUnableToImplementPolicy(const WebCore::ResourceError&);
+ virtual void dispatchWillSubmitForm(WebCore::FramePolicyFunction, PassRefPtr<WebCore::FormState>);
+ virtual void dispatchDidLoadMainResource(WebCore::DocumentLoader*);
+ virtual void revertToProvisionalState(WebCore::DocumentLoader*);
+ virtual void setMainDocumentError(WebCore::DocumentLoader*, const WebCore::ResourceError&);
+ virtual void willChangeEstimatedProgress() { }
+ virtual void didChangeEstimatedProgress() { }
+ virtual void postProgressStartedNotification();
+ virtual void postProgressEstimateChangedNotification();
+ virtual void postProgressFinishedNotification();
+ virtual void setMainFrameDocumentReady(bool);
+ virtual void startDownload(const WebCore::ResourceRequest&);
+ virtual void willChangeTitle(WebCore::DocumentLoader*);
+ virtual void didChangeTitle(WebCore::DocumentLoader*);
+ virtual void committedLoad(WebCore::DocumentLoader*, const char*, int);
+ virtual void finishedLoading(WebCore::DocumentLoader*);
+ virtual void updateGlobalHistory();
+ virtual void updateGlobalHistoryRedirectLinks();
+ virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const;
+ virtual void didDisplayInsecureContent();
+ virtual void didRunInsecureContent(WebCore::SecurityOrigin*);
+ virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&);
+ virtual WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&);
+ virtual WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&);
+ virtual WebCore::ResourceError interruptForPolicyChangeError(const WebCore::ResourceRequest&);
+ virtual WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&);
+ virtual WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&);
+ virtual WebCore::ResourceError pluginWillHandleLoadError(const WebCore::ResourceResponse&);
+ virtual bool shouldFallBack(const WebCore::ResourceError&);
+ virtual bool canHandleRequest(const WebCore::ResourceRequest&) const;
+ virtual bool canShowMIMEType(const WebCore::String& MIMEType) const;
+ virtual bool representationExistsForURLScheme(const WebCore::String& URLScheme) const;
+ virtual WebCore::String generatedMIMETypeForURLScheme(const WebCore::String& URLScheme) const;
+ virtual void frameLoadCompleted();
+ virtual void saveViewStateToItem(WebCore::HistoryItem*);
+ virtual void restoreViewState();
+ virtual void provisionalLoadStarted();
+ virtual void didFinishLoad();
+ virtual void prepareForDataSourceReplacement();
+ virtual PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(
+ const WebCore::ResourceRequest&, const WebCore::SubstituteData&);
+ virtual void setTitle(const WebCore::String& title, const WebCore::KURL&);
+ virtual WebCore::String userAgent(const WebCore::KURL&);
+ virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*);
+ virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*);
+ virtual void transitionToCommittedForNewPage();
+ virtual bool canCachePage() const;
+ virtual void download(
+ WebCore::ResourceHandle*, const WebCore::ResourceRequest&,
+ const WebCore::ResourceRequest& initialRequest,
+ const WebCore::ResourceResponse&);
+ virtual PassRefPtr<WebCore::Frame> createFrame(
+ const WebCore::KURL& url, const WebCore::String& name,
+ WebCore::HTMLFrameOwnerElement* ownerElement,
+ const WebCore::String& referrer, bool allowsScrolling,
+ int marginWidth, int marginHeight);
+ virtual PassRefPtr<WebCore::Widget> createPlugin(
+ const WebCore::IntSize&, WebCore::HTMLPlugInElement*, const WebCore::KURL&,
+ const Vector<WebCore::String>&, const Vector<WebCore::String>&,
+ const WebCore::String&, bool loadManually);
+ virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget);
+ virtual PassRefPtr<WebCore::Widget> createJavaAppletWidget(
+ const WebCore::IntSize&,
+ WebCore::HTMLAppletElement*,
+ const WebCore::KURL& /* base_url */,
+ const Vector<WebCore::String>& paramNames,
+ const Vector<WebCore::String>& paramValues);
+ virtual WebCore::ObjectContentType objectContentType(
+ const WebCore::KURL& url, const WebCore::String& mimeType);
+ virtual WebCore::String overrideMediaType() const;
+ virtual void didPerformFirstNavigation() const;
+ virtual void registerForIconNotification(bool listen = true);
+
+private:
+ void makeDocumentView();
+
+ // Given a NavigationAction, determine the associated WebNavigationPolicy.
+ // For example, a middle click means "open in background tab".
+ static bool actionSpecifiesNavigationPolicy(
+ const WebCore::NavigationAction& action, WebNavigationPolicy* policy);
+
+ // Called when a dummy back-forward navigation is intercepted.
+ void handleBackForwardNavigation(const WebCore::KURL&);
+
+ PassOwnPtr<WebPluginLoadObserver> pluginLoadObserver();
+
+ // The WebFrame that owns this object and manages its lifetime. Therefore,
+ // the web frame object is guaranteed to exist.
+ WebFrameImpl* m_webFrame;
+
+ // True if makeRepresentation was called. We don't actually have a concept
+ // of a "representation", but we need to know when we're expected to have one.
+ // See finishedLoading().
+ bool m_hasRepresentation;
+
+ // Used to help track client redirects. When a provisional load starts, it
+ // has no redirects in its chain. But in the case of client redirects, we want
+ // to add that initial load as a redirect. When we get a new provisional load
+ // and the dest URL matches that load, we know that it was the result of a
+ // previous client redirect and the source should be added as a redirect.
+ // Both should be empty if unused.
+ WebCore::KURL m_expectedClientRedirectSrc;
+ WebCore::KURL m_expectedClientRedirectDest;
+
+ // Contains a pointer to the plugin widget.
+ RefPtr<WebPluginContainerImpl> m_pluginWidget;
+
+ // Indicates if we need to send over the initial notification to the plugin
+ // which specifies that the plugin should be ready to accept data.
+ bool m_sentInitialResponseToPlugin;
+
+ // The navigation policy to use for the next call to dispatchCreatePage.
+ WebNavigationPolicy m_nextNavigationPolicy;
+};
+
+} // namespace WebKit
+
+#endif
diff --git a/webkit/api/src/InspectorClientImpl.cpp b/webkit/api/src/InspectorClientImpl.cpp
index 2dd3b7c..9a1cd3f 100644
--- a/webkit/api/src/InspectorClientImpl.cpp
+++ b/webkit/api/src/InspectorClientImpl.cpp
@@ -40,11 +40,11 @@
#include "WebURL.h"
#include "WebURLRequest.h"
#include "WebViewClient.h"
+#include "WebViewImpl.h"
#include <wtf/Vector.h>
// FIXME: Remove this once WebDevToolsAgentImpl and WebViewImpl move out of glue/.
#include "webkit/glue/webdevtoolsagent_impl.h"
-#include "webkit/glue/webview_impl.h"
using namespace WebCore;
@@ -75,7 +75,7 @@ Page* InspectorClientImpl::createPage()
void InspectorClientImpl::showWindow()
{
- ASSERT(m_inspectedWebView->GetWebDevToolsAgentImpl());
+ ASSERT(m_inspectedWebView->devToolsAgentImpl());
m_inspectedWebView->page()->inspectorController()->setWindowVisible(true);
}
@@ -87,7 +87,7 @@ void InspectorClientImpl::closeWindow()
bool InspectorClientImpl::windowVisible()
{
- ASSERT(m_inspectedWebView->GetWebDevToolsAgentImpl());
+ ASSERT(m_inspectedWebView->devToolsAgentImpl());
return false;
}
diff --git a/webkit/api/src/InspectorClientImpl.h b/webkit/api/src/InspectorClientImpl.h
index aaeff93..62216b2 100644
--- a/webkit/api/src/InspectorClientImpl.h
+++ b/webkit/api/src/InspectorClientImpl.h
@@ -35,9 +35,8 @@
#include "InspectorController.h"
#include <wtf/OwnPtr.h>
-class WebViewImpl;
-
namespace WebKit {
+class WebViewImpl;
class InspectorClientImpl : public WebCore::InspectorClient {
public:
diff --git a/webkit/api/src/WebFrameImpl.cpp b/webkit/api/src/WebFrameImpl.cpp
new file mode 100644
index 0000000..617cfd5
--- /dev/null
+++ b/webkit/api/src/WebFrameImpl.cpp
@@ -0,0 +1,1890 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// How ownership works
+// -------------------
+//
+// Big oh represents a refcounted relationship: owner O--- ownee
+//
+// WebView (for the toplevel frame only)
+// O
+// |
+// Page O------- Frame (m_mainFrame) O-------O FrameView
+// ||
+// ||
+// FrameLoader O-------- WebFrame (via FrameLoaderClient)
+//
+// FrameLoader and Frame are formerly one object that was split apart because
+// it got too big. They basically have the same lifetime, hence the double line.
+//
+// WebFrame is refcounted and has one ref on behalf of the FrameLoader/Frame.
+// This is not a normal reference counted pointer because that would require
+// changing WebKit code that we don't control. Instead, it is created with this
+// 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
+// are created. WebKit will hook up this object to the FrameLoader/Frame
+// and the refcount will be correct.
+//
+// How frames are destroyed
+// ------------------------
+//
+// The main frame is never destroyed and is re-used. The FrameLoader is re-used
+// and a reference to the main frame is kept by the Page.
+//
+// When frame content is replaced, all subframes are destroyed. This happens
+// 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).
+
+#include "config.h"
+#include "WebFrameImpl.h"
+
+#include <algorithm>
+
+#include "Chrome.h"
+#include "ChromiumBridge.h"
+#include "ClipboardUtilitiesChromium.h"
+#include "Console.h"
+#include "Document.h"
+#include "DocumentFragment.h" // Only needed for ReplaceSelectionCommand.h :(
+#include "DocumentLoader.h"
+#include "DocumentMarker.h"
+#include "DOMWindow.h"
+#include "DOMUtilitiesPrivate.h"
+#include "Editor.h"
+#include "EventHandler.h"
+#include "FormState.h"
+#include "FrameChromium.h"
+#include "FrameLoader.h"
+#include "FrameLoadRequest.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "HTMLCollection.h"
+#include "HTMLHeadElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLFormElement.h"
+#include "HTMLFrameOwnerElement.h"
+#include "HTMLLinkElement.h"
+#include "HTMLNames.h"
+#include "HistoryItem.h"
+#include "InspectorController.h"
+#include "markup.h"
+#include "Page.h"
+#include "PasswordAutocompleteListener.h"
+#include "PlatformContextSkia.h"
+#include "PrintContext.h"
+#include "RenderFrame.h"
+#include "RenderView.h"
+#include "RenderWidget.h"
+#include "ReplaceSelectionCommand.h"
+#include "ResourceHandle.h"
+#include "ResourceRequest.h"
+#include "ScriptController.h"
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
+#include "ScrollbarTheme.h"
+#include "ScrollTypes.h"
+#include "SelectionController.h"
+#include "Settings.h"
+#include "SkiaUtils.h"
+#include "SubstituteData.h"
+#include "TextIterator.h"
+#include "TextAffinity.h"
+#include "XPathResult.h"
+#include "WebConsoleMessage.h"
+#include "WebDataSourceImpl.h"
+#include "WebFindOptions.h"
+#include "WebForm.h"
+#include "WebFrameClient.h"
+#include "WebHistoryItem.h"
+#include "WebRange.h"
+#include "WebRect.h"
+#include "WebScriptSource.h"
+#include "WebSecurityOrigin.h"
+#include "WebSize.h"
+#include "WebURLError.h"
+#include "WebVector.h"
+#include "WebViewImpl.h"
+#include <wtf/CurrentTime.h>
+
+#if PLATFORM(DARWIN)
+#include "LocalCurrentGraphicsContext.h"
+#endif
+
+#if PLATFORM(LINUX)
+#include <gdk/gdk.h>
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// Key for a StatsCounter tracking how many WebFrames are active.
+static const char* const webFrameActiveCount = "WebFrameActiveCount";
+
+static const char* const osdType = "application/opensearchdescription+xml";
+static const char* const osdRel = "search";
+
+// Backend for contentAsPlainText, this is a recursive function that gets
+// the text for the current frame and all of its subframes. It will append
+// the text of each frame in turn to the |output| up to |maxChars| length.
+//
+// The |frame| must be non-null.
+static void frameContentAsPlainText(size_t maxChars, Frame* frame,
+ Vector<UChar>* output)
+{
+ Document* doc = frame->document();
+ if (!doc)
+ return;
+
+ if (!frame->view())
+ return;
+
+ // TextIterator iterates over the visual representation of the DOM. As such,
+ // it requires you to do a layout before using it (otherwise it'll crash).
+ if (frame->view()->needsLayout())
+ frame->view()->layout();
+
+ // Select the document body.
+ RefPtr<Range> range(doc->createRange());
+ ExceptionCode exception = 0;
+ range->selectNodeContents(doc->body(), exception);
+
+ if (exception == 0) {
+ // The text iterator will walk nodes giving us text. This is similar to
+ // the plainText() function in TextIterator.h, but we implement the maximum
+ // size and also copy the results directly into a wstring, avoiding the
+ // string conversion.
+ for (TextIterator it(range.get()); !it.atEnd(); it.advance()) {
+ const UChar* chars = it.characters();
+ if (!chars) {
+ if (it.length() != 0) {
+ // It appears from crash reports that an iterator can get into a state
+ // where the character count is nonempty but the character pointer is
+ // null. advance()ing it will then just add that many to the null
+ // pointer which won't be caught in a null check but will crash.
+ //
+ // A null pointer and 0 length is common for some nodes.
+ //
+ // IF YOU CATCH THIS IN A DEBUGGER please let brettw know. We don't
+ // currently understand the conditions for this to occur. Ideally, the
+ // iterators would never get into the condition so we should fix them
+ // if we can.
+ ASSERT_NOT_REACHED();
+ break;
+ }
+
+ // Just got a null node, we can forge ahead!
+ continue;
+ }
+ size_t toAppend =
+ std::min(static_cast<size_t>(it.length()), maxChars - output->size());
+ output->append(chars, toAppend);
+ if (output->size() >= maxChars)
+ return; // Filled up the buffer.
+ }
+ }
+
+ // The separator between frames when the frames are converted to plain text.
+ const UChar frameSeparator[] = { '\n', '\n' };
+ const size_t frameSeparatorLen = 2;
+
+ // Recursively walk the children.
+ FrameTree* frameTree = frame->tree();
+ for (Frame* curChild = frameTree->firstChild(); curChild; curChild = curChild->tree()->nextSibling()) {
+ // Make sure the frame separator won't fill up the buffer, and give up if
+ // it will. The danger is if the separator will make the buffer longer than
+ // maxChars. This will cause the computation above:
+ // maxChars - output->size()
+ // to be a negative number which will crash when the subframe is added.
+ if (output->size() >= maxChars - frameSeparatorLen)
+ return;
+
+ output->append(frameSeparator, frameSeparatorLen);
+ frameContentAsPlainText(maxChars, curChild, output);
+ if (output->size() >= maxChars)
+ return; // Filled up the buffer.
+ }
+}
+
+// Simple class to override some of PrintContext behavior.
+class ChromePrintContext : public PrintContext, public Noncopyable {
+public:
+ ChromePrintContext(Frame* frame)
+ : PrintContext(frame)
+ , m_printedPageWidth(0)
+ {
+ }
+
+ void begin(float width)
+ {
+ ASSERT(!m_printedPageWidth);
+ m_printedPageWidth = width;
+ PrintContext::begin(m_printedPageWidth);
+ }
+
+ float getPageShrink(int pageNumber) const
+ {
+ IntRect pageRect = m_pageRects[pageNumber];
+ return m_printedPageWidth / pageRect.width();
+ }
+
+ // Spools the printed page, a subrect of m_frame. Skip the scale step.
+ // NativeTheme doesn't play well with scaling. Scaling is done browser side
+ // instead. Returns the scale to be applied.
+ float spoolPage(GraphicsContext& ctx, int pageNumber)
+ {
+ IntRect pageRect = m_pageRects[pageNumber];
+ float scale = m_printedPageWidth / pageRect.width();
+
+ ctx.save();
+ ctx.translate(static_cast<float>(-pageRect.x()),
+ static_cast<float>(-pageRect.y()));
+ ctx.clip(pageRect);
+ m_frame->view()->paintContents(&ctx, pageRect);
+ ctx.restore();
+ return scale;
+ }
+
+private:
+ // Set when printing.
+ float m_printedPageWidth;
+};
+
+static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader)
+{
+ return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0;
+}
+
+
+// WebFrame -------------------------------------------------------------------
+
+class WebFrameImpl::DeferredScopeStringMatches {
+public:
+ DeferredScopeStringMatches(WebFrameImpl* webFrame,
+ int identifier,
+ const WebString& searchText,
+ const WebFindOptions& options,
+ bool reset)
+ : m_timer(this, &DeferredScopeStringMatches::doTimeout)
+ , m_webFrame(webFrame)
+ , m_identifier(identifier)
+ , m_searchText(searchText)
+ , m_options(options)
+ , m_reset(reset)
+ {
+ m_timer.startOneShot(0.0);
+ }
+
+private:
+ void doTimeout(Timer<DeferredScopeStringMatches>*)
+ {
+ m_webFrame->callScopeStringMatches(
+ this, m_identifier, m_searchText, m_options, m_reset);
+ }
+
+ Timer<DeferredScopeStringMatches> m_timer;
+ RefPtr<WebFrameImpl> m_webFrame;
+ int m_identifier;
+ WebString m_searchText;
+ WebFindOptions m_options;
+ bool m_reset;
+};
+
+
+// WebFrame -------------------------------------------------------------------
+
+WebFrame* WebFrame::frameForEnteredContext()
+{
+ Frame* frame =
+ ScriptController::retrieveFrameForEnteredContext();
+ return WebFrameImpl::fromFrame(frame);
+}
+
+WebFrame* WebFrame::frameForCurrentContext()
+{
+ Frame* frame =
+ ScriptController::retrieveFrameForCurrentContext();
+ return WebFrameImpl::fromFrame(frame);
+}
+
+WebString WebFrameImpl::name() const
+{
+ return m_frame->tree()->name();
+}
+
+WebURL WebFrameImpl::url() const
+{
+ const WebDataSource* ds = dataSource();
+ if (!ds)
+ return WebURL();
+ return ds->request().url();
+}
+
+WebURL WebFrameImpl::favIconURL() const
+{
+ FrameLoader* frameLoader = m_frame->loader();
+ // The URL to the favicon may be in the header. As such, only
+ // ask the loader for the favicon if it's finished loading.
+ if (frameLoader->state() == FrameStateComplete) {
+ const KURL& url = frameLoader->iconURL();
+ if (!url.isEmpty())
+ return url;
+ }
+ return WebURL();
+}
+
+WebURL WebFrameImpl::openSearchDescriptionURL() const
+{
+ FrameLoader* frameLoader = m_frame->loader();
+ if (frameLoader->state() == FrameStateComplete
+ && m_frame->document() && m_frame->document()->head()
+ && !m_frame->tree()->parent()) {
+ HTMLHeadElement* head = m_frame->document()->head();
+ if (head) {
+ RefPtr<HTMLCollection> children = head->children();
+ for (Node* child = children->firstItem(); child != 0; child = children->nextItem()) {
+ HTMLLinkElement* linkElement = toHTMLLinkElement(child);
+ if (linkElement
+ && linkElement->type() == osdType
+ && linkElement->rel() == osdRel
+ && !linkElement->href().isEmpty())
+ return linkElement->href();
+ }
+ }
+ }
+ return WebURL();
+}
+
+WebSize WebFrameImpl::scrollOffset() const
+{
+ FrameView* view = frameView();
+ if (view)
+ return view->scrollOffset();
+
+ return WebSize();
+}
+
+WebSize WebFrameImpl::contentsSize() const
+{
+ return frame()->view()->contentsSize();
+}
+
+int WebFrameImpl::contentsPreferredWidth() const
+{
+ if ((m_frame->document() != 0) && (m_frame->document()->renderView() != 0))
+ return m_frame->document()->renderView()->minPrefWidth();
+
+ return 0;
+}
+
+bool WebFrameImpl::hasVisibleContent() const
+{
+ return frame()->view()->visibleWidth() > 0 && frame()->view()->visibleHeight() > 0;
+}
+
+WebView* WebFrameImpl::view() const
+{
+ return viewImpl();
+}
+
+WebFrame* WebFrameImpl::opener() const
+{
+ Frame* opener = 0;
+ if (m_frame)
+ opener = m_frame->loader()->opener();
+ return fromFrame(opener);
+}
+
+WebFrame* WebFrameImpl::parent() const
+{
+ Frame *parent = 0;
+ if (m_frame)
+ parent = m_frame->tree()->parent();
+ return fromFrame(parent);
+}
+
+WebFrame* WebFrameImpl::top() const
+{
+ if (m_frame)
+ return fromFrame(m_frame->tree()->top());
+
+ return 0;
+}
+
+WebFrame* WebFrameImpl::firstChild() const
+{
+ return fromFrame(frame()->tree()->firstChild());
+}
+
+WebFrame* WebFrameImpl::lastChild() const
+{
+ return fromFrame(frame()->tree()->lastChild());
+}
+
+WebFrame* WebFrameImpl::nextSibling() const
+{
+ return fromFrame(frame()->tree()->nextSibling());
+}
+
+WebFrame* WebFrameImpl::previousSibling() const
+{
+ return fromFrame(frame()->tree()->previousSibling());
+}
+
+WebFrame* WebFrameImpl::traverseNext(bool wrap) const
+{
+ return fromFrame(frame()->tree()->traverseNextWithWrap(wrap));
+}
+
+WebFrame* WebFrameImpl::traversePrevious(bool wrap) const
+{
+ return fromFrame(frame()->tree()->traversePreviousWithWrap(wrap));
+}
+
+WebFrame* WebFrameImpl::findChildByName(const WebString& name) const
+{
+ return fromFrame(frame()->tree()->child(name));
+}
+
+WebFrame* WebFrameImpl::findChildByExpression(const WebString& xpath) const
+{
+ if (xpath.isEmpty())
+ return 0;
+
+ Document* document = m_frame->document();
+
+ ExceptionCode ec = 0;
+ PassRefPtr<XPathResult> xpathResult =
+ document->evaluate(xpath,
+ document,
+ 0, // namespace
+ XPathResult::ORDERED_NODE_ITERATOR_TYPE,
+ 0, // XPathResult object
+ ec);
+ if (!xpathResult.get())
+ return 0;
+
+ Node* node = xpathResult->iterateNext(ec);
+
+ if (!node || !node->isFrameOwnerElement())
+ return 0;
+ HTMLFrameOwnerElement* frameElement =
+ static_cast<HTMLFrameOwnerElement*>(node);
+ return fromFrame(frameElement->contentFrame());
+}
+
+void WebFrameImpl::forms(WebVector<WebForm>& results) const
+{
+ if (!m_frame)
+ return;
+
+ RefPtr<HTMLCollection> forms = m_frame->document()->forms();
+ size_t formCount = forms->length();
+
+ WebVector<WebForm> temp(formCount);
+ for (size_t i = 0; i < formCount; ++i) {
+ Node* node = forms->item(i);
+ // Strange but true, sometimes item can be 0.
+ if (node)
+ temp[i] = static_cast<HTMLFormElement*>(node);
+ }
+ results.swap(temp);
+}
+
+WebSecurityOrigin WebFrameImpl::securityOrigin() const
+{
+ if (!m_frame || !m_frame->document())
+ return WebSecurityOrigin();
+
+ return WebSecurityOrigin(m_frame->document()->securityOrigin());
+}
+
+void WebFrameImpl::grantUniversalAccess()
+{
+ ASSERT(m_frame && m_frame->document());
+ if (m_frame && m_frame->document())
+ m_frame->document()->securityOrigin()->grantUniversalAccess();
+}
+
+NPObject* WebFrameImpl::windowObject() const
+{
+ if (!m_frame)
+ return 0;
+
+ return m_frame->script()->windowScriptNPObject();
+}
+
+void WebFrameImpl::bindToWindowObject(const WebString& name, NPObject* object)
+{
+ ASSERT(m_frame);
+ if (!m_frame || !m_frame->script()->isEnabled())
+ return;
+
+ String key = name;
+#if USE(V8)
+ m_frame->script()->bindToWindowObject(m_frame, key, object);
+#else
+ notImplemented();
+#endif
+}
+
+void WebFrameImpl::executeScript(const WebScriptSource& source)
+{
+ m_frame->script()->executeScript(
+ ScriptSourceCode(source.code, source.url, source.startLine));
+}
+
+void WebFrameImpl::executeScriptInNewContext(
+ const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup)
+{
+ Vector<ScriptSourceCode> sources;
+
+ for (unsigned i = 0; i < numSources; ++i) {
+ sources.append(ScriptSourceCode(
+ sourcesIn[i].code, sourcesIn[i].url, sourcesIn[i].startLine));
+ }
+
+ m_frame->script()->evaluateInNewContext(sources, extensionGroup);
+}
+
+void WebFrameImpl::executeScriptInIsolatedWorld(
+ int worldId, const WebScriptSource* sourcesIn, unsigned numSources,
+ int extensionGroup)
+{
+ Vector<ScriptSourceCode> sources;
+
+ for (unsigned i = 0; i < numSources; ++i) {
+ sources.append(ScriptSourceCode(
+ sourcesIn[i].code, sourcesIn[i].url, sourcesIn[i].startLine));
+ }
+
+ m_frame->script()->evaluateInIsolatedWorld(worldId, sources, extensionGroup);
+}
+
+void WebFrameImpl::addMessageToConsole(const WebConsoleMessage& message)
+{
+ ASSERT(frame());
+
+ MessageLevel webCoreMessageLevel;
+ switch (message.level) {
+ case WebConsoleMessage::LevelTip:
+ webCoreMessageLevel = TipMessageLevel;
+ break;
+ case WebConsoleMessage::LevelLog:
+ webCoreMessageLevel = LogMessageLevel;
+ break;
+ case WebConsoleMessage::LevelWarning:
+ webCoreMessageLevel = WarningMessageLevel;
+ break;
+ case WebConsoleMessage::LevelError:
+ webCoreMessageLevel = ErrorMessageLevel;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ frame()->domWindow()->console()->addMessage(
+ OtherMessageSource, LogMessageType, webCoreMessageLevel, message.text,
+ 1, String());
+}
+
+void WebFrameImpl::collectGarbage()
+{
+ if (!m_frame)
+ return;
+ if (!m_frame->settings()->isJavaScriptEnabled())
+ return;
+ // FIXME: Move this to the ScriptController and make it JS neutral.
+#if USE(V8)
+ m_frame->script()->collectGarbage();
+#else
+ notImplemented();
+#endif
+}
+
+#if USE(V8)
+// Returns the V8 context for this frame, or an empty handle if there is none.
+v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const
+{
+ if (!m_frame)
+ return v8::Local<v8::Context>();
+
+ return V8Proxy::mainWorldContext(m_frame);
+}
+#endif
+
+bool WebFrameImpl::insertStyleText(
+ const WebString& css, const WebString& id) {
+ Document* document = frame()->document();
+ if (!document)
+ return false;
+ Element* documentElement = document->documentElement();
+ if (!documentElement)
+ return false;
+
+ ExceptionCode err = 0;
+
+ if (!id.isEmpty()) {
+ Element* oldElement = document->getElementById(id);
+ if (oldElement) {
+ Node* parent = oldElement->parent();
+ if (!parent)
+ return false;
+ parent->removeChild(oldElement, err);
+ }
+ }
+
+ RefPtr<Element> stylesheet = document->createElement(
+ HTMLNames::styleTag, false);
+ if (!id.isEmpty())
+ stylesheet->setAttribute(HTMLNames::idAttr, id);
+ stylesheet->setTextContent(css, err);
+ ASSERT(!err);
+ Node* first = documentElement->firstChild();
+ bool success = documentElement->insertBefore(stylesheet, first, err);
+ ASSERT(success);
+ return success;
+}
+
+void WebFrameImpl::reload()
+{
+ m_frame->loader()->history()->saveDocumentAndScrollState();
+
+ stopLoading(); // Make sure existing activity stops.
+ m_frame->loader()->reload();
+}
+
+void WebFrameImpl::loadRequest(const WebURLRequest& request)
+{
+ ASSERT(!request.isNull());
+ const ResourceRequest& resourceRequest = request.toResourceRequest();
+
+ if (resourceRequest.url().protocolIs("javascript")) {
+ loadJavaScriptURL(resourceRequest.url());
+ return;
+ }
+
+ stopLoading(); // Make sure existing activity stops.
+ m_frame->loader()->load(resourceRequest, false);
+}
+
+void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item)
+{
+ RefPtr<HistoryItem> historyItem = PassRefPtr<HistoryItem>(item);
+ ASSERT(historyItem.get());
+
+ stopLoading(); // Make sure existing activity stops.
+
+ // If there is no currentItem, which happens when we are navigating in
+ // session history after a crash, we need to manufacture one otherwise WebKit
+ // hoarks. This is probably the wrong thing to do, but it seems to work.
+ RefPtr<HistoryItem> currentItem = m_frame->loader()->history()->currentItem();
+ if (!currentItem) {
+ currentItem = HistoryItem::create();
+ currentItem->setLastVisitWasFailure(true);
+ m_frame->loader()->history()->setCurrentItem(currentItem.get());
+ viewImpl()->setCurrentHistoryItem(currentItem.get());
+ }
+
+ m_frame->loader()->history()->goToItem(
+ historyItem.get(), FrameLoadTypeIndexedBackForward);
+}
+
+void WebFrameImpl::loadData(const WebData& data,
+ const WebString& mimeType,
+ const WebString& textEncoding,
+ const WebURL& baseURL,
+ const WebURL& unreachableURL,
+ bool replace)
+{
+ SubstituteData substData(data, mimeType, textEncoding, unreachableURL);
+ ASSERT(substData.isValid());
+
+ stopLoading(); // Make sure existing activity stops.
+ m_frame->loader()->load(ResourceRequest(baseURL), substData, false);
+ if (replace) {
+ // Do this to force WebKit to treat the load as replacing the currently
+ // loaded page.
+ m_frame->loader()->setReplacing();
+ }
+}
+
+void WebFrameImpl::loadHTMLString(const WebData& data,
+ const WebURL& baseURL,
+ const WebURL& unreachableURL,
+ bool replace)
+{
+ loadData(data,
+ WebString::fromUTF8("text/html"),
+ WebString::fromUTF8("UTF-8"),
+ baseURL,
+ unreachableURL,
+ replace);
+}
+
+bool WebFrameImpl::isLoading() const
+{
+ if (!m_frame)
+ return false;
+ return m_frame->loader()->isLoading();
+}
+
+void WebFrameImpl::stopLoading()
+{
+ if (!m_frame)
+ return;
+
+ // FIXME: Figure out what we should really do here. It seems like a bug
+ // that FrameLoader::stopLoading doesn't call stopAllLoaders.
+ m_frame->loader()->stopAllLoaders();
+ m_frame->loader()->stopLoading(UnloadEventPolicyNone);
+}
+
+WebDataSource* WebFrameImpl::provisionalDataSource() const
+{
+ FrameLoader* frameLoader = m_frame->loader();
+
+ // We regard the policy document loader as still provisional.
+ DocumentLoader* docLoader = frameLoader->provisionalDocumentLoader();
+ if (!docLoader)
+ docLoader = frameLoader->policyDocumentLoader();
+
+ return DataSourceForDocLoader(docLoader);
+}
+
+WebDataSource* WebFrameImpl::dataSource() const
+{
+ return DataSourceForDocLoader(m_frame->loader()->documentLoader());
+}
+
+WebHistoryItem WebFrameImpl::previousHistoryItem() const
+{
+ // We use the previous item here because documentState (filled-out forms)
+ // only get saved to history when it becomes the previous item. The caller
+ // is expected to query the history item after a navigation occurs, after
+ // the desired history item has become the previous entry.
+ return WebHistoryItem(viewImpl()->previousHistoryItem());
+}
+
+WebHistoryItem WebFrameImpl::currentHistoryItem() const
+{
+ m_frame->loader()->history()->saveDocumentAndScrollState();
+
+ return WebHistoryItem(m_frame->page()->backForwardList()->currentItem());
+}
+
+void WebFrameImpl::enableViewSourceMode(bool enable)
+{
+ if (m_frame)
+ m_frame->setInViewSourceMode(enable);
+}
+
+bool WebFrameImpl::isViewSourceModeEnabled() const
+{
+ if (m_frame)
+ return m_frame->inViewSourceMode();
+
+ return false;
+}
+
+void WebFrameImpl::setReferrerForRequest(
+ WebURLRequest& request, const WebURL& referrerURL) {
+ String referrer;
+ if (referrerURL.isEmpty())
+ referrer = m_frame->loader()->outgoingReferrer();
+ else
+ referrer = referrerURL.spec().utf16();
+ if (SecurityOrigin::shouldHideReferrer(request.url(), referrer))
+ return;
+ request.setHTTPHeaderField(WebString::fromUTF8("Referer"), referrer);
+}
+
+void WebFrameImpl::dispatchWillSendRequest(WebURLRequest& request)
+{
+ ResourceResponse response;
+ m_frame->loader()->client()->dispatchWillSendRequest(
+ 0, 0, request.toMutableResourceRequest(), response);
+}
+
+void WebFrameImpl::commitDocumentData(const char* data, size_t dataLen)
+{
+ DocumentLoader* documentLoader = m_frame->loader()->documentLoader();
+
+ // Set the text encoding. This calls begin() for us. It is safe to call
+ // this multiple times (Mac does: page/mac/WebCoreFrameBridge.mm).
+ bool userChosen = true;
+ String encoding = documentLoader->overrideEncoding();
+ if (encoding.isNull()) {
+ userChosen = false;
+ encoding = documentLoader->response().textEncodingName();
+ }
+ m_frame->loader()->setEncoding(encoding, userChosen);
+
+ // NOTE: mac only does this if there is a document
+ m_frame->loader()->addData(data, dataLen);
+}
+
+unsigned WebFrameImpl::unloadListenerCount() const
+{
+ return frame()->domWindow()->pendingUnloadEventListeners();
+}
+
+bool WebFrameImpl::isProcessingUserGesture() const
+{
+ return frame()->loader()->isProcessingUserGesture();
+}
+
+bool WebFrameImpl::willSuppressOpenerInNewFrame() const
+{
+ return frame()->loader()->suppressOpenerInNewFrame();
+}
+
+void WebFrameImpl::replaceSelection(const WebString& text)
+{
+ RefPtr<DocumentFragment> fragment = createFragmentFromText(
+ frame()->selection()->toNormalizedRange().get(), text);
+ applyCommand(ReplaceSelectionCommand::create(
+ frame()->document(), fragment.get(), false, true, true));
+}
+
+void WebFrameImpl::insertText(const WebString& text)
+{
+ frame()->editor()->insertText(text, 0);
+}
+
+void WebFrameImpl::setMarkedText(
+ const WebString& text, unsigned location, unsigned length)
+{
+ Editor* editor = frame()->editor();
+
+ editor->confirmComposition(text);
+
+ Vector<CompositionUnderline> decorations;
+ editor->setComposition(text, decorations, location, length);
+}
+
+void WebFrameImpl::unmarkText()
+{
+ frame()->editor()->confirmCompositionWithoutDisturbingSelection();
+}
+
+bool WebFrameImpl::hasMarkedText() const
+{
+ return frame()->editor()->hasComposition();
+}
+
+WebRange WebFrameImpl::markedRange() const
+{
+ return frame()->editor()->compositionRange();
+}
+
+bool WebFrameImpl::executeCommand(const WebString& name)
+{
+ ASSERT(frame());
+
+ if (name.length() <= 2)
+ return false;
+
+ // Since we don't have NSControl, we will convert the format of command
+ // string and call the function on Editor directly.
+ String command = name;
+
+ // Make sure the first letter is upper case.
+ command.replace(0, 1, command.substring(0, 1).upper());
+
+ // Remove the trailing ':' if existing.
+ if (command[command.length() - 1] == UChar(':'))
+ command = command.substring(0, command.length() - 1);
+
+ bool rv = true;
+
+ // Specially handling commands that Editor::execCommand does not directly
+ // support.
+ if (command == "DeleteToEndOfParagraph") {
+ Editor* editor = frame()->editor();
+ if (!editor->deleteWithDirection(SelectionController::FORWARD,
+ ParagraphBoundary,
+ true,
+ false)) {
+ editor->deleteWithDirection(SelectionController::FORWARD,
+ CharacterGranularity,
+ true,
+ false);
+ }
+ } else if (command == "Indent")
+ frame()->editor()->indent();
+ else if (command == "Outdent")
+ frame()->editor()->outdent();
+ else if (command == "DeleteBackward")
+ rv = frame()->editor()->command(AtomicString("BackwardDelete")).execute();
+ else if (command == "DeleteForward")
+ rv = frame()->editor()->command(AtomicString("ForwardDelete")).execute();
+ else if (command == "AdvanceToNextMisspelling") {
+ // False must be passed here, or the currently selected word will never be
+ // skipped.
+ frame()->editor()->advanceToNextMisspelling(false);
+ } else if (command == "ToggleSpellPanel")
+ frame()->editor()->showSpellingGuessPanel();
+ else
+ rv = frame()->editor()->command(command).execute();
+ return rv;
+}
+
+bool WebFrameImpl::executeCommand(const WebString& name, const WebString& value)
+{
+ ASSERT(frame());
+ String webName = name;
+
+ // moveToBeginningOfDocument and moveToEndfDocument are only handled by WebKit
+ // for editable nodes.
+ if (!frame()->editor()->canEdit() && webName == "moveToBeginningOfDocument")
+ return viewImpl()->propagateScroll(ScrollUp, ScrollByDocument);
+
+ if (!frame()->editor()->canEdit() && webName == "moveToEndOfDocument")
+ return viewImpl()->propagateScroll(ScrollDown, ScrollByDocument);
+
+ return frame()->editor()->command(webName).execute(value);
+}
+
+bool WebFrameImpl::isCommandEnabled(const WebString& name) const
+{
+ ASSERT(frame());
+ return frame()->editor()->command(name).isEnabled();
+}
+
+void WebFrameImpl::enableContinuousSpellChecking(bool enable)
+{
+ if (enable == isContinuousSpellCheckingEnabled())
+ return;
+ frame()->editor()->toggleContinuousSpellChecking();
+}
+
+bool WebFrameImpl::isContinuousSpellCheckingEnabled() const
+{
+ return frame()->editor()->isContinuousSpellCheckingEnabled();
+}
+
+bool WebFrameImpl::hasSelection() const
+{
+ // frame()->selection()->isNone() never returns true.
+ return (frame()->selection()->start() != frame()->selection()->end());
+}
+
+WebRange WebFrameImpl::selectionRange() const
+{
+ return frame()->selection()->toNormalizedRange();
+}
+
+WebString WebFrameImpl::selectionAsText() const
+{
+ RefPtr<Range> range = frame()->selection()->toNormalizedRange();
+ if (!range.get())
+ return WebString();
+
+ String text = range->text();
+#if PLATFORM(WIN_OS)
+ replaceNewlinesWithWindowsStyleNewlines(text);
+#endif
+ replaceNBSPWithSpace(text);
+ return text;
+}
+
+WebString WebFrameImpl::selectionAsMarkup() const
+{
+ RefPtr<Range> range = frame()->selection()->toNormalizedRange();
+ if (!range.get())
+ return WebString();
+
+ return createMarkup(range.get(), 0);
+}
+
+int WebFrameImpl::printBegin(const WebSize& pageSize)
+{
+ ASSERT(!frame()->document()->isFrameSet());
+
+ m_printContext.set(new ChromePrintContext(frame()));
+ FloatRect rect(0, 0, static_cast<float>(pageSize.width),
+ static_cast<float>(pageSize.height));
+ m_printContext->begin(rect.width());
+ float pageHeight;
+ // We ignore the overlays calculation for now since they are generated in the
+ // browser. pageHeight is actually an output parameter.
+ m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight);
+ return m_printContext->pageCount();
+}
+
+float WebFrameImpl::getPrintPageShrink(int page)
+{
+ // Ensure correct state.
+ if (!m_printContext.get() || page < 0) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
+ return m_printContext->getPageShrink(page);
+}
+
+float WebFrameImpl::printPage(int page, WebCanvas* canvas)
+{
+ // Ensure correct state.
+ if (!m_printContext.get() || page < 0 || !frame() || !frame()->document()) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
+#if PLATFORM(WIN_OS) || PLATFORM(LINUX) || PLATFORM(FREEBSD)
+ PlatformContextSkia context(canvas);
+ GraphicsContext spool(&context);
+#elif PLATFORM(DARWIN)
+ GraphicsContext spool(canvas);
+ LocalCurrentGraphicsContext localContext(&spool);
+#endif
+
+ return m_printContext->spoolPage(spool, page);
+}
+
+void WebFrameImpl::printEnd()
+{
+ ASSERT(m_printContext.get());
+ if (m_printContext.get())
+ m_printContext->end();
+ m_printContext.clear();
+}
+
+bool WebFrameImpl::find(int identifier,
+ const WebString& searchText,
+ const WebFindOptions& options,
+ bool wrapWithinFrame,
+ WebRect* selectionRect)
+{
+ WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
+
+ if (!options.findNext)
+ frame()->page()->unmarkAllTextMatches();
+ else
+ setMarkerActive(m_activeMatch.get(), false); // Active match is changing.
+
+ // Starts the search from the current selection.
+ bool startInSelection = true;
+
+ // If the user has selected something since the last Find operation we want
+ // to start from there. Otherwise, we start searching from where the last Find
+ // operation left off (either a Find or a FindNext operation).
+ VisibleSelection selection(frame()->selection()->selection());
+ if (selection.isNone() && m_activeMatch) {
+ selection = VisibleSelection(m_activeMatch.get());
+ frame()->selection()->setSelection(selection);
+ }
+
+ ASSERT(frame() && frame()->view());
+ bool found = frame()->findString(
+ searchText, options.forward, options.matchCase, wrapWithinFrame,
+ startInSelection);
+ if (found) {
+ // Store which frame was active. This will come in handy later when we
+ // change the active match ordinal below.
+ WebFrameImpl* oldActiveFrame = mainFrameImpl->m_activeMatchFrame;
+ // Set this frame as the active frame (the one with the active highlight).
+ mainFrameImpl->m_activeMatchFrame = this;
+
+ // We found something, so we can now query the selection for its position.
+ VisibleSelection newSelection(frame()->selection()->selection());
+ IntRect currSelectionRect;
+
+ // If we thought we found something, but it couldn't be selected (perhaps
+ // because it was marked -webkit-user-select: none), we can't set it to
+ // be active but we still continue searching. This matches Safari's
+ // behavior, including some oddities when selectable and un-selectable text
+ // are mixed on a page: see https://bugs.webkit.org/show_bug.cgi?id=19127.
+ if (newSelection.isNone() || (newSelection.start() == newSelection.end()))
+ m_activeMatch = 0;
+ else {
+ m_activeMatch = newSelection.toNormalizedRange();
+ currSelectionRect = m_activeMatch->boundingBox();
+ setMarkerActive(m_activeMatch.get(), true); // Active.
+ // WebKit draws the highlighting for all matches.
+ executeCommand(WebString::fromUTF8("Unselect"));
+ }
+
+ if (!options.findNext) {
+ // This is a Find operation, so we set the flag to ask the scoping effort
+ // to find the active rect for us so we can update the ordinal (n of m).
+ m_locatingActiveRect = true;
+ } else {
+ if (oldActiveFrame != this) {
+ // If the active frame has changed it means that we have a multi-frame
+ // page and we just switch to searching in a new frame. Then we just
+ // want to reset the index.
+ if (options.forward)
+ m_activeMatchIndex = 0;
+ else
+ m_activeMatchIndex = m_lastMatchCount - 1;
+ } else {
+ // We are still the active frame, so increment (or decrement) the
+ // |m_activeMatchIndex|, wrapping if needed (on single frame pages).
+ options.forward ? ++m_activeMatchIndex : --m_activeMatchIndex;
+ if (m_activeMatchIndex + 1 > m_lastMatchCount)
+ m_activeMatchIndex = 0;
+ if (m_activeMatchIndex + 1 == 0)
+ m_activeMatchIndex = m_lastMatchCount - 1;
+ }
+ if (selectionRect) {
+ WebRect rect = frame()->view()->convertToContainingWindow(currSelectionRect);
+ rect.x -= frameView()->scrollOffset().width();
+ rect.y -= frameView()->scrollOffset().height();
+ *selectionRect = rect;
+
+ reportFindInPageSelection(rect, m_activeMatchIndex + 1, identifier);
+ }
+ }
+ } else {
+ // Nothing was found in this frame.
+ m_activeMatch = 0;
+
+ // Erase all previous tickmarks and highlighting.
+ invalidateArea(InvalidateAll);
+ }
+
+ return found;
+}
+
+void WebFrameImpl::stopFinding(bool clearSelection)
+{
+ if (!clearSelection)
+ setFindEndstateFocusAndSelection();
+ cancelPendingScopingEffort();
+
+ // Remove all markers for matches found and turn off the highlighting.
+ if (!parent())
+ frame()->document()->removeMarkers(DocumentMarker::TextMatch);
+ frame()->setMarkedTextMatchesAreHighlighted(false);
+
+ // Let the frame know that we don't want tickmarks or highlighting anymore.
+ invalidateArea(InvalidateAll);
+}
+
+void WebFrameImpl::scopeStringMatches(int identifier,
+ const WebString& searchText,
+ const WebFindOptions& options,
+ bool reset)
+{
+ if (!shouldScopeMatches(searchText))
+ return;
+
+ WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
+
+ if (reset) {
+ // This is a brand new search, so we need to reset everything.
+ // Scoping is just about to begin.
+ m_scopingComplete = false;
+ // Clear highlighting for this frame.
+ if (frame()->markedTextMatchesAreHighlighted())
+ frame()->page()->unmarkAllTextMatches();
+ // Clear the counters from last operation.
+ m_lastMatchCount = 0;
+ m_nextInvalidateAfter = 0;
+
+ m_resumeScopingFromRange = 0;
+
+ mainFrameImpl->m_framesScopingCount++;
+
+ // Now, defer scoping until later to allow find operation to finish quickly.
+ scopeStringMatchesSoon(
+ identifier,
+ searchText,
+ options,
+ false); // false=we just reset, so don't do it again.
+ return;
+ }
+
+ RefPtr<Range> searchRange(rangeOfContents(frame()->document()));
+
+ ExceptionCode ec = 0, ec2 = 0;
+ if (m_resumeScopingFromRange.get()) {
+ // This is a continuation of a scoping operation that timed out and didn't
+ // complete last time around, so we should start from where we left off.
+ searchRange->setStart(m_resumeScopingFromRange->startContainer(),
+ m_resumeScopingFromRange->startOffset(ec2) + 1,
+ ec);
+ if (ec != 0 || ec2 != 0) {
+ if (ec2 != 0) // A non-zero |ec| happens when navigating during search.
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ }
+
+ // This timeout controls how long we scope before releasing control. This
+ // value does not prevent us from running for longer than this, but it is
+ // periodically checked to see if we have exceeded our allocated time.
+ const double maxScopingDuration = 0.1; // seconds
+
+ int matchCount = 0;
+ bool timedOut = false;
+ double startTime = currentTime();
+ do {
+ // Find next occurrence of the search string.
+ // FIXME: (http://b/1088245) This WebKit operation may run for longer
+ // than the timeout value, and is not interruptible as it is currently
+ // written. We may need to rewrite it with interruptibility in mind, or
+ // find an alternative.
+ RefPtr<Range> resultRange(findPlainText(searchRange.get(),
+ searchText,
+ true,
+ options.matchCase));
+ if (resultRange->collapsed(ec)) {
+ if (!resultRange->startContainer()->isInShadowTree())
+ break;
+
+ searchRange = rangeOfContents(frame()->document());
+ searchRange->setStartAfter(
+ resultRange->startContainer()->shadowAncestorNode(), ec);
+ continue;
+ }
+
+ // A non-collapsed result range can in some funky whitespace cases still not
+ // advance the range's start position (4509328). Break to avoid infinite
+ // loop. (This function is based on the implementation of
+ // Frame::markAllMatchesForText, which is where this safeguard comes from).
+ VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
+ if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
+ break;
+
+ // Only treat the result as a match if it is visible
+ if (frame()->editor()->insideVisibleArea(resultRange.get())) {
+ ++matchCount;
+
+ setStart(searchRange.get(), newStart);
+ Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
+ if (searchRange->collapsed(ec) && shadowTreeRoot)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
+
+ // Catch a special case where Find found something but doesn't know what
+ // the bounding box for it is. In this case we set the first match we find
+ // as the active rect.
+ IntRect resultBounds = resultRange->boundingBox();
+ IntRect activeSelectionRect;
+ if (m_locatingActiveRect) {
+ activeSelectionRect = m_activeMatch.get() ?
+ m_activeMatch->boundingBox() : resultBounds;
+ }
+
+ // If the Find function found a match it will have stored where the
+ // match was found in m_activeSelectionRect on the current frame. If we
+ // find this rect during scoping it means we have found the active
+ // tickmark.
+ bool foundActiveMatch = false;
+ if (m_locatingActiveRect && (activeSelectionRect == resultBounds)) {
+ // We have found the active tickmark frame.
+ mainFrameImpl->m_activeMatchFrame = this;
+ foundActiveMatch = true;
+ // We also know which tickmark is active now.
+ m_activeMatchIndex = matchCount - 1;
+ // To stop looking for the active tickmark, we set this flag.
+ m_locatingActiveRect = false;
+
+ // Notify browser of new location for the selected rectangle.
+ resultBounds.move(-frameView()->scrollOffset().width(),
+ -frameView()->scrollOffset().height());
+ reportFindInPageSelection(
+ frame()->view()->convertToContainingWindow(resultBounds),
+ m_activeMatchIndex + 1,
+ identifier);
+ }
+
+ addMarker(resultRange.get(), foundActiveMatch);
+ }
+
+ m_resumeScopingFromRange = resultRange;
+ timedOut = (currentTime() - startTime) >= maxScopingDuration;
+ } while (!timedOut);
+
+ // Remember what we search for last time, so we can skip searching if more
+ // letters are added to the search string (and last outcome was 0).
+ m_lastSearchString = searchText;
+
+ if (matchCount > 0) {
+ frame()->setMarkedTextMatchesAreHighlighted(true);
+
+ m_lastMatchCount += matchCount;
+
+ // Let the mainframe know how much we found during this pass.
+ mainFrameImpl->increaseMatchCount(matchCount, identifier);
+ }
+
+ if (timedOut) {
+ // If we found anything during this pass, we should redraw. However, we
+ // don't want to spam too much if the page is extremely long, so if we
+ // reach a certain point we start throttling the redraw requests.
+ if (matchCount > 0)
+ invalidateIfNecessary();
+
+ // Scoping effort ran out of time, lets ask for another time-slice.
+ scopeStringMatchesSoon(
+ identifier,
+ searchText,
+ options,
+ false); // don't reset.
+ return; // Done for now, resume work later.
+ }
+
+ // This frame has no further scoping left, so it is done. Other frames might,
+ // of course, continue to scope matches.
+ m_scopingComplete = true;
+ mainFrameImpl->m_framesScopingCount--;
+
+ // If this is the last frame to finish scoping we need to trigger the final
+ // update to be sent.
+ if (mainFrameImpl->m_framesScopingCount == 0)
+ mainFrameImpl->increaseMatchCount(0, identifier);
+
+ // This frame is done, so show any scrollbar tickmarks we haven't drawn yet.
+ invalidateArea(InvalidateScrollbar);
+}
+
+void WebFrameImpl::cancelPendingScopingEffort()
+{
+ deleteAllValues(m_deferredScopingWork);
+ m_deferredScopingWork.clear();
+
+ m_activeMatchIndex = -1;
+}
+
+void WebFrameImpl::increaseMatchCount(int count, int identifier)
+{
+ // This function should only be called on the mainframe.
+ ASSERT(!parent());
+
+ m_totalMatchCount += count;
+
+ // Update the UI with the latest findings.
+ if (client()) {
+ client()->reportFindInPageMatchCount(identifier, m_totalMatchCount,
+ m_framesScopingCount == 0);
+ }
+}
+
+void WebFrameImpl::reportFindInPageSelection(const WebRect& selectionRect,
+ int activeMatchOrdinal,
+ int identifier)
+{
+ // Update the UI with the latest selection rect.
+ if (client()) {
+ client()->reportFindInPageSelection(
+ identifier, ordinalOfFirstMatchForFrame(this) + activeMatchOrdinal,
+ selectionRect);
+ }
+}
+
+void WebFrameImpl::resetMatchCount()
+{
+ m_totalMatchCount = 0;
+ m_framesScopingCount = 0;
+}
+
+WebURL WebFrameImpl::completeURL(const WebString& url) const
+{
+ if (!m_frame || !m_frame->document())
+ return WebURL();
+
+ return m_frame->document()->completeURL(url);
+}
+
+WebString WebFrameImpl::contentAsText(size_t maxChars) const
+{
+ if (!m_frame)
+ return WebString();
+
+ Vector<UChar> text;
+ frameContentAsPlainText(maxChars, m_frame, &text);
+ return String::adopt(text);
+}
+
+WebString WebFrameImpl::contentAsMarkup() const
+{
+ return createFullMarkup(m_frame->document());
+}
+
+// WebFrameImpl public ---------------------------------------------------------
+
+int WebFrameImpl::m_liveObjectCount = 0;
+
+PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client)
+{
+ return adoptRef(new WebFrameImpl(ClientHandle::create(client)));
+}
+
+WebFrameImpl::WebFrameImpl(PassRefPtr<ClientHandle> clientHandle)
+ : m_frameLoaderClient(this)
+ , m_clientHandle(clientHandle)
+ , m_activeMatchFrame(0)
+ , m_activeMatchIndex(-1)
+ , m_locatingActiveRect(false)
+ , m_resumeScopingFromRange(0)
+ , m_lastMatchCount(-1)
+ , m_totalMatchCount(-1)
+ , m_framesScopingCount(-1)
+ , m_scopingComplete(false)
+ , m_nextInvalidateAfter(0)
+{
+ ChromiumBridge::incrementStatsCounter(webFrameActiveCount);
+ m_liveObjectCount++;
+}
+
+WebFrameImpl::~WebFrameImpl()
+{
+ ChromiumBridge::decrementStatsCounter(webFrameActiveCount);
+ m_liveObjectCount--;
+
+ cancelPendingScopingEffort();
+ clearPasswordListeners();
+}
+
+void WebFrameImpl::initializeAsMainFrame(WebViewImpl* webViewImpl)
+{
+ RefPtr<Frame> frame = Frame::create(webViewImpl->page(), 0, &m_frameLoaderClient);
+ m_frame = frame.get();
+
+ // Add reference on behalf of FrameLoader. See comments in
+ // WebFrameLoaderClient::frameLoaderDestroyed for more info.
+ ref();
+
+ // We must call init() after m_frame is assigned because it is referenced
+ // during init().
+ m_frame->init();
+}
+
+PassRefPtr<Frame> WebFrameImpl::createChildFrame(
+ const FrameLoadRequest& request, HTMLFrameOwnerElement* ownerElement)
+{
+ RefPtr<WebFrameImpl> webframe(adoptRef(new WebFrameImpl(m_clientHandle)));
+
+ // Add an extra ref on behalf of the Frame/FrameLoader, which references the
+ // WebFrame via the FrameLoaderClient interface. See the comment at the top
+ // of this file for more info.
+ webframe->ref();
+
+ RefPtr<Frame> childFrame = Frame::create(
+ m_frame->page(), ownerElement, &webframe->m_frameLoaderClient);
+ webframe->m_frame = childFrame.get();
+
+ childFrame->tree()->setName(request.frameName());
+
+ m_frame->tree()->appendChild(childFrame);
+
+ // 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
+ // so that webframe->mFrame is in the tree before triggering
+ // onload event handler.
+ // 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.
+ // (b:791612)
+ childFrame->init(); // create an empty document
+ if (!childFrame->tree()->parent())
+ return 0;
+
+ m_frame->loader()->loadURLIntoChildFrame(
+ request.resourceRequest().url(),
+ request.resourceRequest().httpReferrer(),
+ childFrame.get());
+
+ // 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.
+ if (!childFrame->tree()->parent())
+ return 0;
+
+ return childFrame.release();
+}
+
+void WebFrameImpl::layout()
+{
+ // layout this frame
+ FrameView* view = m_frame->view();
+ if (view)
+ view->layoutIfNeededRecursive();
+}
+
+void WebFrameImpl::paint(WebCanvas* canvas, const WebRect& rect)
+{
+ if (rect.isEmpty())
+ return;
+ IntRect dirtyRect(rect);
+#if WEBKIT_USING_CG
+ GraphicsContext gc(canvas);
+ LocalCurrentGraphicsContext localContext(&gc);
+#elif WEBKIT_USING_SKIA
+ PlatformContextSkia context(canvas);
+
+ // PlatformGraphicsContext is actually a pointer to PlatformContextSkia
+ GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context));
+#else
+ notImplemented();
+#endif
+ gc.save();
+ if (m_frame->document() && frameView()) {
+ gc.clip(dirtyRect);
+ frameView()->paint(&gc, dirtyRect);
+ m_frame->page()->inspectorController()->drawNodeHighlight(gc);
+ } else
+ gc.fillRect(dirtyRect, Color::white);
+ gc.restore();
+}
+
+void WebFrameImpl::createFrameView()
+{
+ ASSERT(m_frame); // If m_frame doesn't exist, we probably didn't init properly.
+
+ Page* page = m_frame->page();
+ ASSERT(page);
+
+ ASSERT(page->mainFrame() != 0);
+
+ bool isMainFrame = m_frame == page->mainFrame();
+ if (isMainFrame && m_frame->view())
+ m_frame->view()->setParentVisible(false);
+
+ m_frame->setView(0);
+
+ WebViewImpl* webView = viewImpl();
+
+ RefPtr<FrameView> view;
+ if (isMainFrame)
+ view = FrameView::create(m_frame, webView->size());
+ else
+ view = FrameView::create(m_frame);
+
+ m_frame->setView(view);
+
+ if (webView->isTransparent())
+ view->setTransparent(true);
+
+ // FIXME: The Mac code has a comment about this possibly being unnecessary.
+ // See installInFrame in WebCoreFrameBridge.mm
+ if (m_frame->ownerRenderer())
+ m_frame->ownerRenderer()->setWidget(view.get());
+
+ if (HTMLFrameOwnerElement* owner = m_frame->ownerElement())
+ view->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
+
+ if (isMainFrame)
+ view->setParentVisible(true);
+}
+
+WebFrameImpl* WebFrameImpl::fromFrame(Frame* frame)
+{
+ if (!frame)
+ return 0;
+
+ return static_cast<FrameLoaderClientImpl*>(frame->loader()->client())->webFrame();
+}
+
+WebViewImpl* WebFrameImpl::viewImpl() const
+{
+ if (!m_frame)
+ return 0;
+
+ return WebViewImpl::fromPage(m_frame->page());
+}
+
+WebDataSourceImpl* WebFrameImpl::dataSourceImpl() const
+{
+ return static_cast<WebDataSourceImpl*>(dataSource());
+}
+
+WebDataSourceImpl* WebFrameImpl::provisionalDataSourceImpl() const
+{
+ return static_cast<WebDataSourceImpl*>(provisionalDataSource());
+}
+
+void WebFrameImpl::setFindEndstateFocusAndSelection()
+{
+ WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
+
+ if (this == mainFrameImpl->activeMatchFrame() && m_activeMatch.get()) {
+ // If the user has set the selection since the match was found, we
+ // don't focus anything.
+ VisibleSelection selection(frame()->selection()->selection());
+ if (!selection.isNone())
+ return;
+
+ // Try to find the first focusable node up the chain, which will, for
+ // example, focus links if we have found text within the link.
+ Node* node = m_activeMatch->firstNode();
+ while (node && !node->isFocusable() && node != frame()->document())
+ node = node->parent();
+
+ if (node && node != frame()->document()) {
+ // Found a focusable parent node. Set focus to it.
+ frame()->document()->setFocusedNode(node);
+ } else {
+ // Iterate over all the nodes in the range until we find a focusable node.
+ // This, for example, sets focus to the first link if you search for
+ // text and text that is within one or more links.
+ node = m_activeMatch->firstNode();
+ while (node && node != m_activeMatch->pastLastNode()) {
+ if (node->isFocusable()) {
+ frame()->document()->setFocusedNode(node);
+ break;
+ }
+ node = node->traverseNextNode();
+ }
+ }
+ }
+}
+
+void WebFrameImpl::didFail(const ResourceError& error, bool wasProvisional)
+{
+ if (!client())
+ return;
+ WebURLError webError = error;
+ if (wasProvisional)
+ client()->didFailProvisionalLoad(this, webError);
+ else
+ client()->didFailLoad(this, webError);
+}
+
+void WebFrameImpl::setAllowsScrolling(bool flag)
+{
+ m_frame->view()->setCanHaveScrollbars(flag);
+}
+
+void WebFrameImpl::registerPasswordListener(
+ PassRefPtr<HTMLInputElement> inputElement,
+ PasswordAutocompleteListener* listener)
+{
+ RefPtr<HTMLInputElement> element = inputElement;
+ ASSERT(m_passwordListeners.find(element) == m_passwordListeners.end());
+ m_passwordListeners.set(element, listener);
+}
+
+PasswordAutocompleteListener* WebFrameImpl::getPasswordListener(
+ HTMLInputElement* inputElement)
+{
+ return m_passwordListeners.get(RefPtr<HTMLInputElement>(inputElement));
+}
+
+// WebFrameImpl private --------------------------------------------------------
+
+void WebFrameImpl::closing()
+{
+ m_frame = 0;
+}
+
+void WebFrameImpl::invalidateArea(AreaToInvalidate area)
+{
+ ASSERT(frame() && frame()->view());
+ FrameView* view = frame()->view();
+
+ if ((area & InvalidateAll) == InvalidateAll)
+ view->invalidateRect(view->frameRect());
+ else {
+ if ((area & InvalidateContentArea) == InvalidateContentArea) {
+ IntRect contentArea(
+ view->x(), view->y(), view->visibleWidth(), view->visibleHeight());
+ view->invalidateRect(contentArea);
+ }
+
+ if ((area & InvalidateScrollbar) == InvalidateScrollbar) {
+ // Invalidate the vertical scroll bar region for the view.
+ IntRect scrollBarVert(
+ view->x() + view->visibleWidth(), view->y(),
+ ScrollbarTheme::nativeTheme()->scrollbarThickness(),
+ view->visibleHeight());
+ view->invalidateRect(scrollBarVert);
+ }
+ }
+}
+
+void WebFrameImpl::addMarker(Range* range, bool activeMatch)
+{
+ // Use a TextIterator to visit the potentially multiple nodes the range
+ // covers.
+ TextIterator markedText(range);
+ for (; !markedText.atEnd(); markedText.advance()) {
+ RefPtr<Range> textPiece = markedText.range();
+ int exception = 0;
+
+ DocumentMarker marker = {
+ DocumentMarker::TextMatch,
+ textPiece->startOffset(exception),
+ textPiece->endOffset(exception),
+ "",
+ activeMatch
+ };
+
+ if (marker.endOffset > marker.startOffset) {
+ // Find the node to add a marker to and add it.
+ Node* node = textPiece->startContainer(exception);
+ frame()->document()->addMarker(node, marker);
+
+ // Rendered rects for markers in WebKit are not populated until each time
+ // the markers are painted. However, we need it to happen sooner, because
+ // the whole purpose of tickmarks on the scrollbar is to show where
+ // matches off-screen are (that haven't been painted yet).
+ Vector<DocumentMarker> markers = frame()->document()->markersForNode(node);
+ frame()->document()->setRenderedRectForMarker(
+ textPiece->startContainer(exception),
+ markers[markers.size() - 1],
+ range->boundingBox());
+ }
+ }
+}
+
+void WebFrameImpl::setMarkerActive(Range* range, bool active)
+{
+ if (!range)
+ return;
+
+ frame()->document()->setMarkersActive(range, active);
+}
+
+int WebFrameImpl::ordinalOfFirstMatchForFrame(WebFrameImpl* frame) const
+{
+ int ordinal = 0;
+ WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
+ // Iterate from the main frame up to (but not including) |frame| and
+ // add up the number of matches found so far.
+ for (WebFrameImpl* it = mainFrameImpl;
+ it != frame;
+ it = static_cast<WebFrameImpl*>(it->traverseNext(true))) {
+ if (it->m_lastMatchCount > 0)
+ ordinal += it->m_lastMatchCount;
+ }
+ return ordinal;
+}
+
+bool WebFrameImpl::shouldScopeMatches(const String& searchText)
+{
+ // Don't scope if we can't find a frame or if the frame is not visible.
+ // The user may have closed the tab/application, so abort.
+ if (!frame() || !hasVisibleContent())
+ return false;
+
+ ASSERT(frame()->document() && frame()->view());
+
+ // If the frame completed the scoping operation and found 0 matches the last
+ // time it was searched, then we don't have to search it again if the user is
+ // just adding to the search string or sending the same search string again.
+ if (m_scopingComplete && !m_lastSearchString.isEmpty() && m_lastMatchCount == 0) {
+ // Check to see if the search string prefixes match.
+ String previousSearchPrefix =
+ searchText.substring(0, m_lastSearchString.length());
+
+ if (previousSearchPrefix == m_lastSearchString)
+ return false; // Don't search this frame, it will be fruitless.
+ }
+
+ return true;
+}
+
+void WebFrameImpl::scopeStringMatchesSoon(int identifier, const WebString& searchText,
+ const WebFindOptions& options, bool reset)
+{
+ m_deferredScopingWork.append(new DeferredScopeStringMatches(
+ this, identifier, searchText, options, reset));
+}
+
+void WebFrameImpl::callScopeStringMatches(DeferredScopeStringMatches* caller,
+ int identifier, const WebString& searchText,
+ const WebFindOptions& options, bool reset)
+{
+ m_deferredScopingWork.remove(m_deferredScopingWork.find(caller));
+
+ scopeStringMatches(identifier, searchText, options, reset);
+
+ // This needs to happen last since searchText is passed by reference.
+ delete caller;
+}
+
+void WebFrameImpl::invalidateIfNecessary()
+{
+ if (m_lastMatchCount > m_nextInvalidateAfter) {
+ // FIXME: (http://b/1088165) Optimize the drawing of the tickmarks and
+ // remove this. This calculation sets a milestone for when next to
+ // invalidate the scrollbar and the content area. We do this so that we
+ // don't spend too much time drawing the scrollbar over and over again.
+ // Basically, up until the first 500 matches there is no throttle.
+ // After the first 500 matches, we set set the milestone further and
+ // further out (750, 1125, 1688, 2K, 3K).
+ static const int startSlowingDownAfter = 500;
+ static const int slowdown = 750;
+ int i = (m_lastMatchCount / startSlowingDownAfter);
+ m_nextInvalidateAfter += i * slowdown;
+
+ invalidateArea(InvalidateScrollbar);
+ }
+}
+
+void WebFrameImpl::clearPasswordListeners()
+{
+ deleteAllValues(m_passwordListeners);
+ m_passwordListeners.clear();
+}
+
+void WebFrameImpl::loadJavaScriptURL(const KURL& url)
+{
+ // This is copied from FrameLoader::executeIfJavaScriptURL. Unfortunately,
+ // we cannot just use that method since it is private, and it also doesn't
+ // quite behave as we require it to for bookmarklets. The key difference is
+ // that we need to suppress loading the string result from evaluating the JS
+ // URL if executing the JS URL resulted in a location change. We also allow
+ // a JS URL to be loaded even if scripts on the page are otherwise disabled.
+
+ if (!m_frame->document() || !m_frame->page())
+ return;
+
+ String script = decodeURLEscapeSequences(url.string().substring(strlen("javascript:")));
+ ScriptValue result = m_frame->script()->executeScript(script, true);
+
+ String scriptResult;
+ if (!result.getString(scriptResult))
+ return;
+
+ SecurityOrigin* securityOrigin = m_frame->document()->securityOrigin();
+
+ if (!m_frame->redirectScheduler()->locationChangePending()) {
+ m_frame->loader()->stopAllLoaders();
+ m_frame->loader()->begin(m_frame->loader()->url(), true, securityOrigin);
+ m_frame->loader()->write(scriptResult);
+ m_frame->loader()->end();
+ }
+}
+
+} // namespace WebKit
diff --git a/webkit/api/src/WebFrameImpl.h b/webkit/api/src/WebFrameImpl.h
new file mode 100644
index 0000000..8a3772c
--- /dev/null
+++ b/webkit/api/src/WebFrameImpl.h
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebFrameImpl_h
+#define WebFrameImpl_h
+
+#include "Frame.h"
+#include "FrameLoaderClientImpl.h"
+#include "PlatformString.h"
+// FIXME: remove this relative path once consumers from glue are removed.
+#include "../public/WebFrame.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+class HistoryItem;
+class KURL;
+class Node;
+class Range;
+class SubstituteData;
+struct WindowFeatures;
+}
+
+namespace WebKit {
+class ChromePrintContext;
+class PasswordAutocompleteListener;
+class WebDataSourceImpl;
+class WebFrameClient;
+class WebView;
+class WebViewImpl;
+
+// Implementation of WebFrame, note that this is a reference counted object.
+class WebFrameImpl : public WebFrame, public RefCounted<WebFrameImpl> {
+public:
+ // WebFrame methods:
+ virtual WebString name() const;
+ virtual WebURL url() const;
+ virtual WebURL favIconURL() const;
+ virtual WebURL openSearchDescriptionURL() const;
+ virtual WebSize scrollOffset() const;
+ virtual WebSize contentsSize() const;
+ virtual int contentsPreferredWidth() const;
+ virtual bool hasVisibleContent() const;
+ virtual WebView* view() const;
+ virtual WebFrame* opener() const;
+ virtual WebFrame* parent() const;
+ virtual WebFrame* top() const;
+ virtual WebFrame* firstChild() const;
+ virtual WebFrame* lastChild() const;
+ virtual WebFrame* nextSibling() const;
+ virtual WebFrame* previousSibling() const;
+ virtual WebFrame* traverseNext(bool wrap) const;
+ virtual WebFrame* traversePrevious(bool wrap) const;
+ virtual WebFrame* findChildByName(const WebString&) const;
+ virtual WebFrame* findChildByExpression(const WebString&) const;
+ virtual void forms(WebVector<WebForm>&) const;
+ virtual WebSecurityOrigin securityOrigin() const;
+ virtual void grantUniversalAccess();
+ virtual NPObject* windowObject() const;
+ virtual void bindToWindowObject(const WebString& name, NPObject*);
+ virtual void executeScript(const WebScriptSource&);
+ virtual void executeScriptInNewContext(
+ const WebScriptSource* sources, unsigned numSources, int extensionGroup);
+ virtual void executeScriptInIsolatedWorld(
+ int worldId, const WebScriptSource* sources, unsigned numSources,
+ int extensionGroup);
+ virtual void addMessageToConsole(const WebConsoleMessage&);
+ virtual void collectGarbage();
+#if WEBKIT_USING_V8
+ virtual v8::Local<v8::Context> mainWorldScriptContext() const;
+#endif
+ virtual bool insertStyleText(const WebString& css, const WebString& id);
+ virtual void reload();
+ virtual void loadRequest(const WebURLRequest&);
+ virtual void loadHistoryItem(const WebHistoryItem&);
+ virtual void loadData(
+ const WebData&, const WebString& mimeType, const WebString& textEncoding,
+ const WebURL& baseURL, const WebURL& unreachableURL, bool replace);
+ virtual void loadHTMLString(
+ const WebData& html, const WebURL& baseURL, const WebURL& unreachableURL,
+ bool replace);
+ virtual bool isLoading() const;
+ virtual void stopLoading();
+ virtual WebDataSource* provisionalDataSource() const;
+ virtual WebDataSource* dataSource() const;
+ virtual WebHistoryItem previousHistoryItem() const;
+ virtual WebHistoryItem currentHistoryItem() const;
+ virtual void enableViewSourceMode(bool enable);
+ virtual bool isViewSourceModeEnabled() const;
+ virtual void setReferrerForRequest(WebURLRequest&, const WebURL& referrer);
+ virtual void dispatchWillSendRequest(WebURLRequest&);
+ virtual void commitDocumentData(const char* data, size_t length);
+ virtual unsigned unloadListenerCount() const;
+ virtual bool isProcessingUserGesture() const;
+ virtual bool willSuppressOpenerInNewFrame() const;
+ virtual void replaceSelection(const WebString&);
+ virtual void insertText(const WebString&);
+ virtual void setMarkedText(const WebString&, unsigned location, unsigned length);
+ virtual void unmarkText();
+ virtual bool hasMarkedText() const;
+ virtual WebRange markedRange() const;
+ virtual bool executeCommand(const WebString&);
+ virtual bool executeCommand(const WebString&, const WebString& value);
+ virtual bool isCommandEnabled(const WebString&) const;
+ virtual void enableContinuousSpellChecking(bool);
+ virtual bool isContinuousSpellCheckingEnabled() const;
+ virtual bool hasSelection() const;
+ virtual WebRange selectionRange() const;
+ virtual WebString selectionAsText() const;
+ virtual WebString selectionAsMarkup() const;
+ virtual int printBegin(const WebSize& pageSize);
+ virtual float printPage(int pageToPrint, WebCanvas*);
+ virtual float getPrintPageShrink(int page);
+ virtual void printEnd();
+ virtual bool find(
+ int identifier, const WebString& searchText, const WebFindOptions&,
+ bool wrapWithinFrame, WebRect* selectionRect);
+ virtual void stopFinding(bool clearSelection);
+ virtual void scopeStringMatches(
+ int identifier, const WebString& searchText, const WebFindOptions&,
+ bool reset);
+ virtual void cancelPendingScopingEffort();
+ virtual void increaseMatchCount(int count, int identifier);
+ virtual void resetMatchCount();
+ virtual WebURL completeURL(const WebString& url) const;
+ virtual WebString contentAsText(size_t maxChars) const;
+ virtual WebString contentAsMarkup() const;
+
+ static PassRefPtr<WebFrameImpl> create(WebFrameClient* client);
+ ~WebFrameImpl();
+
+ static int liveObjectCount() {
+ return m_liveObjectCount;
+ }
+
+ // Called by the WebViewImpl to initialize its main frame:
+ void initializeAsMainFrame(WebViewImpl*);
+
+ PassRefPtr<WebCore::Frame> createChildFrame(
+ const WebCore::FrameLoadRequest&, WebCore::HTMLFrameOwnerElement*);
+
+ void layout();
+ void paint(WebCanvas*, const WebRect&);
+ void createFrameView();
+
+ static WebFrameImpl* fromFrame(WebCore::Frame* frame);
+
+ WebViewImpl* viewImpl() const;
+
+ WebCore::Frame* frame() const { return m_frame; }
+ WebCore::FrameView* frameView() const { return m_frame ? m_frame->view() : 0; }
+
+ // Getters for the impls corresponding to Get(Provisional)DataSource. They
+ // may return NULL if there is no corresponding data source.
+ WebDataSourceImpl* dataSourceImpl() const;
+ WebDataSourceImpl* provisionalDataSourceImpl() const;
+
+ // Returns which frame has an active match. This function should only be
+ // called on the main frame, as it is the only frame keeping track. Returned
+ // value can be NULL if no frame has an active match.
+ const WebFrameImpl* activeMatchFrame() const { return m_activeMatchFrame; }
+
+ // When a Find operation ends, we want to set the selection to what was active
+ // and set focus to the first focusable node we find (starting with the first
+ // node in the matched range and going up the inheritance chain). If we find
+ // nothing to focus we focus the first focusable node in the range. This
+ // allows us to set focus to a link (when we find text inside a link), which
+ // allows us to navigate by pressing Enter after closing the Find box.
+ void setFindEndstateFocusAndSelection();
+
+ void didFail(const WebCore::ResourceError&, bool wasProvisional);
+
+ // Sets whether the WebFrameImpl allows its document to be scrolled.
+ // If the parameter is true, allow the document to be scrolled.
+ // Otherwise, disallow scrolling.
+ void setAllowsScrolling(bool);
+
+ // Registers a listener for the specified user name input element. The
+ // listener will receive notifications for blur and when autocomplete should
+ // be triggered.
+ // The WebFrameImpl becomes the owner of the passed listener.
+ void registerPasswordListener(
+ PassRefPtr<WebCore::HTMLInputElement>,
+ PasswordAutocompleteListener*);
+
+ // Returns the password autocomplete listener associated with the passed
+ // user name input element, or NULL if none available.
+ // Note that the returned listener is owner by the WebFrameImpl and should not
+ // be kept around as it is deleted when the page goes away.
+ PasswordAutocompleteListener* getPasswordListener(WebCore::HTMLInputElement*);
+
+ WebFrameClient* client() const { return m_clientHandle->client(); }
+ void dropClient() { m_clientHandle->dropClient(); }
+
+private:
+ class DeferredScopeStringMatches;
+ friend class DeferredScopeStringMatches;
+ friend class FrameLoaderClientImpl;
+
+ // A weak reference to the WebFrameClient. Each WebFrame in the hierarchy
+ // owns a reference to a ClientHandle. When the main frame is destroyed, it
+ // clears the WebFrameClient.
+ class ClientHandle : public RefCounted<ClientHandle> {
+ public:
+ static PassRefPtr<ClientHandle> create(WebFrameClient* client)
+ {
+ return adoptRef(new ClientHandle(client));
+ }
+ WebFrameClient* client() { return m_client; }
+ void dropClient() { m_client = NULL; }
+ private:
+ ClientHandle(WebFrameClient* client) : m_client(client) {}
+ WebFrameClient* m_client;
+ };
+
+ // A bit mask specifying area of the frame to invalidate.
+ enum AreaToInvalidate {
+ InvalidateNothing,
+ InvalidateContentArea,
+ InvalidateScrollbar, // Vertical scrollbar only.
+ InvalidateAll // Both content area and the scrollbar.
+ };
+
+ WebFrameImpl(PassRefPtr<ClientHandle>);
+
+ // Informs the WebFrame that the Frame is being closed, called by the
+ // WebFrameLoaderClient
+ void closing();
+
+ // Notifies the delegate about a new selection rect.
+ void reportFindInPageSelection(
+ const WebRect& selectionRect, int activeMatchOrdinal, int identifier);
+
+ // Invalidates a certain area within the frame.
+ void invalidateArea(AreaToInvalidate);
+
+ // Add a WebKit TextMatch-highlight marker to nodes in a range.
+ void addMarker(WebCore::Range*, bool activeMatch);
+
+ // Sets the markers within a range as active or inactive.
+ void setMarkerActive(WebCore::Range*, bool active);
+
+ // Returns the ordinal of the first match in the frame specified. This
+ // function enumerates the frames, starting with the main frame and up to (but
+ // not including) the frame passed in as a parameter and counts how many
+ // matches have been found.
+ int ordinalOfFirstMatchForFrame(WebFrameImpl*) const;
+
+ // Determines whether the scoping effort is required for a particular frame.
+ // It is not necessary if the frame is invisible, for example, or if this
+ // is a repeat search that already returned nothing last time the same prefix
+ // was searched.
+ bool shouldScopeMatches(const WebCore::String& searchText);
+
+ // Queue up a deferred call to scopeStringMatches.
+ void scopeStringMatchesSoon(
+ int identifier, const WebString& searchText, const WebFindOptions&,
+ bool reset);
+
+ // Called by a DeferredScopeStringMatches instance.
+ void callScopeStringMatches(
+ DeferredScopeStringMatches*, int identifier, const WebString& searchText,
+ const WebFindOptions&, bool reset);
+
+ // Determines whether to invalidate the content area and scrollbar.
+ void invalidateIfNecessary();
+
+ // Clears the map of password listeners.
+ void clearPasswordListeners();
+
+ void loadJavaScriptURL(const WebCore::KURL&);
+
+ // Used to check for leaks of this object.
+ static int m_liveObjectCount;
+
+ FrameLoaderClientImpl m_frameLoaderClient;
+
+ RefPtr<ClientHandle> m_clientHandle;
+
+ // This is a weak pointer to our corresponding WebCore frame. A reference to
+ // ourselves is held while frame_ is valid. See our Closing method.
+ WebCore::Frame* m_frame;
+
+ // A way for the main frame to keep track of which frame has an active
+ // match. Should be NULL for all other frames.
+ WebFrameImpl* m_activeMatchFrame;
+
+ // The range of the active match for the current frame.
+ RefPtr<WebCore::Range> m_activeMatch;
+
+ // The index of the active match.
+ int m_activeMatchIndex;
+
+ // This flag is used by the scoping effort to determine if we need to figure
+ // out which rectangle is the active match. Once we find the active
+ // rectangle we clear this flag.
+ bool m_locatingActiveRect;
+
+ // The scoping effort can time out and we need to keep track of where we
+ // ended our last search so we can continue from where we left of.
+ RefPtr<WebCore::Range> m_resumeScopingFromRange;
+
+ // Keeps track of the last string this frame searched for. This is used for
+ // short-circuiting searches in the following scenarios: When a frame has
+ // been searched and returned 0 results, we don't need to search that frame
+ // again if the user is just adding to the search (making it more specific).
+ WebCore::String m_lastSearchString;
+
+ // Keeps track of how many matches this frame has found so far, so that we
+ // don't loose count between scoping efforts, and is also used (in conjunction
+ // with m_lastSearchString and m_scopingComplete) to figure out if we need to
+ // search the frame again.
+ int m_lastMatchCount;
+
+ // This variable keeps a cumulative total of matches found so far for ALL the
+ // frames on the page, and is only incremented by calling IncreaseMatchCount
+ // (on the main frame only). It should be -1 for all other frames.
+ size_t m_totalMatchCount;
+
+ // This variable keeps a cumulative total of how many frames are currently
+ // scoping, and is incremented/decremented on the main frame only.
+ // It should be -1 for all other frames.
+ int m_framesScopingCount;
+
+ // Keeps track of whether the scoping effort was completed (the user may
+ // interrupt it before it completes by submitting a new search).
+ bool m_scopingComplete;
+
+ // Keeps track of when the scoping effort should next invalidate the scrollbar
+ // and the frame area.
+ int m_nextInvalidateAfter;
+
+ // A list of all of the pending calls to scopeStringMatches.
+ Vector<DeferredScopeStringMatches*> m_deferredScopingWork;
+
+ // Valid between calls to BeginPrint() and EndPrint(). Containts the print
+ // information. Is used by PrintPage().
+ OwnPtr<ChromePrintContext> m_printContext;
+
+ // The input fields that are interested in edit events and their associated
+ // listeners.
+ typedef HashMap<RefPtr<WebCore::HTMLInputElement>,
+ PasswordAutocompleteListener*> PasswordListenerMap;
+ PasswordListenerMap m_passwordListeners;
+};
+
+} // namespace WebKit
+
+#endif
diff --git a/webkit/api/src/WebStorageEventDispatcherImpl.cpp b/webkit/api/src/WebStorageEventDispatcherImpl.cpp
index a6da503..2e6df47 100644
--- a/webkit/api/src/WebStorageEventDispatcherImpl.cpp
+++ b/webkit/api/src/WebStorageEventDispatcherImpl.cpp
@@ -35,10 +35,10 @@
#include "SecurityOrigin.h"
-extern const char* pageGroupName;
-
namespace WebKit {
+extern const char* pageGroupName;
+
WebStorageEventDispatcher* WebStorageEventDispatcher::create()
{
return new WebStorageEventDispatcherImpl();
diff --git a/webkit/api/src/WebViewImpl.cpp b/webkit/api/src/WebViewImpl.cpp
new file mode 100644
index 0000000..3aa2279
--- /dev/null
+++ b/webkit/api/src/WebViewImpl.cpp
@@ -0,0 +1,1767 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebViewImpl.h"
+
+#include "AutocompletePopupMenuClient.h"
+#include "AXObjectCache.h"
+#include "CSSStyleSelector.h"
+#include "CSSValueKeywords.h"
+#include "Cursor.h"
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "DOMUtilitiesPrivate.h"
+#include "DragController.h"
+#include "DragData.h"
+#include "Editor.h"
+#include "EventHandler.h"
+#include "FocusController.h"
+#include "FontDescription.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "HTMLNames.h"
+#include "HTMLInputElement.h"
+#include "HTMLMediaElement.h"
+#include "HitTestResult.h"
+#include "Image.h"
+#include "InspectorController.h"
+#include "IntRect.h"
+#include "KeyboardCodes.h"
+#include "KeyboardEvent.h"
+#include "MIMETypeRegistry.h"
+#include "NodeRenderStyle.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "Pasteboard.h"
+#include "PlatformContextSkia.h"
+#include "PlatformKeyboardEvent.h"
+#include "PlatformMouseEvent.h"
+#include "PlatformWheelEvent.h"
+#include "PluginInfoStore.h"
+#include "PopupMenuChromium.h"
+#include "PopupMenuClient.h"
+#include "RenderView.h"
+#include "ResourceHandle.h"
+#include "SecurityOrigin.h"
+#include "SelectionController.h"
+#include "Settings.h"
+#include "TypingCommand.h"
+#include "WebAccessibilityObject.h"
+#include "WebDragData.h"
+#include "WebFrameImpl.h"
+#include "WebInputEvent.h"
+#include "WebInputEventConversion.h"
+#include "WebMediaPlayerAction.h"
+#include "WebNode.h"
+#include "WebPoint.h"
+#include "WebPopupMenuImpl.h"
+#include "WebRect.h"
+#include "WebSettingsImpl.h"
+#include "WebString.h"
+#include "WebVector.h"
+#include "WebViewClient.h"
+
+#if PLATFORM(WIN_OS)
+#include "KeyboardCodesWin.h"
+#include "RenderThemeChromiumWin.h"
+#else
+#include "KeyboardCodesPosix.h"
+#include "RenderTheme.h"
+#endif
+
+// FIXME
+#include "webkit/glue/webdevtoolsagent_impl.h"
+
+// Get rid of WTF's pow define so we can use std::pow.
+#undef pow
+#include <cmath> // for std::pow
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// Change the text zoom level by kTextSizeMultiplierRatio each time the user
+// zooms text in or out (ie., change by 20%). The min and max values limit
+// text zoom to half and 3x the original text size. These three values match
+// those in Apple's port in WebKit/WebKit/WebView/WebView.mm
+static const double textSizeMultiplierRatio = 1.2;
+static const double minTextSizeMultiplier = 0.5;
+static const double maxTextSizeMultiplier = 3.0;
+
+// The group name identifies a namespace of pages. Page group is used on OSX
+// for some programs that use HTML views to display things that don't seem like
+// web pages to the user (so shouldn't have visited link coloring). We only use
+// one page group.
+const char* pageGroupName = "default";
+
+// Ensure that the WebDragOperation enum values stay in sync with the original
+// DragOperation constants.
+#define COMPILE_ASSERT_MATCHING_ENUM(coreName) \
+ COMPILE_ASSERT(int(coreName) == int(Web##coreName), dummy##coreName)
+COMPILE_ASSERT_MATCHING_ENUM(DragOperationNone);
+COMPILE_ASSERT_MATCHING_ENUM(DragOperationCopy);
+COMPILE_ASSERT_MATCHING_ENUM(DragOperationLink);
+COMPILE_ASSERT_MATCHING_ENUM(DragOperationGeneric);
+COMPILE_ASSERT_MATCHING_ENUM(DragOperationPrivate);
+COMPILE_ASSERT_MATCHING_ENUM(DragOperationMove);
+COMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete);
+COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery);
+
+// Note that focusOnShow is false so that the autocomplete popup is shown not
+// activated. We need the page to still have focus so the user can keep typing
+// while the popup is showing.
+static const PopupContainerSettings autocompletePopupSettings = {
+ false, // focusOnShow
+ false, // setTextOnIndexChange
+ false, // acceptOnAbandon
+ true, // loopSelectionNavigation
+ true, // restrictWidthOfListBox. Same as other browser (Fx, IE, and safari)
+ // For autocomplete, we use the direction of the input field as the direction
+ // of the popup items. The main reason is to keep the display of items in
+ // drop-down the same as the items in the input field.
+ PopupContainerSettings::DOMElementDirection,
+};
+
+// WebView ----------------------------------------------------------------
+
+WebView* WebView::create(WebViewClient* client)
+{
+ return new WebViewImpl(client);
+}
+
+void WebView::updateVisitedLinkState(unsigned long long linkHash)
+{
+ Page::visitedStateChanged(PageGroup::pageGroup(pageGroupName), linkHash);
+}
+
+void WebView::resetVisitedLinkState()
+{
+ Page::allVisitedStateChanged(PageGroup::pageGroup(pageGroupName));
+}
+
+void WebViewImpl::initializeMainFrame(WebFrameClient* frameClient) {
+ // NOTE: The WebFrameImpl takes a reference to itself within InitMainFrame
+ // and releases that reference once the corresponding Frame is destroyed.
+ RefPtr<WebFrameImpl> frame = WebFrameImpl::create(frameClient);
+
+ frame->initializeAsMainFrame(this);
+
+ if (m_client) {
+ WebDevToolsAgentClient* toolsClient = m_client->devToolsAgentClient();
+ if (toolsClient)
+ m_devToolsAgent.set(new WebDevToolsAgentImpl(this, toolsClient));
+ }
+
+ // Restrict the access to the local file system
+ // (see WebView.mm WebView::_commonInitializationWithFrameName).
+ SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForLocalOnly);
+}
+
+WebViewImpl::WebViewImpl(WebViewClient* client)
+ : m_client(client)
+ , m_backForwardListClientImpl(this)
+ , m_chromeClientImpl(this)
+ , m_contextMenuClientImpl(this)
+ , m_dragClientImpl(this)
+ , m_editorClientImpl(this)
+ , m_inspectorClientImpl(this)
+ , m_observedNewNavigation(false)
+#ifndef NDEBUG
+ , m_newNavigationLoader(0)
+#endif
+ , m_zoomLevel(0)
+ , m_contextMenuAllowed(false)
+ , m_doingDragAndDrop(false)
+ , m_ignoreInputEvents(false)
+ , m_suppressNextKeypressEvent(false)
+ , m_initialNavigationPolicy(WebNavigationPolicyIgnore)
+ , m_imeAcceptEvents(true)
+ , m_dragTargetDispatch(false)
+ , m_dragIdentity(0)
+ , m_dropEffect(DropEffectDefault)
+ , m_operationsAllowed(WebDragOperationNone)
+ , m_dragOperation(WebDragOperationNone)
+ , m_autocompletePopupShowing(false)
+ , m_isTransparent(false)
+ , m_tabsToLinks(false)
+{
+ // WebKit/win/WebView.cpp does the same thing, except they call the
+ // KJS specific wrapper around this method. We need to have threading
+ // initialized because CollatorICU requires it.
+ WTF::initializeThreading();
+
+ // set to impossible point so we always get the first mouse pos
+ m_lastMousePosition = WebPoint(-1, -1);
+
+ // the page will take ownership of the various clients
+ m_page.set(new Page(&m_chromeClientImpl,
+ &m_contextMenuClientImpl,
+ &m_editorClientImpl,
+ &m_dragClientImpl,
+ &m_inspectorClientImpl,
+ 0));
+
+ m_page->backForwardList()->setClient(&m_backForwardListClientImpl);
+ m_page->setGroupName(pageGroupName);
+}
+
+WebViewImpl::~WebViewImpl()
+{
+ ASSERT(!m_page);
+}
+
+RenderTheme* WebViewImpl::theme() const
+{
+ return m_page.get() ? m_page->theme() : RenderTheme::defaultTheme().get();
+}
+
+WebFrameImpl* WebViewImpl::mainFrameImpl()
+{
+ return m_page.get() ? WebFrameImpl::fromFrame(m_page->mainFrame()) : 0;
+}
+
+bool WebViewImpl::tabKeyCyclesThroughElements() const
+{
+ ASSERT(m_page.get());
+ return m_page->tabKeyCyclesThroughElements();
+}
+
+void WebViewImpl::setTabKeyCyclesThroughElements(bool value)
+{
+ if (m_page)
+ m_page->setTabKeyCyclesThroughElements(value);
+}
+
+void WebViewImpl::mouseMove(const WebMouseEvent& event)
+{
+ if (!mainFrameImpl() || !mainFrameImpl()->frameView())
+ return;
+
+ m_lastMousePosition = WebPoint(event.x, event.y);
+
+ // We call mouseMoved here instead of handleMouseMovedEvent because we need
+ // our ChromeClientImpl to receive changes to the mouse position and
+ // tooltip text, and mouseMoved handles all of that.
+ mainFrameImpl()->frame()->eventHandler()->mouseMoved(
+ PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
+}
+
+void WebViewImpl::mouseLeave(const WebMouseEvent& event)
+{
+ // This event gets sent as the main frame is closing. In that case, just
+ // ignore it.
+ if (!mainFrameImpl() || !mainFrameImpl()->frameView())
+ return;
+
+ m_client->setMouseOverURL(WebURL());
+
+ mainFrameImpl()->frame()->eventHandler()->handleMouseMoveEvent(
+ PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
+}
+
+void WebViewImpl::mouseDown(const WebMouseEvent& event)
+{
+ if (!mainFrameImpl() || !mainFrameImpl()->frameView())
+ return;
+
+ m_lastMouseDownPoint = WebPoint(event.x, event.y);
+
+ // If a text field that has focus is clicked again, we should display the
+ // autocomplete popup.
+ RefPtr<Node> clickedNode;
+ if (event.button == WebMouseEvent::ButtonLeft) {
+ RefPtr<Node> focusedNode = focusedWebCoreNode();
+ if (focusedNode.get() && toHTMLInputElement(focusedNode.get())) {
+ IntPoint point(event.x, event.y);
+ point = m_page->mainFrame()->view()->windowToContents(point);
+ HitTestResult result(point);
+ result = m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, false);
+ if (result.innerNonSharedNode() == focusedNode) {
+ // Already focused text field was clicked, let's remember this. If
+ // focus has not changed after the mouse event is processed, we'll
+ // trigger the autocomplete.
+ clickedNode = focusedNode;
+ }
+ }
+ }
+
+ mainFrameImpl()->frame()->eventHandler()->handleMousePressEvent(
+ PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
+
+ if (clickedNode.get() && clickedNode == focusedWebCoreNode()) {
+ // Focus has not changed, show the autocomplete popup.
+ static_cast<EditorClientImpl*>(m_page->editorClient())->
+ showFormAutofillForNode(clickedNode.get());
+ }
+
+ // Dispatch the contextmenu event regardless of if the click was swallowed.
+ // On Windows, we handle it on mouse up, not down.
+#if PLATFORM(DARWIN)
+ if (event.button == WebMouseEvent::ButtonRight
+ || (event.button == WebMouseEvent::ButtonLeft
+ && event.modifiers & WebMouseEvent::ControlKey))
+ mouseContextMenu(event);
+#elif PLATFORM(LINUX)
+ if (event.button == WebMouseEvent::ButtonRight)
+ mouseContextMenu(event);
+#endif
+}
+
+void WebViewImpl::mouseContextMenu(const WebMouseEvent& event)
+{
+ if (!mainFrameImpl() || !mainFrameImpl()->frameView())
+ return;
+
+ m_page->contextMenuController()->clearContextMenu();
+
+ PlatformMouseEventBuilder pme(mainFrameImpl()->frameView(), event);
+
+ // Find the right target frame. See issue 1186900.
+ HitTestResult result = hitTestResultForWindowPos(pme.pos());
+ Frame* targetFrame;
+ if (result.innerNonSharedNode())
+ targetFrame = result.innerNonSharedNode()->document()->frame();
+ else
+ targetFrame = m_page->focusController()->focusedOrMainFrame();
+
+#if PLATFORM(WIN_OS)
+ targetFrame->view()->setCursor(pointerCursor());
+#endif
+
+ m_contextMenuAllowed = true;
+ targetFrame->eventHandler()->sendContextMenuEvent(pme);
+ m_contextMenuAllowed = false;
+ // Actually showing the context menu is handled by the ContextMenuClient
+ // implementation...
+}
+
+void WebViewImpl::mouseUp(const WebMouseEvent& event)
+{
+ if (!mainFrameImpl() || !mainFrameImpl()->frameView())
+ return;
+
+#if PLATFORM(LINUX)
+ // If the event was a middle click, attempt to copy text into the focused
+ // frame. We execute this before we let the page have a go at the event
+ // because the page may change what is focused during in its event handler.
+ //
+ // This code is in the mouse up handler. There is some debate about putting
+ // this here, as opposed to the mouse down handler.
+ // xterm: pastes on up.
+ // GTK: pastes on down.
+ // Firefox: pastes on up.
+ // Midori: couldn't paste at all with 0.1.2
+ //
+ // There is something of a webcompat angle to this well, as highlighted by
+ // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
+ // down then the text is pasted just before the onclick handler runs and
+ // clears the text box. So it's important this happens after the
+ // handleMouseReleaseEvent() earlier in this function
+ if (event.button == WebMouseEvent::ButtonMiddle) {
+ Frame* focused = focusedWebCoreFrame();
+ IntPoint clickPoint(m_lastMouseDownPoint.x, m_lastMouseDownPoint.y);
+ clickPoint = m_page->mainFrame()->view()->windowToContents(clickPoint);
+ HitTestResult hitTestResult =
+ focused->eventHandler()->hitTestResultAtPoint(clickPoint, false, false,
+ ShouldHitTestScrollbars);
+ // We don't want to send a paste when middle clicking a scroll bar or a
+ // link (which will navigate later in the code).
+ if (!hitTestResult.scrollbar() && !hitTestResult.isLiveLink() && focused) {
+ Editor* editor = focused->editor();
+ Pasteboard* pasteboard = Pasteboard::generalPasteboard();
+ bool oldSelectionMode = pasteboard->isSelectionMode();
+ pasteboard->setSelectionMode(true);
+ editor->command(AtomicString("Paste")).execute();
+ pasteboard->setSelectionMode(oldSelectionMode);
+ }
+ }
+#endif
+
+ mouseCaptureLost();
+ mainFrameImpl()->frame()->eventHandler()->handleMouseReleaseEvent(
+ PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
+
+#if PLATFORM(WIN_OS)
+ // Dispatch the contextmenu event regardless of if the click was swallowed.
+ // On Mac/Linux, we handle it on mouse down, not up.
+ if (event.button == WebMouseEvent::ButtonRight)
+ mouseContextMenu(event);
+#endif
+}
+
+void WebViewImpl::mouseWheel(const WebMouseWheelEvent& event)
+{
+ PlatformWheelEventBuilder platformEvent(mainFrameImpl()->frameView(), event);
+ mainFrameImpl()->frame()->eventHandler()->handleWheelEvent(platformEvent);
+}
+
+bool WebViewImpl::keyEvent(const WebKeyboardEvent& event)
+{
+ ASSERT((event.type == WebInputEvent::RawKeyDown)
+ || (event.type == WebInputEvent::KeyDown)
+ || (event.type == WebInputEvent::KeyUp));
+
+ // Please refer to the comments explaining the m_suppressNextKeypressEvent
+ // member.
+ // The m_suppressNextKeypressEvent is set if the KeyDown is handled by
+ // Webkit. A keyDown event is typically associated with a keyPress(char)
+ // event and a keyUp event. We reset this flag here as this is a new keyDown
+ // event.
+ m_suppressNextKeypressEvent = false;
+
+ // Give autocomplete a chance to consume the key events it is interested in.
+ if (autocompleteHandleKeyEvent(event))
+ return true;
+
+ Frame* frame = focusedWebCoreFrame();
+ if (!frame)
+ return false;
+
+ EventHandler* handler = frame->eventHandler();
+ if (!handler)
+ return keyEventDefault(event);
+
+#if PLATFORM(WIN_OS) || PLATFORM(LINUX)
+ if (((event.modifiers == 0) && (event.windowsKeyCode == VKEY_APPS))
+ || ((event.modifiers == WebInputEvent::ShiftKey) && (event.windowsKeyCode == VKEY_F10))) {
+ sendContextMenuEvent(event);
+ return true;
+ }
+#endif
+
+ // It's not clear if we should continue after detecting a capslock keypress.
+ // I'll err on the side of continuing, which is the pre-existing behaviour.
+ if (event.windowsKeyCode == VKEY_CAPITAL)
+ handler->capsLockStateMayHaveChanged();
+
+ PlatformKeyboardEventBuilder evt(event);
+
+ if (handler->keyEvent(evt)) {
+ if (WebInputEvent::RawKeyDown == event.type && !evt.isSystemKey())
+ m_suppressNextKeypressEvent = true;
+ return true;
+ }
+
+ return keyEventDefault(event);
+}
+
+bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event)
+{
+ if (!m_autocompletePopupShowing
+ // Home and End should be left to the text field to process.
+ || event.windowsKeyCode == VKEY_HOME
+ || event.windowsKeyCode == VKEY_END)
+ return false;
+
+ // Pressing delete triggers the removal of the selected suggestion from the DB.
+ if (event.windowsKeyCode == VKEY_DELETE
+ && m_autocompletePopup->selectedIndex() != -1) {
+ Node* node = focusedWebCoreNode();
+ if (!node || (node->nodeType() != Node::ELEMENT_NODE)) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ Element* element = static_cast<Element*>(node);
+ if (!element->hasLocalName(HTMLNames::inputTag)) {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ int selectedIndex = m_autocompletePopup->selectedIndex();
+ HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element);
+ WebString name = inputElement->name();
+ WebString value = m_autocompletePopupClient->itemText(selectedIndex);
+ m_client->removeAutofillSuggestions(name, value);
+ // Update the entries in the currently showing popup to reflect the
+ // deletion.
+ m_autocompletePopupClient->removeItemAtIndex(selectedIndex);
+ refreshAutofillPopup();
+ return false;
+ }
+
+ if (!m_autocompletePopup->isInterestedInEventForKey(event.windowsKeyCode))
+ return false;
+
+ if (m_autocompletePopup->handleKeyEvent(PlatformKeyboardEventBuilder(event))) {
+ // We need to ignore the next Char event after this otherwise pressing
+ // enter when selecting an item in the menu will go to the page.
+ if (WebInputEvent::RawKeyDown == event.type)
+ m_suppressNextKeypressEvent = true;
+ return true;
+ }
+
+ return false;
+}
+
+bool WebViewImpl::charEvent(const WebKeyboardEvent& event)
+{
+ ASSERT(event.type == WebInputEvent::Char);
+
+ // Please refer to the comments explaining the m_suppressNextKeypressEvent
+ // member. The m_suppressNextKeypressEvent is set if the KeyDown is
+ // handled by Webkit. A keyDown event is typically associated with a
+ // keyPress(char) event and a keyUp event. We reset this flag here as it
+ // only applies to the current keyPress event.
+ if (m_suppressNextKeypressEvent) {
+ m_suppressNextKeypressEvent = false;
+ return true;
+ }
+
+ Frame* frame = focusedWebCoreFrame();
+ if (!frame)
+ return false;
+
+ EventHandler* handler = frame->eventHandler();
+ if (!handler)
+ return keyEventDefault(event);
+
+ PlatformKeyboardEventBuilder evt(event);
+ if (!evt.isCharacterKey())
+ return true;
+
+ // Safari 3.1 does not pass off windows system key messages (WM_SYSCHAR) to
+ // the eventHandler::keyEvent. We mimic this behavior on all platforms since
+ // for now we are converting other platform's key events to windows key
+ // events.
+ if (evt.isSystemKey())
+ return handler->handleAccessKey(evt);
+
+ if (!handler->keyEvent(evt))
+ return keyEventDefault(event);
+
+ return true;
+}
+
+// The WebViewImpl::SendContextMenuEvent function is based on the Webkit
+// function
+// bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam) in
+// webkit\webkit\win\WebView.cpp. The only significant change in this
+// function is the code to convert from a Keyboard event to the Right
+// Mouse button up event.
+//
+// This function is an ugly copy/paste and should be cleaned up when the
+// WebKitWin version is cleaned: https://bugs.webkit.org/show_bug.cgi?id=20438
+#if PLATFORM(WIN_OS) || PLATFORM(LINUX)
+// FIXME: implement on Mac
+bool WebViewImpl::sendContextMenuEvent(const WebKeyboardEvent& event)
+{
+ static const int kContextMenuMargin = 1;
+ Frame* mainFrameImpl = page()->mainFrame();
+ FrameView* view = mainFrameImpl->view();
+ if (!view)
+ return false;
+
+ IntPoint coords(-1, -1);
+#if PLATFORM(WIN_OS)
+ int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
+#else
+ int rightAligned = 0;
+#endif
+ IntPoint location;
+
+ // The context menu event was generated from the keyboard, so show the
+ // context menu by the current selection.
+ Position start = mainFrameImpl->selection()->selection().start();
+ Position end = mainFrameImpl->selection()->selection().end();
+
+ if (!start.node() || !end.node()) {
+ location = IntPoint(
+ rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
+ kContextMenuMargin);
+ } else {
+ RenderObject* renderer = start.node()->renderer();
+ if (!renderer)
+ return false;
+
+ RefPtr<Range> selection = mainFrameImpl->selection()->toNormalizedRange();
+ IntRect firstRect = mainFrameImpl->firstRectForRange(selection.get());
+
+ int x = rightAligned ? firstRect.right() : firstRect.x();
+ location = IntPoint(x, firstRect.bottom());
+ }
+
+ location = view->contentsToWindow(location);
+ // FIXME: The IntSize(0, -1) is a hack to get the hit-testing to result in
+ // the selected element. Ideally we'd have the position of a context menu
+ // event be separate from its target node.
+ coords = location + IntSize(0, -1);
+
+ // The contextMenuController() holds onto the last context menu that was
+ // popped up on the page until a new one is created. We need to clear
+ // this menu before propagating the event through the DOM so that we can
+ // detect if we create a new menu for this event, since we won't create
+ // a new menu if the DOM swallows the event and the defaultEventHandler does
+ // not run.
+ page()->contextMenuController()->clearContextMenu();
+
+ Frame* focusedFrame = page()->focusController()->focusedOrMainFrame();
+ focusedFrame->view()->setCursor(pointerCursor());
+ WebMouseEvent mouseEvent;
+ mouseEvent.button = WebMouseEvent::ButtonRight;
+ mouseEvent.x = coords.x();
+ mouseEvent.y = coords.y();
+ mouseEvent.type = WebInputEvent::MouseUp;
+
+ PlatformMouseEventBuilder platformEvent(view, mouseEvent);
+
+ m_contextMenuAllowed = true;
+ bool handled = focusedFrame->eventHandler()->sendContextMenuEvent(platformEvent);
+ m_contextMenuAllowed = false;
+ return handled;
+}
+#endif
+
+bool WebViewImpl::keyEventDefault(const WebKeyboardEvent& event)
+{
+ Frame* frame = focusedWebCoreFrame();
+ if (!frame)
+ return false;
+
+ switch (event.type) {
+ case WebInputEvent::Char:
+ if (event.windowsKeyCode == VKEY_SPACE) {
+ int keyCode = ((event.modifiers & WebInputEvent::ShiftKey) ? VKEY_PRIOR : VKEY_NEXT);
+ return scrollViewWithKeyboard(keyCode, event.modifiers);
+ }
+ break;
+ case WebInputEvent::RawKeyDown:
+ if (event.modifiers == WebInputEvent::ControlKey) {
+ switch (event.windowsKeyCode) {
+ case 'A':
+ focusedFrame()->executeCommand(WebString::fromUTF8("SelectAll"));
+ return true;
+ case VKEY_INSERT:
+ case 'C':
+ focusedFrame()->executeCommand(WebString::fromUTF8("Copy"));
+ return true;
+ // Match FF behavior in the sense that Ctrl+home/end are the only Ctrl
+ // key combinations which affect scrolling. Safari is buggy in the
+ // sense that it scrolls the page for all Ctrl+scrolling key
+ // combinations. For e.g. Ctrl+pgup/pgdn/up/down, etc.
+ case VKEY_HOME:
+ case VKEY_END:
+ break;
+ default:
+ return false;
+ }
+ }
+ if (!event.isSystemKey && !(event.modifiers & WebInputEvent::ShiftKey))
+ return scrollViewWithKeyboard(event.windowsKeyCode, event.modifiers);
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool WebViewImpl::scrollViewWithKeyboard(int keyCode, int modifiers)
+{
+ ScrollDirection scrollDirection;
+ ScrollGranularity scrollGranularity;
+
+ switch (keyCode) {
+ case VKEY_LEFT:
+ scrollDirection = ScrollLeft;
+ scrollGranularity = ScrollByLine;
+ break;
+ case VKEY_RIGHT:
+ scrollDirection = ScrollRight;
+ scrollGranularity = ScrollByLine;
+ break;
+ case VKEY_UP:
+ scrollDirection = ScrollUp;
+ scrollGranularity = ScrollByLine;
+ break;
+ case VKEY_DOWN:
+ scrollDirection = ScrollDown;
+ scrollGranularity = ScrollByLine;
+ break;
+ case VKEY_HOME:
+ scrollDirection = ScrollUp;
+ scrollGranularity = ScrollByDocument;
+ break;
+ case VKEY_END:
+ scrollDirection = ScrollDown;
+ scrollGranularity = ScrollByDocument;
+ break;
+ case VKEY_PRIOR: // page up
+ scrollDirection = ScrollUp;
+ scrollGranularity = ScrollByPage;
+ break;
+ case VKEY_NEXT: // page down
+ scrollDirection = ScrollDown;
+ scrollGranularity = ScrollByPage;
+ break;
+ default:
+ return false;
+ }
+
+ return propagateScroll(scrollDirection, scrollGranularity);
+}
+
+bool WebViewImpl::propagateScroll(ScrollDirection scrollDirection,
+ ScrollGranularity scrollGranularity)
+{
+ Frame* frame = focusedWebCoreFrame();
+ if (!frame)
+ return false;
+
+ bool scrollHandled =
+ frame->eventHandler()->scrollOverflow(scrollDirection,
+ scrollGranularity);
+ Frame* currentFrame = frame;
+ while (!scrollHandled && currentFrame) {
+ scrollHandled = currentFrame->view()->scroll(scrollDirection,
+ scrollGranularity);
+ currentFrame = currentFrame->tree()->parent();
+ }
+ return scrollHandled;
+}
+
+Frame* WebViewImpl::focusedWebCoreFrame()
+{
+ return m_page.get() ? m_page->focusController()->focusedOrMainFrame() : 0;
+}
+
+WebViewImpl* WebViewImpl::fromPage(Page* page)
+{
+ if (!page)
+ return 0;
+
+ return static_cast<ChromeClientImpl*>(page->chrome()->client())->webview();
+}
+
+// WebWidget ------------------------------------------------------------------
+
+void WebViewImpl::close()
+{
+ RefPtr<WebFrameImpl> mainFrameImpl;
+
+ if (m_page.get()) {
+ // Initiate shutdown for the entire frameset. This will cause a lot of
+ // notifications to be sent.
+ if (m_page->mainFrame()) {
+ mainFrameImpl = WebFrameImpl::fromFrame(m_page->mainFrame());
+ m_page->mainFrame()->loader()->frameDetached();
+ }
+ m_page.clear();
+ }
+
+ // Should happen after m_page.reset().
+ if (m_devToolsAgent.get())
+ m_devToolsAgent.clear();
+
+ // We drop the client after the page has been destroyed to support the
+ // WebFrameClient::didDestroyScriptContext method.
+ if (mainFrameImpl)
+ mainFrameImpl->dropClient();
+
+ // Reset the delegate to prevent notifications being sent as we're being
+ // deleted.
+ m_client = 0;
+
+ deref(); // Balances ref() acquired in WebView::create
+}
+
+void WebViewImpl::resize(const WebSize& newSize)
+{
+ if (m_size == newSize)
+ return;
+ m_size = newSize;
+
+ if (mainFrameImpl()->frameView()) {
+ mainFrameImpl()->frameView()->resize(m_size.width, m_size.height);
+ mainFrameImpl()->frame()->eventHandler()->sendResizeEvent();
+ }
+
+ if (m_client) {
+ WebRect damagedRect(0, 0, m_size.width, m_size.height);
+ m_client->didInvalidateRect(damagedRect);
+ }
+}
+
+void WebViewImpl::layout()
+{
+ WebFrameImpl* webframe = mainFrameImpl();
+ if (webframe) {
+ // In order for our child HWNDs (NativeWindowWidgets) to update properly,
+ // they need to be told that we are updating the screen. The problem is
+ // that the native widgets need to recalculate their clip region and not
+ // overlap any of our non-native widgets. To force the resizing, call
+ // setFrameRect(). This will be a quick operation for most frames, but
+ // the NativeWindowWidgets will update a proper clipping region.
+ FrameView* view = webframe->frameView();
+ if (view)
+ view->setFrameRect(view->frameRect());
+
+ // setFrameRect may have the side-effect of causing existing page
+ // layout to be invalidated, so layout needs to be called last.
+
+ webframe->layout();
+ }
+}
+
+void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect)
+{
+ WebFrameImpl* webframe = mainFrameImpl();
+ if (webframe)
+ webframe->paint(canvas, rect);
+}
+
+// FIXME: m_currentInputEvent should be removed once ChromeClient::show() can
+// get the current-event information from WebCore.
+const WebInputEvent* WebViewImpl::m_currentInputEvent = 0;
+
+bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent)
+{
+ // If we've started a drag and drop operation, ignore input events until
+ // we're done.
+ if (m_doingDragAndDrop)
+ return true;
+
+ if (m_ignoreInputEvents)
+ return true;
+
+ // FIXME: Remove m_currentInputEvent.
+ // This only exists to allow ChromeClient::show() to know which mouse button
+ // triggered a window.open event.
+ // Safari must perform a similar hack, ours is in our WebKit glue layer
+ // theirs is in the application. This should go when WebCore can be fixed
+ // to pass more event information to ChromeClient::show()
+ m_currentInputEvent = &inputEvent;
+
+ bool handled = true;
+
+ // FIXME: WebKit seems to always return false on mouse events processing
+ // methods. For now we'll assume it has processed them (as we are only
+ // interested in whether keyboard events are processed).
+ switch (inputEvent.type) {
+ case WebInputEvent::MouseMove:
+ mouseMove(*static_cast<const WebMouseEvent*>(&inputEvent));
+ break;
+
+ case WebInputEvent::MouseLeave:
+ mouseLeave(*static_cast<const WebMouseEvent*>(&inputEvent));
+ break;
+
+ case WebInputEvent::MouseWheel:
+ mouseWheel(*static_cast<const WebMouseWheelEvent*>(&inputEvent));
+ break;
+
+ case WebInputEvent::MouseDown:
+ mouseDown(*static_cast<const WebMouseEvent*>(&inputEvent));
+ break;
+
+ case WebInputEvent::MouseUp:
+ mouseUp(*static_cast<const WebMouseEvent*>(&inputEvent));
+ break;
+
+ case WebInputEvent::RawKeyDown:
+ case WebInputEvent::KeyDown:
+ case WebInputEvent::KeyUp:
+ handled = keyEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent));
+ break;
+
+ case WebInputEvent::Char:
+ handled = charEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent));
+ break;
+
+ default:
+ handled = false;
+ }
+
+ m_currentInputEvent = 0;
+
+ return handled;
+}
+
+void WebViewImpl::mouseCaptureLost()
+{
+}
+
+void WebViewImpl::setFocus(bool enable)
+{
+ m_page->focusController()->setFocused(enable);
+ if (enable) {
+ // Note that we don't call setActive() when disabled as this cause extra
+ // focus/blur events to be dispatched.
+ m_page->focusController()->setActive(true);
+ m_imeAcceptEvents = true;
+ } else {
+ hideAutoCompletePopup();
+
+ // Clear focus on the currently focused frame if any.
+ if (!m_page.get())
+ return;
+
+ Frame* frame = m_page->mainFrame();
+ if (!frame)
+ return;
+
+ RefPtr<Frame> focusedFrame = m_page->focusController()->focusedFrame();
+ if (focusedFrame.get()) {
+ // Finish an ongoing composition to delete the composition node.
+ Editor* editor = focusedFrame->editor();
+ if (editor && editor->hasComposition())
+ editor->confirmComposition();
+ m_imeAcceptEvents = false;
+ }
+ }
+}
+
+bool WebViewImpl::handleCompositionEvent(WebCompositionCommand command,
+ int cursorPosition,
+ int targetStart,
+ int targetEnd,
+ const WebString& imeString)
+{
+ Frame* focused = focusedWebCoreFrame();
+ if (!focused || !m_imeAcceptEvents)
+ return false;
+ Editor* editor = focused->editor();
+ if (!editor)
+ return false;
+ if (!editor->canEdit()) {
+ // The input focus has been moved to another WebWidget object.
+ // We should use this |editor| object only to complete the ongoing
+ // composition.
+ if (!editor->hasComposition())
+ return false;
+ }
+
+ // We should verify the parent node of this IME composition node are
+ // editable because JavaScript may delete a parent node of the composition
+ // node. In this case, WebKit crashes while deleting texts from the parent
+ // node, which doesn't exist any longer.
+ PassRefPtr<Range> range = editor->compositionRange();
+ if (range) {
+ const Node* node = range->startPosition().node();
+ if (!node || !node->isContentEditable())
+ return false;
+ }
+
+ if (command == WebCompositionCommandDiscard) {
+ // A browser process sent an IPC message which does not contain a valid
+ // string, which means an ongoing composition has been canceled.
+ // If the ongoing composition has been canceled, replace the ongoing
+ // composition string with an empty string and complete it.
+ String emptyString;
+ Vector<CompositionUnderline> emptyUnderlines;
+ editor->setComposition(emptyString, emptyUnderlines, 0, 0);
+ } else {
+ // A browser process sent an IPC message which contains a string to be
+ // displayed in this Editor object.
+ // To display the given string, set the given string to the
+ // m_compositionNode member of this Editor object and display it.
+ if (targetStart < 0)
+ targetStart = 0;
+ if (targetEnd < 0)
+ targetEnd = static_cast<int>(imeString.length());
+ String compositionString(imeString);
+ // Create custom underlines.
+ // To emphasize the selection, the selected region uses a solid black
+ // for its underline while other regions uses a pale gray for theirs.
+ Vector<CompositionUnderline> underlines(3);
+ underlines[0].startOffset = 0;
+ underlines[0].endOffset = targetStart;
+ underlines[0].thick = true;
+ underlines[0].color.setRGB(0xd3, 0xd3, 0xd3);
+ underlines[1].startOffset = targetStart;
+ underlines[1].endOffset = targetEnd;
+ underlines[1].thick = true;
+ underlines[1].color.setRGB(0x00, 0x00, 0x00);
+ underlines[2].startOffset = targetEnd;
+ underlines[2].endOffset = static_cast<int>(imeString.length());
+ underlines[2].thick = true;
+ underlines[2].color.setRGB(0xd3, 0xd3, 0xd3);
+ // When we use custom underlines, WebKit ("InlineTextBox.cpp" Line 282)
+ // prevents from writing a text in between 'selectionStart' and
+ // 'selectionEnd' somehow.
+ // Therefore, we use the 'cursorPosition' for these arguments so that
+ // there are not any characters in the above region.
+ editor->setComposition(compositionString, underlines,
+ cursorPosition, cursorPosition);
+ // The given string is a result string, which means the ongoing
+ // composition has been completed. I have to call the
+ // Editor::confirmCompletion() and complete this composition.
+ if (command == WebCompositionCommandConfirm)
+ editor->confirmComposition();
+ }
+
+ return editor->hasComposition();
+}
+
+bool WebViewImpl::queryCompositionStatus(bool* enableIME, WebRect* caretRect)
+{
+ // Store whether the selected node needs IME and the caret rectangle.
+ // This process consists of the following four steps:
+ // 1. Retrieve the selection controller of the focused frame;
+ // 2. Retrieve the caret rectangle from the controller;
+ // 3. Convert the rectangle, which is relative to the parent view, to the
+ // one relative to the client window, and;
+ // 4. Store the converted rectangle.
+ const Frame* focused = focusedWebCoreFrame();
+ if (!focused)
+ return false;
+
+ const Editor* editor = focused->editor();
+ if (!editor || !editor->canEdit())
+ return false;
+
+ SelectionController* controller = focused->selection();
+ if (!controller)
+ return false;
+
+ const Node* node = controller->start().node();
+ if (!node)
+ return false;
+
+ *enableIME = node->shouldUseInputMethod() && !controller->isInPasswordField();
+ const FrameView* view = node->document()->view();
+ if (!view)
+ return false;
+
+ *caretRect = view->contentsToWindow(controller->absoluteCaretBounds());
+ return true;
+}
+
+void WebViewImpl::setTextDirection(WebTextDirection direction)
+{
+ // The Editor::setBaseWritingDirection() function checks if we can change
+ // the text direction of the selected node and updates its DOM "dir"
+ // attribute and its CSS "direction" property.
+ // So, we just call the function as Safari does.
+ const Frame* focused = focusedWebCoreFrame();
+ if (!focused)
+ return;
+
+ Editor* editor = focused->editor();
+ if (!editor || !editor->canEdit())
+ return;
+
+ switch (direction) {
+ case WebTextDirectionDefault:
+ editor->setBaseWritingDirection(NaturalWritingDirection);
+ break;
+
+ case WebTextDirectionLeftToRight:
+ editor->setBaseWritingDirection(LeftToRightWritingDirection);
+ break;
+
+ case WebTextDirectionRightToLeft:
+ editor->setBaseWritingDirection(RightToLeftWritingDirection);
+ break;
+
+ default:
+ notImplemented();
+ break;
+ }
+}
+
+// WebView --------------------------------------------------------------------
+
+WebSettings* WebViewImpl::settings()
+{
+ if (!m_webSettings.get())
+ m_webSettings.set(new WebSettingsImpl(m_page->settings()));
+ ASSERT(m_webSettings.get());
+ return m_webSettings.get();
+}
+
+WebString WebViewImpl::pageEncoding() const
+{
+ if (!m_page.get())
+ return WebString();
+
+ return m_page->mainFrame()->loader()->encoding();
+}
+
+void WebViewImpl::setPageEncoding(const WebString& encodingName)
+{
+ if (!m_page.get())
+ return;
+
+ // Only change override encoding, don't change default encoding.
+ // Note that the new encoding must be 0 if it isn't supposed to be set.
+ String newEncodingName;
+ if (!encodingName.isEmpty())
+ newEncodingName = encodingName;
+ m_page->mainFrame()->loader()->reloadWithOverrideEncoding(newEncodingName);
+}
+
+bool WebViewImpl::dispatchBeforeUnloadEvent()
+{
+ // FIXME: This should really cause a recursive depth-first walk of all
+ // frames in the tree, calling each frame's onbeforeunload. At the moment,
+ // we're consistent with Safari 3.1, not IE/FF.
+ Frame* frame = m_page->focusController()->focusedOrMainFrame();
+ if (!frame)
+ return true;
+
+ return frame->shouldClose();
+}
+
+void WebViewImpl::dispatchUnloadEvent()
+{
+ // Run unload handlers.
+ m_page->mainFrame()->loader()->closeURL();
+}
+
+WebFrame* WebViewImpl::mainFrame()
+{
+ return mainFrameImpl();
+}
+
+WebFrame* WebViewImpl::findFrameByName(
+ const WebString& name, WebFrame* relativeToFrame)
+{
+ if (!relativeToFrame)
+ relativeToFrame = mainFrame();
+ Frame* frame = static_cast<WebFrameImpl*>(relativeToFrame)->frame();
+ frame = frame->tree()->find(name);
+ return WebFrameImpl::fromFrame(frame);
+}
+
+WebFrame* WebViewImpl::focusedFrame()
+{
+ return WebFrameImpl::fromFrame(focusedWebCoreFrame());
+}
+
+void WebViewImpl::setFocusedFrame(WebFrame* frame)
+{
+ if (!frame) {
+ // Clears the focused frame if any.
+ Frame* frame = focusedWebCoreFrame();
+ if (frame)
+ frame->selection()->setFocused(false);
+ return;
+ }
+ WebFrameImpl* frameImpl = static_cast<WebFrameImpl*>(frame);
+ Frame* webcoreFrame = frameImpl->frame();
+ webcoreFrame->page()->focusController()->setFocusedFrame(webcoreFrame);
+}
+
+void WebViewImpl::setInitialFocus(bool reverse)
+{
+ if (!m_page.get())
+ return;
+
+ // Since we don't have a keyboard event, we'll create one.
+ WebKeyboardEvent keyboardEvent;
+ keyboardEvent.type = WebInputEvent::RawKeyDown;
+ if (reverse)
+ keyboardEvent.modifiers = WebInputEvent::ShiftKey;
+
+ // VK_TAB which is only defined on Windows.
+ keyboardEvent.windowsKeyCode = 0x09;
+ PlatformKeyboardEventBuilder platformEvent(keyboardEvent);
+ RefPtr<KeyboardEvent> webkitEvent = KeyboardEvent::create(platformEvent, 0);
+ page()->focusController()->setInitialFocus(
+ reverse ? FocusDirectionBackward : FocusDirectionForward,
+ webkitEvent.get());
+}
+
+void WebViewImpl::clearFocusedNode()
+{
+ if (!m_page.get())
+ return;
+
+ RefPtr<Frame> frame = m_page->mainFrame();
+ if (!frame.get())
+ return;
+
+ RefPtr<Document> document = frame->document();
+ if (!document.get())
+ return;
+
+ RefPtr<Node> oldFocusedNode = document->focusedNode();
+
+ // Clear the focused node.
+ document->setFocusedNode(0);
+
+ if (!oldFocusedNode.get())
+ return;
+
+ // If a text field has focus, we need to make sure the selection controller
+ // knows to remove selection from it. Otherwise, the text field is still
+ // processing keyboard events even though focus has been moved to the page and
+ // keystrokes get eaten as a result.
+ if (oldFocusedNode->hasTagName(HTMLNames::textareaTag)
+ || (oldFocusedNode->hasTagName(HTMLNames::inputTag)
+ && static_cast<HTMLInputElement*>(oldFocusedNode.get())->isTextField())) {
+ // Clear the selection.
+ SelectionController* selection = frame->selection();
+ selection->clear();
+ }
+}
+
+void WebViewImpl::zoomIn(bool textOnly)
+{
+ Frame* frame = mainFrameImpl()->frame();
+ double multiplier = std::min(std::pow(textSizeMultiplierRatio, m_zoomLevel + 1),
+ maxTextSizeMultiplier);
+ float zoomFactor = static_cast<float>(multiplier);
+ if (zoomFactor != frame->zoomFactor()) {
+ ++m_zoomLevel;
+ frame->setZoomFactor(zoomFactor, textOnly);
+ }
+}
+
+void WebViewImpl::zoomOut(bool textOnly)
+{
+ Frame* frame = mainFrameImpl()->frame();
+ double multiplier = std::max(std::pow(textSizeMultiplierRatio, m_zoomLevel - 1),
+ minTextSizeMultiplier);
+ float zoomFactor = static_cast<float>(multiplier);
+ if (zoomFactor != frame->zoomFactor()) {
+ --m_zoomLevel;
+ frame->setZoomFactor(zoomFactor, textOnly);
+ }
+}
+
+void WebViewImpl::zoomDefault()
+{
+ // We don't change the zoom mode (text only vs. full page) here. We just want
+ // to reset whatever is already set.
+ m_zoomLevel = 0;
+ mainFrameImpl()->frame()->setZoomFactor(
+ 1.0f, mainFrameImpl()->frame()->isZoomFactorTextOnly());
+}
+
+void WebViewImpl::performMediaPlayerAction(const WebMediaPlayerAction& action,
+ const WebPoint& location)
+{
+ HitTestResult result =
+ hitTestResultForWindowPos(location);
+ RefPtr<Node> node = result.innerNonSharedNode();
+ if (!node->hasTagName(HTMLNames::videoTag) && !node->hasTagName(HTMLNames::audioTag))
+ return;
+
+ RefPtr<HTMLMediaElement> mediaElement =
+ static_pointer_cast<HTMLMediaElement>(node);
+ switch (action.type) {
+ case WebMediaPlayerAction::Play:
+ if (action.enable)
+ mediaElement->play();
+ else
+ mediaElement->pause();
+ break;
+ case WebMediaPlayerAction::Mute:
+ mediaElement->setMuted(action.enable);
+ break;
+ case WebMediaPlayerAction::Loop:
+ mediaElement->setLoop(action.enable);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void WebViewImpl::copyImageAt(const WebPoint& point)
+{
+ if (!m_page.get())
+ return;
+
+ HitTestResult result = hitTestResultForWindowPos(point);
+
+ if (result.absoluteImageURL().isEmpty()) {
+ // There isn't actually an image at these coordinates. Might be because
+ // the window scrolled while the context menu was open or because the page
+ // changed itself between when we thought there was an image here and when
+ // we actually tried to retreive the image.
+ //
+ // FIXME: implement a cache of the most recent HitTestResult to avoid having
+ // to do two hit tests.
+ return;
+ }
+
+ m_page->mainFrame()->editor()->copyImage(result);
+}
+
+void WebViewImpl::dragSourceEndedAt(
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint,
+ WebDragOperation operation)
+{
+ PlatformMouseEvent pme(clientPoint,
+ screenPoint,
+ LeftButton, MouseEventMoved, 0, false, false, false,
+ false, 0);
+ m_page->mainFrame()->eventHandler()->dragSourceEndedAt(pme,
+ static_cast<DragOperation>(operation));
+}
+
+void WebViewImpl::dragSourceMovedTo(
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint)
+{
+ PlatformMouseEvent pme(clientPoint,
+ screenPoint,
+ LeftButton, MouseEventMoved, 0, false, false, false,
+ false, 0);
+ m_page->mainFrame()->eventHandler()->dragSourceMovedTo(pme);
+}
+
+void WebViewImpl::dragSourceSystemDragEnded()
+{
+ // It's possible for us to get this callback while not doing a drag if
+ // it's from a previous page that got unloaded.
+ if (m_doingDragAndDrop) {
+ m_page->dragController()->dragEnded();
+ m_doingDragAndDrop = false;
+ }
+}
+
+WebDragOperation WebViewImpl::dragTargetDragEnter(
+ const WebDragData& webDragData, int identity,
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint,
+ WebDragOperationsMask operationsAllowed)
+{
+ ASSERT(!m_currentDragData.get());
+
+ m_currentDragData = webDragData;
+ m_dragIdentity = identity;
+ m_operationsAllowed = operationsAllowed;
+
+ DragData dragData(
+ m_currentDragData.get(),
+ clientPoint,
+ screenPoint,
+ static_cast<DragOperation>(operationsAllowed));
+
+ m_dropEffect = DropEffectDefault;
+ m_dragTargetDispatch = true;
+ DragOperation effect = m_page->dragController()->dragEntered(&dragData);
+ // Mask the operation against the drag source's allowed operations.
+ if ((effect & dragData.draggingSourceOperationMask()) != effect)
+ effect = DragOperationNone;
+ m_dragTargetDispatch = false;
+
+ if (m_dropEffect != DropEffectDefault) {
+ m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy
+ : WebDragOperationNone;
+ } else
+ m_dragOperation = static_cast<WebDragOperation>(effect);
+ return m_dragOperation;
+}
+
+WebDragOperation WebViewImpl::dragTargetDragOver(
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint,
+ WebDragOperationsMask operationsAllowed)
+{
+ ASSERT(m_currentDragData.get());
+
+ m_operationsAllowed = operationsAllowed;
+ DragData dragData(
+ m_currentDragData.get(),
+ clientPoint,
+ screenPoint,
+ static_cast<DragOperation>(operationsAllowed));
+
+ m_dropEffect = DropEffectDefault;
+ m_dragTargetDispatch = true;
+ DragOperation effect = m_page->dragController()->dragUpdated(&dragData);
+ // Mask the operation against the drag source's allowed operations.
+ if ((effect & dragData.draggingSourceOperationMask()) != effect)
+ effect = DragOperationNone;
+ m_dragTargetDispatch = false;
+
+ if (m_dropEffect != DropEffectDefault) {
+ m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy
+ : WebDragOperationNone;
+ } else
+ m_dragOperation = static_cast<WebDragOperation>(effect);
+ return m_dragOperation;
+}
+
+void WebViewImpl::dragTargetDragLeave()
+{
+ ASSERT(m_currentDragData.get());
+
+ DragData dragData(
+ m_currentDragData.get(),
+ IntPoint(),
+ IntPoint(),
+ static_cast<DragOperation>(m_operationsAllowed));
+
+ m_dragTargetDispatch = true;
+ m_page->dragController()->dragExited(&dragData);
+ m_dragTargetDispatch = false;
+
+ m_currentDragData = 0;
+ m_dropEffect = DropEffectDefault;
+ m_dragOperation = WebDragOperationNone;
+ m_dragIdentity = 0;
+}
+
+void WebViewImpl::dragTargetDrop(const WebPoint& clientPoint,
+ const WebPoint& screenPoint)
+{
+ ASSERT(m_currentDragData.get());
+
+ // If this webview transitions from the "drop accepting" state to the "not
+ // accepting" state, then our IPC message reply indicating that may be in-
+ // flight, or else delayed by javascript processing in this webview. If a
+ // drop happens before our IPC reply has reached the browser process, then
+ // the browser forwards the drop to this webview. So only allow a drop to
+ // proceed if our webview m_dragOperation state is not DragOperationNone.
+
+ if (m_dragOperation == WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop.
+ dragTargetDragLeave();
+ return;
+ }
+
+ DragData dragData(
+ m_currentDragData.get(),
+ clientPoint,
+ screenPoint,
+ static_cast<DragOperation>(m_operationsAllowed));
+
+ m_dragTargetDispatch = true;
+ m_page->dragController()->performDrag(&dragData);
+ m_dragTargetDispatch = false;
+
+ m_currentDragData = 0;
+ m_dropEffect = DropEffectDefault;
+ m_dragOperation = WebDragOperationNone;
+ m_dragIdentity = 0;
+}
+
+int WebViewImpl::dragIdentity()
+{
+ if (m_dragTargetDispatch)
+ return m_dragIdentity;
+ return 0;
+}
+
+void WebViewImpl::inspectElementAt(const WebPoint& point)
+{
+ if (!m_page.get())
+ return;
+
+ if (point.x == -1 || point.y == -1)
+ m_page->inspectorController()->inspect(0);
+ else {
+ HitTestResult result = hitTestResultForWindowPos(point);
+
+ if (!result.innerNonSharedNode())
+ return;
+
+ m_page->inspectorController()->inspect(result.innerNonSharedNode());
+ }
+}
+
+WebString WebViewImpl::inspectorSettings() const
+{
+ return m_inspectorSettings;
+}
+
+void WebViewImpl::setInspectorSettings(const WebString& settings)
+{
+ m_inspectorSettings = settings;
+}
+
+WebDevToolsAgent* WebViewImpl::devToolsAgent()
+{
+ return m_devToolsAgent.get();
+}
+
+WebAccessibilityObject WebViewImpl::accessibilityObject()
+{
+ if (!mainFrameImpl())
+ return WebAccessibilityObject();
+
+ Document* document = mainFrameImpl()->frame()->document();
+ return WebAccessibilityObject(
+ document->axObjectCache()->getOrCreate(document->renderer()));
+}
+
+void WebViewImpl::applyAutofillSuggestions(
+ const WebNode& node,
+ const WebVector<WebString>& suggestions,
+ int defaultSuggestionIndex)
+{
+ if (!m_page.get() || suggestions.isEmpty()) {
+ hideAutoCompletePopup();
+ return;
+ }
+
+ ASSERT(defaultSuggestionIndex < static_cast<int>(suggestions.size()));
+
+ if (RefPtr<Frame> focused = m_page->focusController()->focusedFrame()) {
+ RefPtr<Document> document = focused->document();
+ if (!document.get()) {
+ hideAutoCompletePopup();
+ return;
+ }
+
+ RefPtr<Node> focusedNode = document->focusedNode();
+ // If the node for which we queried the autofill suggestions is not the
+ // focused node, then we have nothing to do. FIXME: also check the
+ // carret is at the end and that the text has not changed.
+ if (!focusedNode.get() || focusedNode != PassRefPtr<Node>(node)) {
+ hideAutoCompletePopup();
+ return;
+ }
+
+ if (!focusedNode->hasTagName(HTMLNames::inputTag)) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ HTMLInputElement* inputElem =
+ static_cast<HTMLInputElement*>(focusedNode.get());
+
+ // The first time the autocomplete is shown we'll create the client and the
+ // popup.
+ if (!m_autocompletePopupClient.get())
+ m_autocompletePopupClient.set(new AutocompletePopupMenuClient(this));
+ m_autocompletePopupClient->initialize(inputElem,
+ suggestions,
+ defaultSuggestionIndex);
+ if (!m_autocompletePopup.get()) {
+ m_autocompletePopup =
+ PopupContainer::create(m_autocompletePopupClient.get(),
+ autocompletePopupSettings);
+ }
+
+ if (m_autocompletePopupShowing) {
+ m_autocompletePopupClient->setSuggestions(suggestions);
+ refreshAutofillPopup();
+ } else {
+ m_autocompletePopup->show(focusedNode->getRect(),
+ focusedNode->ownerDocument()->view(), 0);
+ m_autocompletePopupShowing = true;
+ }
+ }
+}
+
+void WebViewImpl::hideAutofillPopup()
+{
+ hideAutoCompletePopup();
+}
+
+// WebView --------------------------------------------------------------------
+
+bool WebViewImpl::setDropEffect(bool accept) {
+ if (m_dragTargetDispatch) {
+ m_dropEffect = accept ? DropEffectCopy : DropEffectNone;
+ return true;
+ }
+ return false;
+}
+
+WebDevToolsAgentImpl* WebViewImpl::devToolsAgentImpl()
+{
+ return m_devToolsAgent.get();
+}
+
+void WebViewImpl::setIsTransparent(bool isTransparent)
+{
+ // Set any existing frames to be transparent.
+ Frame* frame = m_page->mainFrame();
+ while (frame) {
+ frame->view()->setTransparent(isTransparent);
+ frame = frame->tree()->traverseNext();
+ }
+
+ // Future frames check this to know whether to be transparent.
+ m_isTransparent = isTransparent;
+}
+
+bool WebViewImpl::isTransparent() const
+{
+ return m_isTransparent;
+}
+
+void WebViewImpl::setIsActive(bool active)
+{
+ if (page() && page()->focusController())
+ page()->focusController()->setActive(active);
+}
+
+bool WebViewImpl::isActive() const
+{
+ return (page() && page()->focusController()) ? page()->focusController()->isActive() : false;
+}
+
+void WebViewImpl::didCommitLoad(bool* isNewNavigation)
+{
+ if (isNewNavigation)
+ *isNewNavigation = m_observedNewNavigation;
+
+#ifndef NDEBUG
+ ASSERT(!m_observedNewNavigation
+ || m_page->mainFrame()->loader()->documentLoader() == m_newNavigationLoader);
+ m_newNavigationLoader = 0;
+#endif
+ m_observedNewNavigation = false;
+}
+
+bool WebViewImpl::navigationPolicyFromMouseEvent(unsigned short button,
+ bool ctrl, bool shift,
+ bool alt, bool meta,
+ WebNavigationPolicy* policy)
+{
+#if PLATFORM(WIN_OS) || PLATFORM(LINUX) || PLATFORM(FREEBSD)
+ const bool newTabModifier = (button == 1) || ctrl;
+#elif PLATFORM(DARWIN)
+ const bool newTabModifier = (button == 1) || meta;
+#endif
+ if (!newTabModifier && !shift && !alt)
+ return false;
+
+ ASSERT(policy);
+ if (newTabModifier) {
+ if (shift)
+ *policy = WebNavigationPolicyNewForegroundTab;
+ else
+ *policy = WebNavigationPolicyNewBackgroundTab;
+ } else {
+ if (shift)
+ *policy = WebNavigationPolicyNewWindow;
+ else
+ *policy = WebNavigationPolicyDownload;
+ }
+ return true;
+}
+
+void WebViewImpl::startDragging(const WebPoint& eventPos,
+ const WebDragData& dragData,
+ WebDragOperationsMask mask)
+{
+ if (!m_client)
+ return;
+ ASSERT(!m_doingDragAndDrop);
+ m_doingDragAndDrop = true;
+ m_client->startDragging(eventPos, dragData, mask);
+}
+
+void WebViewImpl::setCurrentHistoryItem(HistoryItem* item)
+{
+ m_backForwardListClientImpl.setCurrentHistoryItem(item);
+}
+
+HistoryItem* WebViewImpl::previousHistoryItem()
+{
+ return m_backForwardListClientImpl.previousHistoryItem();
+}
+
+void WebViewImpl::observeNewNavigation()
+{
+ m_observedNewNavigation = true;
+#ifndef NDEBUG
+ m_newNavigationLoader = m_page->mainFrame()->loader()->documentLoader();
+#endif
+}
+
+void WebViewImpl::hideAutoCompletePopup()
+{
+ if (m_autocompletePopupShowing) {
+ m_autocompletePopup->hidePopup();
+ autoCompletePopupDidHide();
+ }
+}
+
+void WebViewImpl::autoCompletePopupDidHide()
+{
+ m_autocompletePopupShowing = false;
+}
+
+void WebViewImpl::setIgnoreInputEvents(bool newValue)
+{
+ ASSERT(m_ignoreInputEvents != newValue);
+ m_ignoreInputEvents = newValue;
+}
+
+#if ENABLE(NOTIFICATIONS)
+NotificationPresenterImpl* WebViewImpl::notificationPresenterImpl()
+{
+ if (!m_notificationPresenter.isInitialized() && m_client)
+ m_notificationPresenter.initialize(m_client->notificationPresenter());
+ return &m_notificationPresenter;
+}
+#endif
+
+void WebViewImpl::refreshAutofillPopup() {
+ ASSERT(m_autocompletePopupShowing);
+
+ // Hide the popup if it has become empty.
+ if (m_autocompletePopupClient->listSize() == 0) {
+ hideAutoCompletePopup();
+ return;
+ }
+
+ IntRect oldBounds = m_autocompletePopup->boundsRect();
+ m_autocompletePopup->refresh();
+ IntRect newBounds = m_autocompletePopup->boundsRect();
+ // Let's resize the backing window if necessary.
+ if (oldBounds != newBounds) {
+ WebPopupMenuImpl* popupMenu =
+ static_cast<WebPopupMenuImpl*>(m_autocompletePopup->client());
+ popupMenu->client()->setWindowRect(newBounds);
+ }
+}
+
+Node* WebViewImpl::focusedWebCoreNode()
+{
+ Frame* frame = m_page->focusController()->focusedFrame();
+ if (!frame)
+ return 0;
+
+ Document* document = frame->document();
+ if (!document)
+ return 0;
+
+ return document->focusedNode();
+}
+
+HitTestResult WebViewImpl::hitTestResultForWindowPos(const IntPoint& pos)
+{
+ IntPoint docPoint(m_page->mainFrame()->view()->windowToContents(pos));
+ return m_page->mainFrame()->eventHandler()->hitTestResultAtPoint(docPoint, false);
+}
+
+void WebViewImpl::setTabsToLinks(bool enable)
+{
+ m_tabsToLinks = enable;
+}
+
+bool WebViewImpl::tabsToLinks() const
+{
+ return m_tabsToLinks;
+}
+
+} // namespace WebKit
diff --git a/webkit/api/src/WebViewImpl.h b/webkit/api/src/WebViewImpl.h
new file mode 100644
index 0000000..7f99256
--- /dev/null
+++ b/webkit/api/src/WebViewImpl.h
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebViewImpl_h
+#define WebViewImpl_h
+
+#include "BackForwardListClientImpl.h"
+#include "ChromeClientImpl.h"
+#include "ContextMenuClientImpl.h"
+#include "DragClientImpl.h"
+#include "EditorClientImpl.h"
+#include "InspectorClientImpl.h"
+#include "NotificationPresenterImpl.h"
+// FIXME: remove this relative path once consumers from glue are removed.
+#include "../public/WebNavigationPolicy.h"
+#include "../public/WebPoint.h"
+#include "../public/WebSize.h"
+#include "../public/WebString.h"
+#include "../public/WebView.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+class ChromiumDataObject;
+class Frame;
+class HistoryItem;
+class HitTestResult;
+class KeyboardEvent;
+class Page;
+class PlatformKeyboardEvent;
+class PopupContainer;
+class Range;
+class RenderTheme;
+class Widget;
+}
+
+class WebDevToolsAgentImpl;
+
+namespace WebKit {
+class AutocompletePopupMenuClient;
+class ContextMenuClientImpl;
+class WebAccessibilityObject;
+class WebFrameImpl;
+class WebKeyboardEvent;
+class WebMouseEvent;
+class WebMouseWheelEvent;
+class WebSettingsImpl;
+
+class WebViewImpl : public WebView, public RefCounted<WebViewImpl> {
+public:
+ // WebWidget methods:
+ virtual void close();
+ virtual WebSize size() { return m_size; }
+ virtual void resize(const WebSize&);
+ virtual void layout();
+ virtual void paint(WebCanvas*, const WebRect&);
+ virtual bool handleInputEvent(const WebInputEvent&);
+ virtual void mouseCaptureLost();
+ virtual void setFocus(bool enable);
+ virtual bool handleCompositionEvent(WebCompositionCommand command,
+ int cursorPosition,
+ int targetStart,
+ int targetEnd,
+ const WebString& text);
+ virtual bool queryCompositionStatus(bool* enabled,
+ WebRect* caretRect);
+ virtual void setTextDirection(WebTextDirection direction);
+
+ // WebView methods:
+ virtual void initializeMainFrame(WebFrameClient*);
+ virtual WebSettings* settings();
+ virtual WebString pageEncoding() const;
+ virtual void setPageEncoding(const WebString& encoding);
+ virtual bool isTransparent() const;
+ virtual void setIsTransparent(bool value);
+ virtual bool tabsToLinks() const;
+ virtual void setTabsToLinks(bool value);
+ virtual bool tabKeyCyclesThroughElements() const;
+ virtual void setTabKeyCyclesThroughElements(bool value);
+ virtual bool isActive() const;
+ virtual void setIsActive(bool value);
+ virtual bool dispatchBeforeUnloadEvent();
+ virtual void dispatchUnloadEvent();
+ virtual WebFrame* mainFrame();
+ virtual WebFrame* findFrameByName(
+ const WebString& name, WebFrame* relativeToFrame);
+ virtual WebFrame* focusedFrame();
+ virtual void setFocusedFrame(WebFrame* frame);
+ virtual void setInitialFocus(bool reverse);
+ virtual void clearFocusedNode();
+ virtual void zoomIn(bool textOnly);
+ virtual void zoomOut(bool textOnly);
+ virtual void zoomDefault();
+ virtual void performMediaPlayerAction(
+ const WebMediaPlayerAction& action,
+ const WebPoint& location);
+ virtual void copyImageAt(const WebPoint& point);
+ virtual void dragSourceEndedAt(
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint,
+ WebDragOperation operation);
+ virtual void dragSourceMovedTo(
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint);
+ virtual void dragSourceSystemDragEnded();
+ virtual WebDragOperation dragTargetDragEnter(
+ const WebDragData& dragData, int identity,
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint,
+ WebDragOperationsMask operationsAllowed);
+ virtual WebDragOperation dragTargetDragOver(
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint,
+ WebDragOperationsMask operationsAllowed);
+ virtual void dragTargetDragLeave();
+ virtual void dragTargetDrop(
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint);
+ virtual int dragIdentity();
+ virtual bool setDropEffect(bool accept);
+ virtual void inspectElementAt(const WebPoint& point);
+ virtual WebString inspectorSettings() const;
+ virtual void setInspectorSettings(const WebString& settings);
+ virtual WebDevToolsAgent* devToolsAgent();
+ virtual WebAccessibilityObject accessibilityObject();
+ virtual void applyAutofillSuggestions(
+ const WebNode&,
+ const WebVector<WebString>& suggestions,
+ int defaultSuggestionIndex);
+ virtual void hideAutofillPopup();
+
+ // WebViewImpl
+
+ void setIgnoreInputEvents(bool newValue);
+ WebDevToolsAgentImpl* devToolsAgentImpl();
+
+ const WebPoint& lastMouseDownPoint() const
+ {
+ return m_lastMouseDownPoint;
+ }
+
+ WebCore::Frame* focusedWebCoreFrame();
+
+ // Returns the currently focused Node or null if no node has focus.
+ WebCore::Node* focusedWebCoreNode();
+
+ static WebViewImpl* fromPage(WebCore::Page*);
+
+ WebViewClient* client()
+ {
+ return m_client;
+ }
+
+ // Returns the page object associated with this view. This may be null when
+ // the page is shutting down, but will be valid at all other times.
+ WebCore::Page* page() const
+ {
+ return m_page.get();
+ }
+
+ WebCore::RenderTheme* theme() const;
+
+ // Returns the main frame associated with this view. This may be null when
+ // the page is shutting down, but will be valid at all other times.
+ WebFrameImpl* mainFrameImpl();
+
+ // History related methods:
+ void setCurrentHistoryItem(WebCore::HistoryItem*);
+ WebCore::HistoryItem* previousHistoryItem();
+ void observeNewNavigation();
+
+ // Event related methods:
+ void mouseMove(const WebMouseEvent&);
+ void mouseLeave(const WebMouseEvent&);
+ void mouseDown(const WebMouseEvent&);
+ void mouseUp(const WebMouseEvent&);
+ void mouseContextMenu(const WebMouseEvent&);
+ void mouseDoubleClick(const WebMouseEvent&);
+ void mouseWheel(const WebMouseWheelEvent&);
+ bool keyEvent(const WebKeyboardEvent&);
+ bool charEvent(const WebKeyboardEvent&);
+
+ // Handles context menu events orignated via the the keyboard. These
+ // include the VK_APPS virtual key and the Shift+F10 combine. Code is
+ // based on the Webkit function bool WebView::handleContextMenuEvent(WPARAM
+ // wParam, LPARAM lParam) in webkit\webkit\win\WebView.cpp. The only
+ // significant change in this function is the code to convert from a
+ // Keyboard event to the Right Mouse button down event.
+ bool sendContextMenuEvent(const WebKeyboardEvent&);
+
+ // Notifies the WebView that a load has been committed. isNewNavigation
+ // will be true if a new session history item should be created for that
+ // load.
+ void didCommitLoad(bool* isNewNavigation);
+
+ bool contextMenuAllowed() const
+ {
+ return m_contextMenuAllowed;
+ }
+
+ // Set the disposition for how this webview is to be initially shown.
+ void setInitialNavigationPolicy(WebNavigationPolicy policy)
+ {
+ m_initialNavigationPolicy = policy;
+ }
+ WebNavigationPolicy initialNavigationPolicy() const
+ {
+ return m_initialNavigationPolicy;
+ }
+
+ // Determines whether a page should e.g. be opened in a background tab.
+ // Returns false if it has no opinion, in which case it doesn't set *policy.
+ static bool navigationPolicyFromMouseEvent(
+ unsigned short button,
+ bool ctrl,
+ bool shift,
+ bool alt,
+ bool meta,
+ WebNavigationPolicy*);
+
+ // Start a system drag and drop operation.
+ void startDragging(
+ const WebPoint& eventPos,
+ const WebDragData& dragData,
+ WebDragOperationsMask dragSourceOperationMask);
+
+ // Hides the autocomplete popup if it is showing.
+ void hideAutoCompletePopup();
+ void autoCompletePopupDidHide();
+
+#if ENABLE(NOTIFICATIONS)
+ // Returns the provider of desktop notifications.
+ NotificationPresenterImpl* notificationPresenterImpl();
+#endif
+
+ // Tries to scroll a frame or any parent of a frame. Returns true if the view
+ // was scrolled.
+ bool propagateScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity);
+
+ // HACK: currentInputEvent() is for ChromeClientImpl::show(), until we can
+ // fix WebKit to pass enough information up into ChromeClient::show() so we
+ // can decide if the window.open event was caused by a middle-mouse click
+ static const WebInputEvent* currentInputEvent()
+ {
+ return m_currentInputEvent;
+ }
+
+private:
+ friend class WebView; // So WebView::Create can call our constructor
+ friend class WTF::RefCounted<WebViewImpl>;
+
+ WebViewImpl(WebViewClient* client);
+ ~WebViewImpl();
+
+ void modifySelection(uint32 message, WebCore::Frame*, const WebCore::PlatformKeyboardEvent&);
+
+ // Returns true if the event was actually processed.
+ bool keyEventDefault(const WebKeyboardEvent&);
+
+ // Returns true if the autocomple has consumed the event.
+ bool autocompleteHandleKeyEvent(const WebKeyboardEvent&);
+
+ // Repaints the autofill popup. Should be called when the suggestions have
+ // changed. Note that this should only be called when the autofill popup is
+ // showing.
+ void refreshAutofillPopup();
+
+ // Returns true if the view was scrolled.
+ bool scrollViewWithKeyboard(int keyCode, int modifiers);
+
+ // Converts |pos| from window coordinates to contents coordinates and gets
+ // the HitTestResult for it.
+ WebCore::HitTestResult hitTestResultForWindowPos(const WebCore::IntPoint&);
+
+ WebViewClient* m_client;
+
+ BackForwardListClientImpl m_backForwardListClientImpl;
+ ChromeClientImpl m_chromeClientImpl;
+ ContextMenuClientImpl m_contextMenuClientImpl;
+ DragClientImpl m_dragClientImpl;
+ EditorClientImpl m_editorClientImpl;
+ InspectorClientImpl m_inspectorClientImpl;
+
+ WebSize m_size;
+
+ WebPoint m_lastMousePosition;
+ OwnPtr<WebCore::Page> m_page;
+
+ // This flag is set when a new navigation is detected. It is used to satisfy
+ // the corresponding argument to WebFrameClient::didCommitProvisionalLoad.
+ bool m_observedNewNavigation;
+#ifndef NDEBUG
+ // Used to assert that the new navigation we observed is the same navigation
+ // when we make use of m_observedNewNavigation.
+ const WebCore::DocumentLoader* m_newNavigationLoader;
+#endif
+
+ // An object that can be used to manipulate m_page->settings() without linking
+ // against WebCore. This is lazily allocated the first time GetWebSettings()
+ // is called.
+ OwnPtr<WebSettingsImpl> m_webSettings;
+
+ // A copy of the web drop data object we received from the browser.
+ RefPtr<WebCore::ChromiumDataObject> m_currentDragData;
+
+ // The point relative to the client area where the mouse was last pressed
+ // down. This is used by the drag client to determine what was under the
+ // mouse when the drag was initiated. We need to track this here in
+ // WebViewImpl since DragClient::startDrag does not pass the position the
+ // mouse was at when the drag was initiated, only the current point, which
+ // can be misleading as it is usually not over the element the user actually
+ // dragged by the time a drag is initiated.
+ WebPoint m_lastMouseDownPoint;
+
+ // Keeps track of the current text zoom level. 0 means no zoom, positive
+ // values mean larger text, negative numbers mean smaller.
+ int m_zoomLevel;
+
+ bool m_contextMenuAllowed;
+
+ bool m_doingDragAndDrop;
+
+ bool m_ignoreInputEvents;
+
+ // Webkit expects keyPress events to be suppressed if the associated keyDown
+ // event was handled. Safari implements this behavior by peeking out the
+ // associated WM_CHAR event if the keydown was handled. We emulate
+ // this behavior by setting this flag if the keyDown was handled.
+ bool m_suppressNextKeypressEvent;
+
+ // The policy for how this webview is to be initially shown.
+ WebNavigationPolicy m_initialNavigationPolicy;
+
+ // Represents whether or not this object should process incoming IME events.
+ bool m_imeAcceptEvents;
+
+ // True while dispatching system drag and drop events to drag/drop targets
+ // within this WebView.
+ bool m_dragTargetDispatch;
+
+ // Valid when m_dragTargetDispatch is true; the identity of the drag data
+ // copied from the WebDropData object sent from the browser process.
+ int32 m_dragIdentity;
+
+ // Valid when m_dragTargetDispatch is true. Used to override the default
+ // browser drop effect with the effects "none" or "copy".
+ enum DragTargetDropEffect {
+ DropEffectDefault = -1,
+ DropEffectNone,
+ DropEffectCopy
+ } m_dropEffect;
+
+ // The available drag operations (copy, move link...) allowed by the source.
+ WebDragOperation m_operationsAllowed;
+
+ // The current drag operation as negotiated by the source and destination.
+ // When not equal to DragOperationNone, the drag data can be dropped onto the
+ // current drop target in this WebView (the drop target can accept the drop).
+ WebDragOperation m_dragOperation;
+
+ // The autocomplete popup. Kept around and reused every-time new suggestions
+ // should be shown.
+ RefPtr<WebCore::PopupContainer> m_autocompletePopup;
+
+ // Whether the autocomplete popup is currently showing.
+ bool m_autocompletePopupShowing;
+
+ // The autocomplete client.
+ OwnPtr<AutocompletePopupMenuClient> m_autocompletePopupClient;
+
+ OwnPtr<WebDevToolsAgentImpl> m_devToolsAgent;
+
+ // Whether the webview is rendering transparently.
+ bool m_isTransparent;
+
+ // Whether the user can press tab to focus links.
+ bool m_tabsToLinks;
+
+ // Inspector settings.
+ WebString m_inspectorSettings;
+
+#if ENABLE(NOTIFICATIONS)
+ // The provider of desktop notifications;
+ NotificationPresenterImpl m_notificationPresenter;
+#endif
+
+ static const WebInputEvent* m_currentInputEvent;
+};
+
+} // namespace WebKit
+
+#endif
diff --git a/webkit/api/src/WebWorkerClientImpl.cpp b/webkit/api/src/WebWorkerClientImpl.cpp
index 16d7134..5e99b57 100644
--- a/webkit/api/src/WebWorkerClientImpl.cpp
+++ b/webkit/api/src/WebWorkerClientImpl.cpp
@@ -47,21 +47,19 @@
#include "WorkerContextExecutionProxy.h"
#include "WorkerMessagingProxy.h"
#include <wtf/Threading.h>
-#undef LOG
+#include "FrameLoaderClientImpl.h"
#include "PlatformMessagePortChannel.h"
#include "WebFrameClient.h"
+#include "WebFrameImpl.h"
#include "WebKit.h"
#include "WebKitClient.h"
#include "WebMessagePortChannel.h"
#include "WebString.h"
#include "WebURL.h"
+#include "WebViewImpl.h"
#include "WebWorker.h"
#include "WebWorkerImpl.h"
-// FIXME: remove the includes below
-#include "webkit/glue/webframeloaderclient_impl.h"
-#include "webkit/glue/webframe_impl.h"
-#include "webkit/glue/webview_impl.h"
using namespace WebCore;
@@ -93,7 +91,7 @@ WorkerContextProxy* WebWorkerClientImpl::createWorkerContextProxy(Worker* worker
if (worker->scriptExecutionContext()->isDocument()) {
Document* document = static_cast<Document*>(
worker->scriptExecutionContext());
- WebFrameImpl* webFrame = WebFrameImpl::FromFrame(document->frame());
+ WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
webWorker = webFrame->client()->createWorker(webFrame, proxy);
} else {
WorkerContextExecutionProxy* currentContext =
diff --git a/webkit/api/src/WebWorkerImpl.cpp b/webkit/api/src/WebWorkerImpl.cpp
index 8e6f6df..4028b71 100644
--- a/webkit/api/src/WebWorkerImpl.cpp
+++ b/webkit/api/src/WebWorkerImpl.cpp
@@ -48,14 +48,13 @@
#include "PlatformMessagePortChannel.h"
#include "WebDataSourceImpl.h"
#include "WebFrameClient.h"
+#include "WebFrameImpl.h"
#include "WebMessagePortChannel.h"
#include "WebScreenInfo.h"
#include "WebString.h"
#include "WebURL.h"
#include "WebView.h"
#include "WebWorkerClient.h"
-// FIXME: webframe should eventually move to api/src too.
-#include "webkit/glue/webframe_impl.h"
using namespace WebCore;
diff --git a/webkit/glue/devtools/debugger_agent_impl.cc b/webkit/glue/devtools/debugger_agent_impl.cc
index 9080869..a32b9a2 100644
--- a/webkit/glue/devtools/debugger_agent_impl.cc
+++ b/webkit/glue/devtools/debugger_agent_impl.cc
@@ -9,6 +9,7 @@
#include <wtf/Vector.h>
#include "Document.h"
+#include "Frame.h"
#include "Page.h"
#include "V8Binding.h"
#include "V8DOMWindow.h"
@@ -17,12 +18,12 @@
#undef LOG
#include "grit/webkit_resources.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdevtoolsagent_impl.h"
#include "webkit/glue/webkit_glue.h"
-#include "webkit/glue/webview_impl.h"
using WebCore::DOMWindow;
using WebCore::Document;
@@ -34,6 +35,7 @@ using WebCore::V8Custom;
using WebCore::V8DOMWindow;
using WebCore::V8DOMWrapper;
using WebCore::V8Proxy;
+using WebKit::WebViewImpl;
DebuggerAgentImpl::DebuggerAgentImpl(
WebViewImpl* web_view_impl,
diff --git a/webkit/glue/devtools/debugger_agent_impl.h b/webkit/glue/devtools/debugger_agent_impl.h
index 0659dd7..95ea2d8 100644
--- a/webkit/glue/devtools/debugger_agent_impl.h
+++ b/webkit/glue/devtools/debugger_agent_impl.h
@@ -12,7 +12,6 @@
#include "webkit/glue/devtools/debugger_agent.h"
class WebDevToolsAgentImpl;
-class WebViewImpl;
namespace WebCore {
class Document;
@@ -21,13 +20,17 @@ class Page;
class String;
}
+namespace WebKit {
+class WebViewImpl;
+}
+
class DebuggerAgentImpl : public DebuggerAgent {
public:
// Creates utility context with injected js agent.
static void CreateUtilityContext(WebCore::Frame* frame,
v8::Persistent<v8::Context>* context);
- DebuggerAgentImpl(WebViewImpl* web_view_impl,
+ DebuggerAgentImpl(WebKit::WebViewImpl* web_view_impl,
DebuggerAgentDelegate* delegate,
WebDevToolsAgentImpl* webdevtools_agent);
virtual ~DebuggerAgentImpl();
@@ -66,10 +69,10 @@ class DebuggerAgentImpl : public DebuggerAgent {
WebCore::Page* GetPage();
WebDevToolsAgentImpl* webdevtools_agent() { return webdevtools_agent_; };
- WebViewImpl* web_view() { return web_view_impl_; }
+ WebKit::WebViewImpl* web_view() { return web_view_impl_; }
private:
- WebViewImpl* web_view_impl_;
+ WebKit::WebViewImpl* web_view_impl_;
DebuggerAgentDelegate* delegate_;
WebDevToolsAgentImpl* webdevtools_agent_;
int profiler_log_position_;
diff --git a/webkit/glue/devtools/debugger_agent_manager.cc b/webkit/glue/devtools/debugger_agent_manager.cc
index edf6738..2cfb459 100644
--- a/webkit/glue/devtools/debugger_agent_manager.cc
+++ b/webkit/glue/devtools/debugger_agent_manager.cc
@@ -11,16 +11,19 @@
#undef LOG
#include "webkit/api/public/WebDevToolsAgent.h"
+#include "webkit/api/src/WebFrameImpl.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
#include "webkit/glue/webdevtoolsagent_impl.h"
-#include "webkit/glue/webview_impl.h"
#if USE(V8)
#include "v8/include/v8-debug.h"
#endif
using WebKit::WebDevToolsAgent;
+using WebKit::WebFrameImpl;
+using WebKit::WebViewImpl;
WebDevToolsAgent::MessageLoopDispatchHandler
DebuggerAgentManager::message_loop_dispatch_handler_ = NULL;
@@ -77,7 +80,7 @@ void DebuggerAgentManager::V8DebugHostDispatchHandler() {
agent->web_view(),
new WebCore::PageGroupLoadDeferrer(agent->GetPage(), true));
views.append(agent->web_view());
- agent->web_view()->SetIgnoreInputEvents(true);
+ agent->web_view()->setIgnoreInputEvents(true);
}
// 2. Process messages.
@@ -89,7 +92,7 @@ void DebuggerAgentManager::V8DebugHostDispatchHandler() {
++it) {
if (page_deferrers_.contains(*it)) {
// The view was not closed during the dispatch.
- (*it)->SetIgnoreInputEvents(false);
+ (*it)->setIgnoreInputEvents(false);
}
}
deleteAllValues(page_deferrers_);
diff --git a/webkit/glue/devtools/debugger_agent_manager.h b/webkit/glue/devtools/debugger_agent_manager.h
index 22a1f93..3d49ed7 100644
--- a/webkit/glue/devtools/debugger_agent_manager.h
+++ b/webkit/glue/devtools/debugger_agent_manager.h
@@ -15,10 +15,13 @@ namespace WebCore {
class PageGroupLoadDeferrer;
}
-class DebuggerAgentImpl;
-class DictionaryValue;
+namespace WebKit {
class WebFrameImpl;
class WebViewImpl;
+}
+
+class DebuggerAgentImpl;
+class DictionaryValue;
// There is single v8 instance per render process. Also there may be several
// RenderViews and consequently devtools agents in the process that want to talk
@@ -46,9 +49,9 @@ class DebuggerAgentManager : public Noncopyable {
// Sets |host_id| as the frame context data. This id is used to filter scripts
// related to the inspected page.
- static void SetHostId(WebFrameImpl* webframe, int host_id);
+ static void SetHostId(WebKit::WebFrameImpl* webframe, int host_id);
- static void OnWebViewClosed(WebViewImpl* webview);
+ static void OnWebViewClosed(WebKit::WebViewImpl* webview);
static void OnNavigate();
@@ -86,7 +89,7 @@ class DebuggerAgentManager : public Noncopyable {
static WebKit::WebDevToolsAgent::MessageLoopDispatchHandler
message_loop_dispatch_handler_;
static bool in_host_dispatch_handler_;
- typedef HashMap<WebViewImpl*, WebCore::PageGroupLoadDeferrer*>
+ typedef HashMap<WebKit::WebViewImpl*, WebCore::PageGroupLoadDeferrer*>
DeferrersMap;
static DeferrersMap page_deferrers_;
diff --git a/webkit/glue/dom_operations.cc b/webkit/glue/dom_operations.cc
index ba1e2bc..2b523d6 100644
--- a/webkit/glue/dom_operations.cc
+++ b/webkit/glue/dom_operations.cc
@@ -33,16 +33,18 @@ MSVC_POP_WARNING();
#include "base/string_util.h"
// TODO(yaar) Eventually should not depend on api/src.
#include "webkit/api/src/DOMUtilitiesPrivate.h"
+#include "webkit/api/src/WebFrameImpl.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/glue/dom_operations.h"
#include "webkit/glue/dom_operations_private.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/password_autocomplete_listener_impl.h"
-#include "webkit/glue/webframe_impl.h"
-#include "webkit/glue/webview_impl.h"
using WebCore::String;
+using WebKit::FrameLoaderClientImpl;
using WebKit::WebFrame;
+using WebKit::WebFrameImpl;
using WebKit::WebView;
namespace {
@@ -345,11 +347,11 @@ void FillPasswordForm(WebView* view,
WebCore::HTMLInputElement* password_element =
form_elements->input_elements[data.basic_data.elements[1]].get();
- WebFrameLoaderClient* frame_loader_client =
- static_cast<WebFrameLoaderClient*>(username_element->document()->
- frame()->loader()->client());
- WebFrameImpl* webframe_impl = frame_loader_client->webframe();
- webframe_impl->RegisterPasswordListener(
+ FrameLoaderClientImpl* frame_loader_client =
+ static_cast<FrameLoaderClientImpl*>(username_element->document()->
+ frame()->loader()->client());
+ WebFrameImpl* webframe_impl = frame_loader_client->webFrame();
+ webframe_impl->registerPasswordListener(
username_element,
new PasswordAutocompleteListenerImpl(
new HTMLInputDelegate(username_element),
@@ -369,7 +371,7 @@ WebFrameImpl* GetWebFrameImplFromElement(WebCore::Element* element,
WebCore::HTMLFrameOwnerElement* frame_element =
static_cast<WebCore::HTMLFrameOwnerElement*>(element);
WebCore::Frame* content_frame = frame_element->contentFrame();
- return WebFrameImpl::FromFrame(content_frame);
+ return WebFrameImpl::fromFrame(content_frame);
}
}
return NULL;
diff --git a/webkit/glue/dom_operations.h b/webkit/glue/dom_operations.h
index af61698..e0d7142 100644
--- a/webkit/glue/dom_operations.h
+++ b/webkit/glue/dom_operations.h
@@ -17,7 +17,6 @@ class WebView;
}
struct FormData;
-class WebFrameImpl;
// A collection of operations that access the underlying WebKit DOM directly.
namespace webkit_glue {
diff --git a/webkit/glue/dom_operations_private.h b/webkit/glue/dom_operations_private.h
index 69676f4..403ca16 100644
--- a/webkit/glue/dom_operations_private.h
+++ b/webkit/glue/dom_operations_private.h
@@ -15,11 +15,11 @@ class String;
}
namespace WebKit {
+class WebFrameImpl;
class WebView;
}
class GURL;
-class WebFrameImpl;
namespace webkit_glue {
@@ -27,8 +27,8 @@ namespace webkit_glue {
// object corresponding to the content frame, otherwise return NULL.
// The parameter is_frame_element indicates whether the input element
// is frame/iframe element or not.
-WebFrameImpl* GetWebFrameImplFromElement(WebCore::Element* element,
- bool* is_frame_element);
+WebKit::WebFrameImpl* GetWebFrameImplFromElement(WebCore::Element* element,
+ bool* is_frame_element);
// If element is img, script or input type=image, then return its link refer
// to the "src" attribute. If element is link, then return its link refer to
@@ -50,8 +50,8 @@ bool ElementHasLegalLinkAttribute(const WebCore::Element* element,
const WebCore::QualifiedName& attr_name);
// Get pointer of WebFrameImpl from webview according to specific URL.
-WebFrameImpl* GetWebFrameImplFromWebViewForSpecificURL(WebKit::WebView* view,
- const GURL& page_url);
+WebKit::WebFrameImpl* GetWebFrameImplFromWebViewForSpecificURL(
+ WebKit::WebView* view, const GURL& page_url);
} // namespace webkit_glue
diff --git a/webkit/glue/dom_serializer.cc b/webkit/glue/dom_serializer.cc
index a4a0683..b3c7b28 100644
--- a/webkit/glue/dom_serializer.cc
+++ b/webkit/glue/dom_serializer.cc
@@ -73,14 +73,15 @@ MSVC_POP_WARNING();
#include "webkit/glue/dom_serializer.h"
#include "base/string_util.h"
+#include "webkit/api/src/WebFrameImpl.h"
#include "webkit/glue/dom_operations.h"
#include "webkit/glue/dom_operations_private.h"
#include "webkit/glue/dom_serializer_delegate.h"
#include "webkit/glue/entity_map.h"
#include "webkit/glue/glue_util.h"
-#include "webkit/glue/webframe_impl.h"
using WebKit::WebFrame;
+using WebKit::WebFrameImpl;
namespace {
diff --git a/webkit/glue/dom_serializer.h b/webkit/glue/dom_serializer.h
index 3c59760..3c70431 100644
--- a/webkit/glue/dom_serializer.h
+++ b/webkit/glue/dom_serializer.h
@@ -11,8 +11,6 @@
#include "base/hash_tables.h"
#include "googleurl/src/gurl.h"
-class WebFrameImpl;
-
namespace WebCore {
class Document;
class Element;
@@ -23,6 +21,7 @@ class TextEncoding;
namespace WebKit {
class WebFrame;
+class WebFrameImpl;
}
namespace webkit_glue {
@@ -71,7 +70,7 @@ class DomSerializer {
private:
// Specified frame which need to be serialized;
- WebFrameImpl* specified_webframeimpl_;
+ WebKit::WebFrameImpl* specified_webframeimpl_;
// This hash_map is used to map resource URL of original link to its local
// file path.
typedef base::hash_map<std::string, FilePath> LinkLocalPathMap;
@@ -92,7 +91,7 @@ class DomSerializer {
// Local directory name of all local resource files.
const FilePath& local_directory_name_;
// Vector for saving all frames which need to be serialized.
- std::vector<WebFrameImpl*> frames_;
+ std::vector<WebKit::WebFrameImpl*> frames_;
struct SerializeDomParam {
// Frame URL of current processing document presented by GURL
diff --git a/webkit/glue/dom_serializer_unittest.cc b/webkit/glue/dom_serializer_unittest.cc
index 449227e..eeafc5e0 100644
--- a/webkit/glue/dom_serializer_unittest.cc
+++ b/webkit/glue/dom_serializer_unittest.cc
@@ -37,10 +37,12 @@ MSVC_POP_WARNING();
#include "webkit/glue/dom_serializer.h"
#include "webkit/glue/dom_serializer_delegate.h"
#include "webkit/glue/glue_util.h"
-#include "webkit/glue/webframe_impl.h"
+#include "webkit/api/src/WebFrameImpl.h"
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
#include "webkit/tools/test_shell/test_shell_test.h"
+using WebKit::WebFrameImpl;
+
namespace {
class DomSerializerTests : public TestShellTest,
diff --git a/webkit/glue/image_resource_fetcher.h b/webkit/glue/image_resource_fetcher.h
index ef2f857..593b915 100644
--- a/webkit/glue/image_resource_fetcher.h
+++ b/webkit/glue/image_resource_fetcher.h
@@ -9,12 +9,11 @@
#include "webkit/glue/resource_fetcher.h"
class SkBitmap;
-class WebViewImpl;
namespace webkit_glue {
// ImageResourceFetcher handles downloading an image for a webview. Once
-// downloading is done the hosting WebViewImpl is notified. ImageResourceFetcher
+// downloading is done the supplied callback is notified. ImageResourceFetcher
// is used to download the favicon and images for web apps.
class ImageResourceFetcher {
public:
diff --git a/webkit/glue/password_autocomplete_listener_impl.cc b/webkit/glue/password_autocomplete_listener_impl.cc
index 883e6bc..b955f53 100644
--- a/webkit/glue/password_autocomplete_listener_impl.cc
+++ b/webkit/glue/password_autocomplete_listener_impl.cc
@@ -13,10 +13,13 @@
#include "base/string_util.h"
#include "webkit/api/public/WebNode.h"
#include "webkit/api/public/WebVector.h"
+#include "webkit/api/src/WebFrameImpl.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/password_autocomplete_listener_impl.h"
-#include "webkit/glue/webframe_impl.h"
-#include "webkit/glue/webview_impl.h"
+
+using WebKit::WebFrameImpl;
+using WebKit::WebViewImpl;
namespace webkit_glue {
@@ -47,8 +50,8 @@ void HTMLInputDelegate::RefreshAutofillPopup(
const std::vector<string16>& suggestions,
int default_suggestion_index) {
WebFrameImpl* webframe =
- WebFrameImpl::FromFrame(element_->document()->frame());
- WebViewImpl* webview = webframe->GetWebViewImpl();
+ WebFrameImpl::fromFrame(element_->document()->frame());
+ WebViewImpl* webview = webframe->viewImpl();
if (!webview)
return;
diff --git a/webkit/glue/webaccessibilitymanager_impl.cc b/webkit/glue/webaccessibilitymanager_impl.cc
index fde40b3..f512a37 100644
--- a/webkit/glue/webaccessibilitymanager_impl.cc
+++ b/webkit/glue/webaccessibilitymanager_impl.cc
@@ -13,12 +13,13 @@
#include "webkit/glue/webaccessibilitymanager_impl.h"
#include "webkit/api/public/WebAccessibilityObject.h"
+#include "webkit/api/src/WebFrameImpl.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/glue/glue_accessibility_object.h"
#include "webkit/glue/glue_util.h"
-#include "webkit/glue/webframe_impl.h"
-#include "webkit/glue/webview_impl.h"
using WebKit::WebAccessibilityObject;
+using WebKit::WebFrameImpl;
using WebKit::WebView;
namespace webkit_glue {
diff --git a/webkit/glue/webdevtoolsagent_impl.cc b/webkit/glue/webdevtoolsagent_impl.cc
index e53fe46..ea84c14 100644
--- a/webkit/glue/webdevtoolsagent_impl.cc
+++ b/webkit/glue/webdevtoolsagent_impl.cc
@@ -26,14 +26,15 @@
#include "webkit/api/public/WebDataSource.h"
#include "webkit/api/public/WebDevToolsAgentClient.h"
+#include "webkit/api/public/WebFrame.h"
#include "webkit/api/public/WebURL.h"
#include "webkit/api/public/WebURLRequest.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/glue/devtools/bound_object.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdevtoolsagent_impl.h"
-#include "webkit/glue/webview_impl.h"
using WebCore::Document;
using WebCore::InspectorBackend;
@@ -53,10 +54,12 @@ using WebCore::V8Proxy;
using WebKit::WebDataSource;
using WebKit::WebDevToolsAgentClient;
using WebKit::WebFrame;
+using WebKit::WebFrameImpl;
using WebKit::WebPoint;
using WebKit::WebString;
using WebKit::WebURL;
using WebKit::WebURLRequest;
+using WebKit::WebViewImpl;
namespace {
diff --git a/webkit/glue/webdevtoolsagent_impl.h b/webkit/glue/webdevtoolsagent_impl.h
index 4bb19ff..7db9762 100644
--- a/webkit/glue/webdevtoolsagent_impl.h
+++ b/webkit/glue/webdevtoolsagent_impl.h
@@ -25,20 +25,20 @@ class String;
namespace WebKit {
class WebDevToolsAgentClient;
class WebFrame;
+class WebFrameImpl;
+class WebViewImpl;
}
class BoundObject;
class DebuggerAgentDelegateStub;
class DebuggerAgentImpl;
class Value;
-class WebFrameImpl;
-class WebViewImpl;
class WebDevToolsAgentImpl : public WebKit::WebDevToolsAgent,
public ToolsAgent,
public DevToolsRpc::Delegate {
public:
- WebDevToolsAgentImpl(WebViewImpl* web_view_impl,
+ WebDevToolsAgentImpl(WebKit::WebViewImpl* web_view_impl,
WebKit::WebDevToolsAgentClient* client);
virtual ~WebDevToolsAgentImpl();
@@ -78,11 +78,11 @@ class WebDevToolsAgentImpl : public WebKit::WebDevToolsAgent,
// Methods called by the glue.
void SetMainFrameDocumentReady(bool ready);
- void DidCommitLoadForFrame(WebViewImpl* webview,
+ void DidCommitLoadForFrame(WebKit::WebViewImpl* webview,
WebKit::WebFrame* frame,
bool is_new_navigation);
- void WindowObjectCleared(WebFrameImpl* webframe);
+ void WindowObjectCleared(WebKit::WebFrameImpl* webframe);
void ForceRepaint();
@@ -105,7 +105,7 @@ class WebDevToolsAgentImpl : public WebKit::WebDevToolsAgent,
int host_id_;
WebKit::WebDevToolsAgentClient* client_;
- WebViewImpl* web_view_impl_;
+ WebKit::WebViewImpl* web_view_impl_;
OwnPtr<DebuggerAgentDelegateStub> debugger_agent_delegate_stub_;
OwnPtr<ToolsAgentDelegateStub> tools_agent_delegate_stub_;
OwnPtr<ToolsAgentNativeDelegateStub> tools_agent_native_delegate_stub_;
diff --git a/webkit/glue/webdevtoolsfrontend_impl.cc b/webkit/glue/webdevtoolsfrontend_impl.cc
index db384fe..0cee5b5 100644
--- a/webkit/glue/webdevtoolsfrontend_impl.cc
+++ b/webkit/glue/webdevtoolsfrontend_impl.cc
@@ -27,21 +27,24 @@
#include "webkit/api/public/WebDevToolsFrontendClient.h"
#include "webkit/api/public/WebFrame.h"
#include "webkit/api/public/WebScriptSource.h"
+#include "webkit/api/src/WebFrameImpl.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/glue/devtools/bound_object.h"
#include "webkit/glue/devtools/debugger_agent.h"
#include "webkit/glue/devtools/devtools_rpc_js.h"
#include "webkit/glue/devtools/tools_agent.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdevtoolsfrontend_impl.h"
-#include "webkit/glue/webview_impl.h"
using namespace WebCore;
using WebKit::WebDevToolsFrontend;
using WebKit::WebDevToolsFrontendClient;
using WebKit::WebFrame;
+using WebKit::WebFrameImpl;
using WebKit::WebScriptSource;
using WebKit::WebString;
using WebKit::WebView;
+using WebKit::WebViewImpl;
static v8::Local<v8::String> ToV8String(const String& s) {
if (s.isNull())
@@ -124,7 +127,7 @@ WebDevToolsFrontendImpl::WebDevToolsFrontendImpl(
client_(client),
application_locale_(application_locale),
loaded_(false) {
- WebFrameImpl* frame = web_view_impl_->main_frame();
+ WebFrameImpl* frame = web_view_impl_->mainFrameImpl();
v8::HandleScope scope;
v8::Handle<v8::Context> frame_context = V8Proxy::context(frame->frame());
@@ -228,7 +231,7 @@ void WebDevToolsFrontendImpl::AddResourceSourceToFrame(int resource_id,
}
void WebDevToolsFrontendImpl::ExecuteScript(const Vector<String>& v) {
- WebFrameImpl* frame = web_view_impl_->main_frame();
+ WebFrameImpl* frame = web_view_impl_->mainFrameImpl();
v8::HandleScope scope;
v8::Handle<v8::Context> frame_context = V8Proxy::context(frame->frame());
v8::Context::Scope context_scope(frame_context);
@@ -264,7 +267,7 @@ v8::Handle<v8::Value> WebDevToolsFrontendImpl::JsReset(
const v8::Arguments& args) {
WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(
v8::External::Cast(*args.Data())->Value());
- WebFrameImpl* frame = frontend->web_view_impl_->main_frame();
+ WebFrameImpl* frame = frontend->web_view_impl_->mainFrameImpl();
frontend->tools_agent_native_delegate_impl_.set(
new ToolsAgentNativeDelegateImpl(frame));
return v8::Undefined();
diff --git a/webkit/glue/webdevtoolsfrontend_impl.h b/webkit/glue/webdevtoolsfrontend_impl.h
index 5f573a6..94e6bc0 100644
--- a/webkit/glue/webdevtoolsfrontend_impl.h
+++ b/webkit/glue/webdevtoolsfrontend_impl.h
@@ -22,20 +22,23 @@ class Page;
class String;
}
+namespace WebKit {
+class WebViewImpl;
+}
+
class BoundObject;
class JsDebuggerAgentBoundObj;
class JsNetAgentBoundObj;
class JsToolsAgentBoundObj;
class ToolsAgentNativeDelegateImpl;
class WebDevToolsClientDelegate;
-class WebViewImpl;
class WebDevToolsFrontendImpl : public WebKit::WebDevToolsFrontend,
public DevToolsRpc::Delegate,
public Noncopyable {
public:
WebDevToolsFrontendImpl(
- WebViewImpl* web_view_impl,
+ WebKit::WebViewImpl* web_view_impl,
WebKit::WebDevToolsFrontendClient* client,
const String& application_locale);
virtual ~WebDevToolsFrontendImpl();
@@ -80,7 +83,7 @@ class WebDevToolsFrontendImpl : public WebKit::WebDevToolsFrontend,
static v8::Handle<v8::Value> JsDebuggerCommand(
const v8::Arguments& args);
- WebViewImpl* web_view_impl_;
+ WebKit::WebViewImpl* web_view_impl_;
WebKit::WebDevToolsFrontendClient* client_;
String application_locale_;
OwnPtr<BoundObject> debugger_command_executor_obj_;
diff --git a/webkit/glue/webframe_impl.cc b/webkit/glue/webframe_impl.cc
deleted file mode 100644
index f3576ad..0000000
--- a/webkit/glue/webframe_impl.cc
+++ /dev/null
@@ -1,1921 +0,0 @@
-/*
- * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// How ownership works
-// -------------------
-//
-// Big oh represents a refcounted relationship: owner O--- ownee
-//
-// WebView (for the toplevel frame only)
-// O
-// |
-// Page O------- Frame (m_mainFrame) O-------O FrameView
-// ||
-// ||
-// FrameLoader O-------- WebFrame (via FrameLoaderClient)
-//
-// FrameLoader and Frame are formerly one object that was split apart because
-// it got too big. They basically have the same lifetime, hence the double line.
-//
-// WebFrame is refcounted and has one ref on behalf of the FrameLoader/Frame.
-// This is not a normal reference counted pointer because that would require
-// changing WebKit code that we don't control. Instead, it is created with this
-// 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
-// are created. WebKit will hook up this object to the FrameLoader/Frame
-// and the refcount will be correct.
-//
-// How frames are destroyed
-// ------------------------
-//
-// The main frame is never destroyed and is re-used. The FrameLoader is re-used
-// and a reference to the main frame is kept by the Page.
-//
-// When frame content is replaced, all subframes are destroyed. This happens
-// 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).
-
-#include "config.h"
-
-#include <algorithm>
-#include <string>
-
-#include "HTMLFormElement.h" // need this before Document.h
-#include "Chrome.h"
-#include "ChromiumBridge.h"
-#include "ClipboardUtilitiesChromium.h"
-#include "Console.h"
-#include "Document.h"
-#include "DocumentFragment.h" // Only needed for ReplaceSelectionCommand.h :(
-#include "DocumentLoader.h"
-#include "DocumentMarker.h"
-#include "DOMWindow.h"
-#include "Editor.h"
-#include "EventHandler.h"
-#include "FormState.h"
-#include "FrameChromium.h"
-#include "FrameLoader.h"
-#include "FrameLoadRequest.h"
-#include "FrameTree.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "HTMLCollection.h"
-#include "HTMLHeadElement.h"
-#include "HTMLInputElement.h"
-#include "HTMLFrameOwnerElement.h"
-#include "HTMLLinkElement.h"
-#include "HTMLNames.h"
-#include "HistoryItem.h"
-#include "InspectorController.h"
-#if PLATFORM(DARWIN)
-#include "LocalCurrentGraphicsContext.h"
-#endif
-#include "markup.h"
-#include "Page.h"
-#include "PlatformContextSkia.h"
-#include "PrintContext.h"
-#include "RenderFrame.h"
-#if PLATFORM(WIN_OS)
-#include "RenderThemeChromiumWin.h"
-#endif
-#include "RenderView.h"
-#include "RenderWidget.h"
-#include "ReplaceSelectionCommand.h"
-#include "ResourceHandle.h"
-#include "ResourceRequest.h"
-#include "ScriptController.h"
-#include "ScriptSourceCode.h"
-#include "ScriptValue.h"
-#include "ScrollbarTheme.h"
-#include "ScrollTypes.h"
-#include "SelectionController.h"
-#include "Settings.h"
-#include "SkiaUtils.h"
-#include "SubstituteData.h"
-#include "TextIterator.h"
-#include "TextAffinity.h"
-#include "XPathResult.h"
-#include <wtf/CurrentTime.h>
-#undef LOG
-
-#include "webkit/api/public/WebConsoleMessage.h"
-#include "webkit/api/public/WebFindOptions.h"
-#include "webkit/api/public/WebForm.h"
-#include "webkit/api/public/WebFrameClient.h"
-#include "webkit/api/public/WebHistoryItem.h"
-#include "webkit/api/public/WebRange.h"
-#include "webkit/api/public/WebRect.h"
-#include "webkit/api/public/WebScriptSource.h"
-#include "webkit/api/public/WebSecurityOrigin.h"
-#include "webkit/api/public/WebSize.h"
-#include "webkit/api/public/WebURLError.h"
-#include "webkit/api/public/WebVector.h"
-#include "webkit/api/src/DOMUtilitiesPrivate.h"
-#include "webkit/api/src/PasswordAutocompleteListener.h"
-#include "webkit/api/src/WebDataSourceImpl.h"
-#include "webkit/glue/glue_util.h"
-#include "webkit/glue/webframe_impl.h"
-#include "webkit/glue/webview_impl.h"
-
-#if PLATFORM(LINUX)
-#include <gdk/gdk.h>
-#endif
-
-using WebCore::AtomicString;
-using WebCore::ChromiumBridge;
-using WebCore::Color;
-using WebCore::Document;
-using WebCore::DocumentFragment;
-using WebCore::DocumentLoader;
-using WebCore::ExceptionCode;
-using WebCore::GraphicsContext;
-using WebCore::HTMLFrameOwnerElement;
-using WebCore::HTMLInputElement;
-using WebCore::Frame;
-using WebCore::FrameLoader;
-using WebCore::FrameLoadRequest;
-using WebCore::FrameLoadType;
-using WebCore::FrameTree;
-using WebCore::FrameView;
-using WebCore::HistoryItem;
-using WebCore::HTMLFormElement;
-using WebCore::IntRect;
-using WebCore::KURL;
-using WebCore::Node;
-using WebCore::Range;
-using WebCore::ReloadIgnoringCacheData;
-using WebCore::RenderObject;
-using WebCore::ResourceError;
-using WebCore::ResourceHandle;
-using WebCore::ResourceRequest;
-using WebCore::ResourceResponse;
-using WebCore::VisibleSelection;
-using WebCore::ScriptValue;
-using WebCore::SecurityOrigin;
-using WebCore::SharedBuffer;
-using WebCore::String;
-using WebCore::SubstituteData;
-using WebCore::TextIterator;
-using WebCore::Timer;
-using WebCore::VisiblePosition;
-using WebCore::XPathResult;
-
-using WebKit::PasswordAutocompleteListener;
-using WebKit::WebCanvas;
-using WebKit::WebConsoleMessage;
-using WebKit::WebData;
-using WebKit::WebDataSource;
-using WebKit::WebDataSourceImpl;
-using WebKit::WebFindOptions;
-using WebKit::WebFrame;
-using WebKit::WebFrameClient;
-using WebKit::WebHistoryItem;
-using WebKit::WebForm;
-using WebKit::WebRange;
-using WebKit::WebRect;
-using WebKit::WebScriptSource;
-using WebKit::WebSecurityOrigin;
-using WebKit::WebSize;
-using WebKit::WebString;
-using WebKit::WebURL;
-using WebKit::WebURLError;
-using WebKit::WebURLRequest;
-using WebKit::WebURLResponse;
-using WebKit::WebVector;
-using WebKit::WebView;
-
-// Key for a StatsCounter tracking how many WebFrames are active.
-static const char* const kWebFrameActiveCount = "WebFrameActiveCount";
-
-static const char* const kOSDType = "application/opensearchdescription+xml";
-static const char* const kOSDRel = "search";
-
-// The separator between frames when the frames are converted to plain text.
-static const wchar_t kFrameSeparator[] = L"\n\n";
-static const size_t kFrameSeparatorLen = arraysize(kFrameSeparator) - 1;
-
-// Backend for contentAsPlainText, this is a recursive function that gets
-// the text for the current frame and all of its subframes. It will append
-// the text of each frame in turn to the |output| up to |max_chars| length.
-//
-// The |frame| must be non-NULL.
-static void FrameContentAsPlainText(size_t max_chars, Frame* frame,
- Vector<UChar>* output) {
- Document* doc = frame->document();
- if (!doc)
- return;
-
- if (!frame->view())
- return;
-
- // TextIterator iterates over the visual representation of the DOM. As such,
- // it requires you to do a layout before using it (otherwise it'll crash).
- if (frame->view()->needsLayout())
- frame->view()->layout();
-
- // Select the document body.
- RefPtr<Range> range(doc->createRange());
- ExceptionCode exception = 0;
- range->selectNodeContents(doc->body(), exception);
-
- if (exception == 0) {
- // The text iterator will walk nodes giving us text. This is similar to
- // the plainText() function in TextIterator.h, but we implement the maximum
- // size and also copy the results directly into a wstring, avoiding the
- // string conversion.
- for (TextIterator it(range.get()); !it.atEnd(); it.advance()) {
- const UChar* chars = it.characters();
- if (!chars) {
- if (it.length() != 0) {
- // It appears from crash reports that an iterator can get into a state
- // where the character count is nonempty but the character pointer is
- // NULL. advance()ing it will then just add that many to the NULL
- // pointer which won't be caught in a NULL check but will crash.
- //
- // A NULL pointer and 0 length is common for some nodes.
- //
- // IF YOU CATCH THIS IN A DEBUGGER please let brettw know. We don't
- // currently understand the conditions for this to occur. Ideally, the
- // iterators would never get into the condition so we should fix them
- // if we can.
- ASSERT_NOT_REACHED();
- break;
- }
-
- // Just got a NULL node, we can forge ahead!
- continue;
- }
- size_t to_append = std::min(static_cast<size_t>(it.length()),
- max_chars - output->size());
- output->append(chars, to_append);
- if (output->size() >= max_chars)
- return; // Filled up the buffer.
- }
- }
-
- // Recursively walk the children.
- FrameTree* frame_tree = frame->tree();
- for (Frame* cur_child = frame_tree->firstChild(); cur_child;
- cur_child = cur_child->tree()->nextSibling()) {
- // Make sure the frame separator won't fill up the buffer, and give up if
- // it will. The danger is if the separator will make the buffer longer than
- // max_chars. This will cause the computation above:
- // max_chars - output->size()
- // to be a negative number which will crash when the subframe is added.
- if (output->size() >= max_chars - kFrameSeparatorLen)
- return;
-
- output->append(kFrameSeparator, kFrameSeparatorLen);
- FrameContentAsPlainText(max_chars, cur_child, output);
- if (output->size() >= max_chars)
- return; // Filled up the buffer.
- }
-}
-
-// Simple class to override some of PrintContext behavior.
-class ChromePrintContext : public WebCore::PrintContext {
- public:
- ChromePrintContext(Frame* frame)
- : PrintContext(frame),
- printed_page_width_(0) {
- }
- void begin(float width) {
- ASSERT(!printed_page_width_);
- printed_page_width_ = width;
- WebCore::PrintContext::begin(printed_page_width_);
- }
- float getPageShrink(int pageNumber) const {
- IntRect pageRect = m_pageRects[pageNumber];
- return printed_page_width_ / pageRect.width();
- }
- // Spools the printed page, a subrect of m_frame.
- // Skip the scale step. NativeTheme doesn't play well with scaling. Scaling
- // is done browser side instead.
- // Returns the scale to be applied.
- float spoolPage(GraphicsContext& ctx, int pageNumber) {
- IntRect pageRect = m_pageRects[pageNumber];
- float scale = printed_page_width_ / pageRect.width();
-
- ctx.save();
- ctx.translate(static_cast<float>(-pageRect.x()),
- static_cast<float>(-pageRect.y()));
- ctx.clip(pageRect);
- m_frame->view()->paintContents(&ctx, pageRect);
- ctx.restore();
- return scale;
- }
- protected:
- // Set when printing.
- float printed_page_width_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ChromePrintContext);
-};
-
-static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) {
- return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : NULL;
-}
-
-
-// WebFrame -------------------------------------------------------------------
-
-class WebFrameImpl::DeferredScopeStringMatches {
- public:
- DeferredScopeStringMatches(WebFrameImpl* webframe,
- int identifier,
- const WebString& search_text,
- const WebFindOptions& options,
- bool reset)
- : ALLOW_THIS_IN_INITIALIZER_LIST(
- timer_(this, &DeferredScopeStringMatches::DoTimeout)),
- webframe_(webframe),
- identifier_(identifier),
- search_text_(search_text),
- options_(options),
- reset_(reset) {
- timer_.startOneShot(0.0);
- }
-
- private:
- void DoTimeout(Timer<DeferredScopeStringMatches>*) {
- webframe_->CallScopeStringMatches(
- this, identifier_, search_text_, options_, reset_);
- }
-
- Timer<DeferredScopeStringMatches> timer_;
- RefPtr<WebFrameImpl> webframe_;
- int identifier_;
- WebString search_text_;
- WebFindOptions options_;
- bool reset_;
-};
-
-
-// WebFrame -------------------------------------------------------------------
-
-// static
-WebFrame* WebFrame::frameForEnteredContext() {
- Frame* frame =
- WebCore::ScriptController::retrieveFrameForEnteredContext();
- return WebFrameImpl::FromFrame(frame);
-}
-
-// static
-WebFrame* WebFrame::frameForCurrentContext() {
- Frame* frame =
- WebCore::ScriptController::retrieveFrameForCurrentContext();
- return WebFrameImpl::FromFrame(frame);
-}
-
-WebString WebFrameImpl::name() const {
- return webkit_glue::StringToWebString(frame_->tree()->name());
-}
-
-WebURL WebFrameImpl::url() const {
- const WebDataSource* ds = dataSource();
- if (!ds)
- return WebURL();
- return ds->request().url();
-}
-
-WebURL WebFrameImpl::favIconURL() const {
- WebCore::FrameLoader* frame_loader = frame_->loader();
- // The URL to the favicon may be in the header. As such, only
- // ask the loader for the favicon if it's finished loading.
- if (frame_loader->state() == WebCore::FrameStateComplete) {
- const KURL& url = frame_loader->iconURL();
- if (!url.isEmpty()) {
- return webkit_glue::KURLToWebURL(url);
- }
- }
- return WebURL();
-}
-
-WebURL WebFrameImpl::openSearchDescriptionURL() const {
- WebCore::FrameLoader* frame_loader = frame_->loader();
- if (frame_loader->state() == WebCore::FrameStateComplete &&
- frame_->document() && frame_->document()->head() &&
- !frame_->tree()->parent()) {
- WebCore::HTMLHeadElement* head = frame_->document()->head();
- if (head) {
- RefPtr<WebCore::HTMLCollection> children = head->children();
- for (Node* child = children->firstItem(); child != NULL;
- child = children->nextItem()) {
- WebCore::HTMLLinkElement* link_element =
- WebKit::toHTMLLinkElement(child);
- if (link_element && link_element->type() == kOSDType &&
- link_element->rel() == kOSDRel && !link_element->href().isEmpty()) {
- return webkit_glue::KURLToWebURL(link_element->href());
- }
- }
- }
- }
- return WebURL();
-}
-
-WebSize WebFrameImpl::scrollOffset() const {
- WebCore::FrameView* view = frameview();
- if (view)
- return webkit_glue::IntSizeToWebSize(view->scrollOffset());
-
- return WebSize();
-}
-
-WebSize WebFrameImpl::contentsSize() const {
- return webkit_glue::IntSizeToWebSize(frame()->view()->contentsSize());
-}
-
-int WebFrameImpl::contentsPreferredWidth() const {
- if ((frame_->document() != NULL) &&
- (frame_->document()->renderView() != NULL)) {
- return frame_->document()->renderView()->minPrefWidth();
- } else {
- return 0;
- }
-}
-
-bool WebFrameImpl::hasVisibleContent() const {
- return frame()->view()->visibleWidth() > 0 &&
- frame()->view()->visibleHeight() > 0;
-}
-
-WebView* WebFrameImpl::view() const {
- return GetWebViewImpl();
-}
-
-WebFrame* WebFrameImpl::opener() const {
- Frame* opener = NULL;
- if (frame_)
- opener = frame_->loader()->opener();
- return FromFrame(opener);
-}
-
-WebFrame* WebFrameImpl::parent() const {
- Frame *parent = NULL;
- if (frame_)
- parent = frame_->tree()->parent();
- return FromFrame(parent);
-}
-
-WebFrame* WebFrameImpl::top() const {
- if (frame_)
- return FromFrame(frame_->tree()->top());
-
- return NULL;
-}
-
-WebFrame* WebFrameImpl::firstChild() const {
- return FromFrame(frame()->tree()->firstChild());
-}
-
-WebFrame* WebFrameImpl::lastChild() const {
- return FromFrame(frame()->tree()->lastChild());
-}
-
-WebFrame* WebFrameImpl::nextSibling() const {
- return FromFrame(frame()->tree()->nextSibling());
-}
-
-WebFrame* WebFrameImpl::previousSibling() const {
- return FromFrame(frame()->tree()->previousSibling());
-}
-
-WebFrame* WebFrameImpl::traverseNext(bool wrap) const {
- return FromFrame(frame()->tree()->traverseNextWithWrap(wrap));
-}
-
-WebFrame* WebFrameImpl::traversePrevious(bool wrap) const {
- return FromFrame(frame()->tree()->traversePreviousWithWrap(wrap));
-}
-
-WebFrame* WebFrameImpl::findChildByName(const WebKit::WebString& name) const {
- return FromFrame(frame()->tree()->child(
- webkit_glue::WebStringToString(name)));
-}
-
-WebFrame* WebFrameImpl::findChildByExpression(
- const WebKit::WebString& xpath) const {
- if (xpath.isEmpty())
- return NULL;
-
- Document* document = frame_->document();
-
- ExceptionCode ec = 0;
- PassRefPtr<XPathResult> xpath_result =
- document->evaluate(webkit_glue::WebStringToString(xpath),
- document,
- NULL, /* namespace */
- XPathResult::ORDERED_NODE_ITERATOR_TYPE,
- NULL, /* XPathResult object */
- ec);
- if (!xpath_result.get())
- return NULL;
-
- Node* node = xpath_result->iterateNext(ec);
-
- if (!node || !node->isFrameOwnerElement())
- return NULL;
- HTMLFrameOwnerElement* frame_element =
- static_cast<HTMLFrameOwnerElement*>(node);
- return FromFrame(frame_element->contentFrame());
-}
-
-void WebFrameImpl::forms(WebVector<WebForm>& results) const {
- if (!frame_)
- return;
-
- RefPtr<WebCore::HTMLCollection> forms = frame_->document()->forms();
- size_t form_count = forms->length();
-
- WebVector<WebForm> temp(form_count);
- for (size_t i = 0; i < form_count; ++i) {
- Node* node = forms->item(i);
- // Strange but true, sometimes item can be NULL.
- if (node) {
- temp[i] = webkit_glue::HTMLFormElementToWebForm(
- static_cast<HTMLFormElement*>(node));
- }
- }
- results.swap(temp);
-}
-
-WebSecurityOrigin WebFrameImpl::securityOrigin() const {
- if (!frame_ || !frame_->document())
- return WebSecurityOrigin();
-
- return webkit_glue::SecurityOriginToWebSecurityOrigin(
- frame_->document()->securityOrigin());
-}
-
-void WebFrameImpl::grantUniversalAccess() {
- ASSERT(frame_ && frame_->document());
- if (frame_ && frame_->document()) {
- frame_->document()->securityOrigin()->grantUniversalAccess();
- }
-}
-
-NPObject* WebFrameImpl::windowObject() const {
- if (!frame_)
- return NULL;
-
- return frame_->script()->windowScriptNPObject();
-}
-
-void WebFrameImpl::bindToWindowObject(const WebString& name,
- NPObject* object) {
- ASSERT(frame_);
- if (!frame_ || !frame_->script()->isEnabled())
- return;
-
- String key = webkit_glue::WebStringToString(name);
-#if USE(V8)
- frame_->script()->bindToWindowObject(frame_, key, object);
-#else
- notImplemented();
-#endif
-}
-
-void WebFrameImpl::executeScript(const WebScriptSource& source) {
- frame_->script()->executeScript(
- WebCore::ScriptSourceCode(
- webkit_glue::WebStringToString(source.code),
- webkit_glue::WebURLToKURL(source.url),
- source.startLine));
-}
-
-void WebFrameImpl::executeScriptInNewContext(
- const WebScriptSource* sources_in, unsigned num_sources,
- int extension_group) {
- Vector<WebCore::ScriptSourceCode> sources;
-
- for (unsigned i = 0; i < num_sources; ++i) {
- sources.append(WebCore::ScriptSourceCode(
- webkit_glue::WebStringToString(sources_in[i].code),
- webkit_glue::WebURLToKURL(sources_in[i].url),
- sources_in[i].startLine));
- }
-
- frame_->script()->evaluateInNewContext(sources, extension_group);
-}
-
-void WebFrameImpl::executeScriptInIsolatedWorld(
- int world_id, const WebScriptSource* sources_in, unsigned num_sources,
- int extension_group) {
- Vector<WebCore::ScriptSourceCode> sources;
-
- for (unsigned i = 0; i < num_sources; ++i) {
- sources.append(WebCore::ScriptSourceCode(
- webkit_glue::WebStringToString(sources_in[i].code),
- webkit_glue::WebURLToKURL(sources_in[i].url),
- sources_in[i].startLine));
- }
-
- frame_->script()->evaluateInIsolatedWorld(world_id, sources, extension_group);
-}
-
-void WebFrameImpl::addMessageToConsole(const WebConsoleMessage& message) {
- ASSERT(frame());
-
- WebCore::MessageLevel webcore_message_level;
- switch (message.level) {
- case WebConsoleMessage::LevelTip:
- webcore_message_level = WebCore::TipMessageLevel;
- break;
- case WebConsoleMessage::LevelLog:
- webcore_message_level = WebCore::LogMessageLevel;
- break;
- case WebConsoleMessage::LevelWarning:
- webcore_message_level = WebCore::WarningMessageLevel;
- break;
- case WebConsoleMessage::LevelError:
- webcore_message_level = WebCore::ErrorMessageLevel;
- break;
- default:
- ASSERT_NOT_REACHED();
- return;
- }
-
- frame()->domWindow()->console()->addMessage(
- WebCore::OtherMessageSource, WebCore::LogMessageType,
- webcore_message_level, webkit_glue::WebStringToString(message.text),
- 1, String());
-}
-
-void WebFrameImpl::collectGarbage() {
- if (!frame_)
- return;
- if (!frame_->settings()->isJavaScriptEnabled())
- return;
- // TODO(mbelshe): Move this to the ScriptController and make it JS neutral.
-#if USE(V8)
- frame_->script()->collectGarbage();
-#else
- notImplemented();
-#endif
-}
-
-#if USE(V8)
-// Returns the V8 context for this frame, or an empty handle if there is none.
-v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const {
- if (!frame_)
- return v8::Local<v8::Context>();
-
- return WebCore::V8Proxy::mainWorldContext(frame_);
-}
-#endif
-
-bool WebFrameImpl::insertStyleText(
- const WebString& css, const WebString& id) {
- Document* document = frame()->document();
- if (!document)
- return false;
- WebCore::Element* document_element = document->documentElement();
- if (!document_element)
- return false;
-
- ExceptionCode err = 0;
-
- if (!id.isEmpty()) {
- WebCore::Element* old_element =
- document->getElementById(webkit_glue::WebStringToString(id));
- if (old_element) {
- Node* parent = old_element->parent();
- if (!parent)
- return false;
- parent->removeChild(old_element, err);
- }
- }
-
- RefPtr<WebCore::Element> stylesheet = document->createElement(
- WebCore::HTMLNames::styleTag, false);
- if (!id.isEmpty())
- stylesheet->setAttribute(WebCore::HTMLNames::idAttr,
- webkit_glue::WebStringToString(id));
- stylesheet->setTextContent(webkit_glue::WebStringToString(css), err);
- ASSERT(!err);
- WebCore::Node* first = document_element->firstChild();
- bool success = document_element->insertBefore(stylesheet, first, err);
- ASSERT(success);
- return success;
-}
-
-void WebFrameImpl::reload() {
- frame_->loader()->history()->saveDocumentAndScrollState();
-
- stopLoading(); // Make sure existing activity stops.
- frame_->loader()->reload();
-}
-
-void WebFrameImpl::loadRequest(const WebURLRequest& request) {
- const ResourceRequest* resource_request =
- webkit_glue::WebURLRequestToResourceRequest(&request);
- ASSERT(resource_request);
-
- if (resource_request->url().protocolIs("javascript")) {
- LoadJavaScriptURL(resource_request->url());
- return;
- }
-
- stopLoading(); // Make sure existing activity stops.
- frame_->loader()->load(*resource_request, false);
-}
-
-void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item) {
- RefPtr<HistoryItem> history_item =
- webkit_glue::WebHistoryItemToHistoryItem(item);
- ASSERT(history_item.get());
-
- stopLoading(); // Make sure existing activity stops.
-
- // If there is no current_item, which happens when we are navigating in
- // session history after a crash, we need to manufacture one otherwise WebKit
- // hoarks. This is probably the wrong thing to do, but it seems to work.
- RefPtr<HistoryItem> current_item = frame_->loader()->history()->currentItem();
- if (!current_item) {
- current_item = HistoryItem::create();
- current_item->setLastVisitWasFailure(true);
- frame_->loader()->history()->setCurrentItem(current_item.get());
- GetWebViewImpl()->SetCurrentHistoryItem(current_item.get());
- }
-
- frame_->loader()->history()->goToItem(history_item.get(),
- WebCore::FrameLoadTypeIndexedBackForward);
-}
-
-void WebFrameImpl::loadData(const WebData& data,
- const WebString& mime_type,
- const WebString& text_encoding,
- const WebURL& base_url,
- const WebURL& unreachable_url,
- bool replace) {
- SubstituteData subst_data(
- webkit_glue::WebDataToSharedBuffer(data),
- webkit_glue::WebStringToString(mime_type),
- webkit_glue::WebStringToString(text_encoding),
- webkit_glue::WebURLToKURL(unreachable_url));
- ASSERT(subst_data.isValid());
-
- stopLoading(); // Make sure existing activity stops.
- frame_->loader()->load(ResourceRequest(webkit_glue::WebURLToKURL(base_url)),
- subst_data, false);
- if (replace) {
- // Do this to force WebKit to treat the load as replacing the currently
- // loaded page.
- frame_->loader()->setReplacing();
- }
-}
-
-void WebFrameImpl::loadHTMLString(const WebData& data,
- const WebURL& base_url,
- const WebURL& unreachable_url,
- bool replace) {
- loadData(data,
- WebString::fromUTF8("text/html"),
- WebString::fromUTF8("UTF-8"),
- base_url,
- unreachable_url,
- replace);
-}
-
-bool WebFrameImpl::isLoading() const {
- if (!frame_)
- return false;
- return frame_->loader()->isLoading();
-}
-
-void WebFrameImpl::stopLoading() {
- if (!frame_)
- return;
-
- // TODO(darin): Figure out what we should really do here. It seems like a
- // bug that FrameLoader::stopLoading doesn't call stopAllLoaders.
- frame_->loader()->stopAllLoaders();
- frame_->loader()->stopLoading(WebCore::UnloadEventPolicyNone);
-}
-
-WebDataSource* WebFrameImpl::provisionalDataSource() const {
- FrameLoader* frame_loader = frame_->loader();
-
- // We regard the policy document loader as still provisional.
- DocumentLoader* doc_loader = frame_loader->provisionalDocumentLoader();
- if (!doc_loader)
- doc_loader = frame_loader->policyDocumentLoader();
-
- return DataSourceForDocLoader(doc_loader);
-}
-
-WebDataSource* WebFrameImpl::dataSource() const {
- return DataSourceForDocLoader(frame_->loader()->documentLoader());
-}
-
-WebHistoryItem WebFrameImpl::previousHistoryItem() const {
- // We use the previous item here because documentState (filled-out forms)
- // only get saved to history when it becomes the previous item. The caller
- // is expected to query the history item after a navigation occurs, after
- // the desired history item has become the previous entry.
- return webkit_glue::HistoryItemToWebHistoryItem(
- GetWebViewImpl()->GetPreviousHistoryItem());
-}
-
-WebHistoryItem WebFrameImpl::currentHistoryItem() const {
- frame_->loader()->history()->saveDocumentAndScrollState();
-
- return webkit_glue::HistoryItemToWebHistoryItem(
- frame_->page()->backForwardList()->currentItem());
-}
-
-void WebFrameImpl::enableViewSourceMode(bool enable) {
- if (frame_)
- frame_->setInViewSourceMode(enable);
-}
-
-bool WebFrameImpl::isViewSourceModeEnabled() const {
- if (frame_)
- return frame_->inViewSourceMode();
-
- return false;
-}
-
-void WebFrameImpl::setReferrerForRequest(
- WebURLRequest& request, const WebURL& referrer_url) {
- String referrer;
- if (referrer_url.isEmpty()) {
- referrer = frame_->loader()->outgoingReferrer();
- } else {
- referrer = webkit_glue::WebStringToString(referrer_url.spec().utf16());
- }
- if (SecurityOrigin::shouldHideReferrer(
- webkit_glue::WebURLToKURL(request.url()), referrer))
- return;
- request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
- webkit_glue::StringToWebString(referrer));
-}
-
-void WebFrameImpl::dispatchWillSendRequest(WebURLRequest& request) {
- ResourceResponse response;
- frame_->loader()->client()->dispatchWillSendRequest(NULL, 0,
- *webkit_glue::WebURLRequestToMutableResourceRequest(&request),
- response);
-}
-
-void WebFrameImpl::commitDocumentData(const char* data, size_t data_len) {
- DocumentLoader* document_loader = frame_->loader()->documentLoader();
-
- // Set the text encoding. This calls begin() for us. It is safe to call
- // this multiple times (Mac does: page/mac/WebCoreFrameBridge.mm).
- bool user_chosen = true;
- String encoding = document_loader->overrideEncoding();
- if (encoding.isNull()) {
- user_chosen = false;
- encoding = document_loader->response().textEncodingName();
- }
- frame_->loader()->setEncoding(encoding, user_chosen);
-
- // NOTE: mac only does this if there is a document
- frame_->loader()->addData(data, data_len);
-}
-
-unsigned WebFrameImpl::unloadListenerCount() const {
- return frame()->domWindow()->pendingUnloadEventListeners();
-}
-
-bool WebFrameImpl::isProcessingUserGesture() const {
- return frame()->loader()->isProcessingUserGesture();
-}
-
-bool WebFrameImpl::willSuppressOpenerInNewFrame() const {
- return frame()->loader()->suppressOpenerInNewFrame();
-}
-
-void WebFrameImpl::replaceSelection(const WebString& wtext) {
- String text = webkit_glue::WebStringToString(wtext);
- RefPtr<DocumentFragment> fragment = createFragmentFromText(
- frame()->selection()->toNormalizedRange().get(), text);
- WebCore::applyCommand(WebCore::ReplaceSelectionCommand::create(
- frame()->document(), fragment.get(), false, true, true));
-}
-
-void WebFrameImpl::insertText(const WebString& text) {
- frame()->editor()->insertText(webkit_glue::WebStringToString(text), NULL);
-}
-
-void WebFrameImpl::setMarkedText(
- const WebString& text, unsigned location, unsigned length) {
- WebCore::Editor* editor = frame()->editor();
- WebCore::String str = webkit_glue::WebStringToString(text);
-
- editor->confirmComposition(str);
-
- WTF::Vector<WebCore::CompositionUnderline> decorations;
- editor->setComposition(str, decorations, location, length);
-}
-
-void WebFrameImpl::unmarkText() {
- frame()->editor()->confirmCompositionWithoutDisturbingSelection();
-}
-
-bool WebFrameImpl::hasMarkedText() const {
- return frame()->editor()->hasComposition();
-}
-
-WebRange WebFrameImpl::markedRange() const {
- return webkit_glue::RangeToWebRange(frame()->editor()->compositionRange());
-}
-
-bool WebFrameImpl::executeCommand(const WebString& name) {
- ASSERT(frame());
-
- if (name.length() <= 2)
- return false;
-
- // Since we don't have NSControl, we will convert the format of command
- // string and call the function on Editor directly.
- String command = webkit_glue::WebStringToString(name);
-
- // Make sure the first letter is upper case.
- command.replace(0, 1, command.substring(0, 1).upper());
-
- // Remove the trailing ':' if existing.
- if (command[command.length() - 1] == UChar(':'))
- command = command.substring(0, command.length() - 1);
-
- bool rv = true;
-
- // Specially handling commands that Editor::execCommand does not directly
- // support.
- if (command == "DeleteToEndOfParagraph") {
- WebCore::Editor* editor = frame()->editor();
- if (!editor->deleteWithDirection(WebCore::SelectionController::FORWARD,
- WebCore::ParagraphBoundary,
- true,
- false)) {
- editor->deleteWithDirection(WebCore::SelectionController::FORWARD,
- WebCore::CharacterGranularity,
- true,
- false);
- }
- } else if (command == "Indent") {
- frame()->editor()->indent();
- } else if (command == "Outdent") {
- frame()->editor()->outdent();
- } else if (command == "DeleteBackward") {
- rv = frame()->editor()->command(AtomicString("BackwardDelete")).execute();
- } else if (command == "DeleteForward") {
- rv = frame()->editor()->command(AtomicString("ForwardDelete")).execute();
- } else if (command == "AdvanceToNextMisspelling") {
- // False must be passed here, or the currently selected word will never be
- // skipped.
- frame()->editor()->advanceToNextMisspelling(false);
- } else if (command == "ToggleSpellPanel") {
- frame()->editor()->showSpellingGuessPanel();
- } else {
- rv = frame()->editor()->command(command).execute();
- }
- return rv;
-}
-
-bool WebFrameImpl::executeCommand(const WebString& name,
- const WebString& value) {
- ASSERT(frame());
- WebCore::String web_name = webkit_glue::WebStringToString(name);
-
- // moveToBeginningOfDocument and moveToEndfDocument are only handled by WebKit
- // for editable nodes.
- if (!frame()->editor()->canEdit() &&
- web_name == "moveToBeginningOfDocument") {
- return GetWebViewImpl()->PropagateScroll(WebCore::ScrollUp,
- WebCore::ScrollByDocument);
- } else if (!frame()->editor()->canEdit() &&
- web_name == "moveToEndOfDocument") {
- return GetWebViewImpl()->PropagateScroll(WebCore::ScrollDown,
- WebCore::ScrollByDocument);
- } else {
- return frame()->editor()->command(web_name).
- execute(webkit_glue::WebStringToString(value));
- }
-}
-
-bool WebFrameImpl::isCommandEnabled(const WebString& name) const {
- ASSERT(frame());
- return frame()->editor()->command(webkit_glue::WebStringToString(name)).
- isEnabled();
-}
-
-void WebFrameImpl::enableContinuousSpellChecking(bool enable) {
- if (enable == isContinuousSpellCheckingEnabled())
- return;
- frame()->editor()->toggleContinuousSpellChecking();
-}
-
-bool WebFrameImpl::isContinuousSpellCheckingEnabled() const {
- return frame()->editor()->isContinuousSpellCheckingEnabled();
-}
-
-bool WebFrameImpl::hasSelection() const {
- // frame()->selection()->isNone() never returns true.
- return (frame()->selection()->start() != frame()->selection()->end());
-}
-
-WebRange WebFrameImpl::selectionRange() const {
- return webkit_glue::RangeToWebRange(
- frame()->selection()->toNormalizedRange());
-}
-
-WebString WebFrameImpl::selectionAsText() const {
- RefPtr<Range> range = frame()->selection()->toNormalizedRange();
- if (!range.get())
- return WebString();
-
- String text = range->text();
-#if PLATFORM(WIN_OS)
- WebCore::replaceNewlinesWithWindowsStyleNewlines(text);
-#endif
- WebCore::replaceNBSPWithSpace(text);
- return webkit_glue::StringToWebString(text);
-}
-
-WebString WebFrameImpl::selectionAsMarkup() const {
- RefPtr<Range> range = frame()->selection()->toNormalizedRange();
- if (!range.get())
- return WebString();
-
- String markup = WebCore::createMarkup(range.get(), 0);
- return webkit_glue::StringToWebString(markup);
-}
-
-int WebFrameImpl::printBegin(const WebSize& page_size) {
- ASSERT(!frame()->document()->isFrameSet());
-
- print_context_.set(new ChromePrintContext(frame()));
- WebCore::FloatRect rect(0, 0,
- static_cast<float>(page_size.width),
- static_cast<float>(page_size.height));
- print_context_->begin(rect.width());
- float page_height;
- // We ignore the overlays calculation for now since they are generated in the
- // browser. page_height is actually an output parameter.
- print_context_->computePageRects(rect, 0, 0, 1.0, page_height);
- return print_context_->pageCount();
-}
-
-float WebFrameImpl::getPrintPageShrink(int page) {
- // Ensure correct state.
- if (!print_context_.get() || page < 0) {
- ASSERT_NOT_REACHED();
- return 0;
- }
-
- return print_context_->getPageShrink(page);
-}
-
-float WebFrameImpl::printPage(int page, WebCanvas* canvas) {
- // Ensure correct state.
- if (!print_context_.get() || page < 0 || !frame() || !frame()->document()) {
- ASSERT_NOT_REACHED();
- return 0;
- }
-
-#if PLATFORM(WIN_OS) || PLATFORM(LINUX) || PLATFORM(FREEBSD)
- PlatformContextSkia context(canvas);
- GraphicsContext spool(&context);
-#elif PLATFORM(DARWIN)
- GraphicsContext spool(canvas);
- WebCore::LocalCurrentGraphicsContext localContext(&spool);
-#endif
-
- return print_context_->spoolPage(spool, page);
-}
-
-void WebFrameImpl::printEnd() {
- ASSERT(print_context_.get());
- if (print_context_.get())
- print_context_->end();
- print_context_.clear();
-}
-
-bool WebFrameImpl::find(int request_id,
- const WebString& search_text,
- const WebFindOptions& options,
- bool wrap_within_frame,
- WebRect* selection_rect) {
- WebCore::String webcore_string = webkit_glue::WebStringToString(search_text);
-
- WebFrameImpl* const main_frame_impl = GetWebViewImpl()->main_frame();
-
- if (!options.findNext)
- frame()->page()->unmarkAllTextMatches();
- else
- SetMarkerActive(active_match_.get(), false); // Active match is changing.
-
- // Starts the search from the current selection.
- bool start_in_selection = true;
-
- // If the user has selected something since the last Find operation we want
- // to start from there. Otherwise, we start searching from where the last Find
- // operation left off (either a Find or a FindNext operation).
- VisibleSelection selection(frame()->selection()->selection());
- if (selection.isNone() && active_match_) {
- selection = VisibleSelection(active_match_.get());
- frame()->selection()->setSelection(selection);
- }
-
- ASSERT(frame() && frame()->view());
- bool found = frame()->findString(webcore_string, options.forward,
- options.matchCase, wrap_within_frame,
- start_in_selection);
- if (found) {
- // Store which frame was active. This will come in handy later when we
- // change the active match ordinal below.
- WebFrameImpl* old_active_frame = main_frame_impl->active_match_frame_;
- // Set this frame as the active frame (the one with the active highlight).
- main_frame_impl->active_match_frame_ = this;
-
- // We found something, so we can now query the selection for its position.
- VisibleSelection new_selection(frame()->selection()->selection());
- IntRect curr_selection_rect;
-
- // If we thought we found something, but it couldn't be selected (perhaps
- // because it was marked -webkit-user-select: none), we can't set it to
- // be active but we still continue searching. This matches Safari's
- // behavior, including some oddities when selectable and un-selectable text
- // are mixed on a page: see https://bugs.webkit.org/show_bug.cgi?id=19127.
- if (new_selection.isNone() ||
- (new_selection.start() == new_selection.end())) {
- active_match_ = NULL;
- } else {
- active_match_ = new_selection.toNormalizedRange();
- curr_selection_rect = active_match_->boundingBox();
- SetMarkerActive(active_match_.get(), true); // Active.
- // WebKit draws the highlighting for all matches.
- executeCommand(WebString::fromUTF8("Unselect"));
- }
-
- if (!options.findNext) {
- // This is a Find operation, so we set the flag to ask the scoping effort
- // to find the active rect for us so we can update the ordinal (n of m).
- locating_active_rect_ = true;
- } else {
- if (old_active_frame != this) {
- // If the active frame has changed it means that we have a multi-frame
- // page and we just switch to searching in a new frame. Then we just
- // want to reset the index.
- if (options.forward)
- active_match_index_ = 0;
- else
- active_match_index_ = last_match_count_ - 1;
- } else {
- // We are still the active frame, so increment (or decrement) the
- // |active_match_index|, wrapping if needed (on single frame pages).
- options.forward ? ++active_match_index_ : --active_match_index_;
- if (active_match_index_ + 1 > last_match_count_)
- active_match_index_ = 0;
- if (active_match_index_ + 1 == 0)
- active_match_index_ = last_match_count_ - 1;
- }
- if (selection_rect) {
- WebRect rect = webkit_glue::IntRectToWebRect(
- frame()->view()->convertToContainingWindow(curr_selection_rect));
- rect.x -= frameview()->scrollOffset().width();
- rect.y -= frameview()->scrollOffset().height();
- *selection_rect = rect;
-
- ReportFindInPageSelection(rect,
- active_match_index_ + 1,
- request_id);
- }
- }
- } else {
- // Nothing was found in this frame.
- active_match_ = NULL;
-
- // Erase all previous tickmarks and highlighting.
- InvalidateArea(INVALIDATE_ALL);
- }
-
- return found;
-}
-
-void WebFrameImpl::stopFinding(bool clear_selection) {
- if (!clear_selection)
- SetFindEndstateFocusAndSelection();
- cancelPendingScopingEffort();
-
- // Remove all markers for matches found and turn off the highlighting.
- if (!parent())
- frame()->document()->removeMarkers(WebCore::DocumentMarker::TextMatch);
- frame()->setMarkedTextMatchesAreHighlighted(false);
-
- // Let the frame know that we don't want tickmarks or highlighting anymore.
- InvalidateArea(INVALIDATE_ALL);
-}
-
-void WebFrameImpl::scopeStringMatches(int request_id,
- const WebString& search_text,
- const WebFindOptions& options,
- bool reset) {
- if (!ShouldScopeMatches(search_text))
- return;
-
- WebFrameImpl* main_frame_impl = GetWebViewImpl()->main_frame();
-
- if (reset) {
- // This is a brand new search, so we need to reset everything.
- // Scoping is just about to begin.
- scoping_complete_ = false;
- // Clear highlighting for this frame.
- if (frame()->markedTextMatchesAreHighlighted())
- frame()->page()->unmarkAllTextMatches();
- // Clear the counters from last operation.
- last_match_count_ = 0;
- next_invalidate_after_ = 0;
-
- resume_scoping_from_range_ = NULL;
-
- main_frame_impl->frames_scoping_count_++;
-
- // Now, defer scoping until later to allow find operation to finish quickly.
- ScopeStringMatchesSoon(
- request_id,
- search_text,
- options,
- false); // false=we just reset, so don't do it again.
- return;
- }
-
- WebCore::String webcore_string = webkit_glue::String16ToString(search_text);
-
- RefPtr<Range> search_range(rangeOfContents(frame()->document()));
-
- ExceptionCode ec = 0, ec2 = 0;
- if (resume_scoping_from_range_.get()) {
- // This is a continuation of a scoping operation that timed out and didn't
- // complete last time around, so we should start from where we left off.
- search_range->setStart(resume_scoping_from_range_->startContainer(),
- resume_scoping_from_range_->startOffset(ec2) + 1,
- ec);
- if (ec != 0 || ec2 != 0) {
- if (ec2 != 0) // A non-zero |ec| happens when navigating during search.
- ASSERT_NOT_REACHED();
- return;
- }
- }
-
- // This timeout controls how long we scope before releasing control. This
- // value does not prevent us from running for longer than this, but it is
- // periodically checked to see if we have exceeded our allocated time.
- const double kTimeout = 0.1; // seconds
-
- int match_count = 0;
- bool timeout = false;
- double start_time = currentTime();
- do {
- // Find next occurrence of the search string.
- // TODO(finnur): (http://b/1088245) This WebKit operation may run
- // for longer than the timeout value, and is not interruptible as it is
- // currently written. We may need to rewrite it with interruptibility in
- // mind, or find an alternative.
- RefPtr<Range> result_range(findPlainText(search_range.get(),
- webcore_string,
- true,
- options.matchCase));
- if (result_range->collapsed(ec)) {
- if (!result_range->startContainer()->isInShadowTree())
- break;
-
- search_range = rangeOfContents(frame()->document());
- search_range->setStartAfter(
- result_range->startContainer()->shadowAncestorNode(), ec);
- continue;
- }
-
- // A non-collapsed result range can in some funky whitespace cases still not
- // advance the range's start position (4509328). Break to avoid infinite
- // loop. (This function is based on the implementation of
- // Frame::markAllMatchesForText, which is where this safeguard comes from).
- VisiblePosition new_start = endVisiblePosition(result_range.get(),
- WebCore::DOWNSTREAM);
- if (new_start == startVisiblePosition(search_range.get(),
- WebCore::DOWNSTREAM))
- break;
-
- // Only treat the result as a match if it is visible
- if (frame()->editor()->insideVisibleArea(result_range.get())) {
- ++match_count;
-
- setStart(search_range.get(), new_start);
- Node* shadow_tree_root = search_range->shadowTreeRootNode();
- if (search_range->collapsed(ec) && shadow_tree_root)
- search_range->setEnd(shadow_tree_root,
- shadow_tree_root->childNodeCount(), ec);
-
- // Catch a special case where Find found something but doesn't know what
- // the bounding box for it is. In this case we set the first match we find
- // as the active rect.
- IntRect result_bounds = result_range->boundingBox();
- IntRect active_selection_rect;
- if (locating_active_rect_) {
- active_selection_rect = active_match_.get() ?
- active_match_->boundingBox() : result_bounds;
- }
-
- // If the Find function found a match it will have stored where the
- // match was found in active_selection_rect_ on the current frame. If we
- // find this rect during scoping it means we have found the active
- // tickmark.
- bool found_active_match = false;
- if (locating_active_rect_ && (active_selection_rect == result_bounds)) {
- // We have found the active tickmark frame.
- main_frame_impl->active_match_frame_ = this;
- found_active_match = true;
- // We also know which tickmark is active now.
- active_match_index_ = match_count - 1;
- // To stop looking for the active tickmark, we set this flag.
- locating_active_rect_ = false;
-
- // Notify browser of new location for the selected rectangle.
- result_bounds.move(-frameview()->scrollOffset().width(),
- -frameview()->scrollOffset().height());
- ReportFindInPageSelection(
- webkit_glue::IntRectToWebRect(
- frame()->view()->convertToContainingWindow(result_bounds)),
- active_match_index_ + 1,
- request_id);
- }
-
- AddMarker(result_range.get(), found_active_match);
- }
-
- resume_scoping_from_range_ = result_range;
- timeout = (currentTime() - start_time) >= kTimeout;
- } while (!timeout);
-
- // Remember what we search for last time, so we can skip searching if more
- // letters are added to the search string (and last outcome was 0).
- last_search_string_ = search_text;
-
- if (match_count > 0) {
- frame()->setMarkedTextMatchesAreHighlighted(true);
-
- last_match_count_ += match_count;
-
- // Let the mainframe know how much we found during this pass.
- main_frame_impl->increaseMatchCount(match_count, request_id);
- }
-
- if (timeout) {
- // If we found anything during this pass, we should redraw. However, we
- // don't want to spam too much if the page is extremely long, so if we
- // reach a certain point we start throttling the redraw requests.
- if (match_count > 0)
- InvalidateIfNecessary();
-
- // Scoping effort ran out of time, lets ask for another time-slice.
- ScopeStringMatchesSoon(
- request_id,
- search_text,
- options,
- false); // don't reset.
- return; // Done for now, resume work later.
- }
-
- // This frame has no further scoping left, so it is done. Other frames might,
- // of course, continue to scope matches.
- scoping_complete_ = true;
- main_frame_impl->frames_scoping_count_--;
-
- // If this is the last frame to finish scoping we need to trigger the final
- // update to be sent.
- if (main_frame_impl->frames_scoping_count_ == 0)
- main_frame_impl->increaseMatchCount(0, request_id);
-
- // This frame is done, so show any scrollbar tickmarks we haven't drawn yet.
- InvalidateArea(INVALIDATE_SCROLLBAR);
-}
-
-void WebFrameImpl::cancelPendingScopingEffort() {
- deleteAllValues(deferred_scoping_work_);
- deferred_scoping_work_.clear();
-
- active_match_index_ = -1;
-}
-
-void WebFrameImpl::increaseMatchCount(int count, int request_id) {
- // This function should only be called on the mainframe.
- ASSERT(!parent());
-
- total_matchcount_ += count;
-
- // Update the UI with the latest findings.
- if (client()) {
- client()->reportFindInPageMatchCount(
- request_id, total_matchcount_, frames_scoping_count_ == 0);
- }
-}
-
-void WebFrameImpl::ReportFindInPageSelection(const WebRect& selection_rect,
- int active_match_ordinal,
- int request_id) {
- // Update the UI with the latest selection rect.
- if (client()) {
- client()->reportFindInPageSelection(
- request_id, OrdinalOfFirstMatchForFrame(this) + active_match_ordinal,
- selection_rect);
- }
-}
-
-void WebFrameImpl::resetMatchCount() {
- total_matchcount_ = 0;
- frames_scoping_count_ = 0;
-}
-
-WebURL WebFrameImpl::completeURL(const WebString& url) const {
- if (!frame_ || !frame_->document())
- return WebURL();
-
- return webkit_glue::KURLToWebURL(
- frame_->document()->completeURL(webkit_glue::WebStringToString(url)));
-}
-
-WebString WebFrameImpl::contentAsText(size_t max_chars) const {
- if (!frame_)
- return WebString();
-
- Vector<UChar> text;
- FrameContentAsPlainText(max_chars, frame_, &text);
- return webkit_glue::StringToWebString(String::adopt(text));
-}
-
-WebString WebFrameImpl::contentAsMarkup() const {
- return webkit_glue::StringToWebString(createFullMarkup(frame_->document()));
-}
-
-// WebFrameImpl public ---------------------------------------------------------
-
-int WebFrameImpl::live_object_count_ = 0;
-
-PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) {
- return adoptRef(new WebFrameImpl(ClientHandle::create(client)));
-}
-
-WebFrameImpl::WebFrameImpl(PassRefPtr<ClientHandle> client_handle)
- : ALLOW_THIS_IN_INITIALIZER_LIST(frame_loader_client_(this)),
- client_handle_(client_handle),
- active_match_frame_(NULL),
- active_match_index_(-1),
- locating_active_rect_(false),
- resume_scoping_from_range_(NULL),
- last_match_count_(-1),
- total_matchcount_(-1),
- frames_scoping_count_(-1),
- scoping_complete_(false),
- next_invalidate_after_(0) {
- ChromiumBridge::incrementStatsCounter(kWebFrameActiveCount);
- live_object_count_++;
-}
-
-WebFrameImpl::~WebFrameImpl() {
- ChromiumBridge::decrementStatsCounter(kWebFrameActiveCount);
- live_object_count_--;
-
- cancelPendingScopingEffort();
- ClearPasswordListeners();
-}
-
-void WebFrameImpl::InitMainFrame(WebViewImpl* webview_impl) {
- RefPtr<Frame> frame =
- Frame::create(webview_impl->page(), 0, &frame_loader_client_);
- frame_ = frame.get();
-
- // Add reference on behalf of FrameLoader. See comments in
- // WebFrameLoaderClient::frameLoaderDestroyed for more info.
- ref();
-
- // We must call init() after frame_ is assigned because it is referenced
- // during init().
- frame_->init();
-}
-
-PassRefPtr<Frame> WebFrameImpl::CreateChildFrame(
- const FrameLoadRequest& request, HTMLFrameOwnerElement* owner_element) {
- // TODO(darin): share code with initWithName()
-
- RefPtr<WebFrameImpl> webframe(adoptRef(new WebFrameImpl(client_handle_)));
-
- // Add an extra ref on behalf of the Frame/FrameLoader, which references the
- // WebFrame via the FrameLoaderClient interface. See the comment at the top
- // of this file for more info.
- webframe->ref();
-
- RefPtr<Frame> child_frame = Frame::create(
- frame_->page(), owner_element, &webframe->frame_loader_client_);
- webframe->frame_ = child_frame.get();
-
- child_frame->tree()->setName(request.frameName());
-
- frame_->tree()->appendChild(child_frame);
-
- // 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
- // so that webframe->frame_ is in the tree before triggering
- // onload event handler.
- // Because the event handler may set webframe->frame_ to null,
- // it is necessary to check the value after calling init() and
- // return without loading URL.
- // (b:791612)
- child_frame->init(); // create an empty document
- if (!child_frame->tree()->parent())
- return NULL;
-
- frame_->loader()->loadURLIntoChildFrame(
- request.resourceRequest().url(),
- request.resourceRequest().httpReferrer(),
- child_frame.get());
-
- // 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.
- if (!child_frame->tree()->parent())
- return NULL;
-
- return child_frame.release();
-}
-
-void WebFrameImpl::Layout() {
- // layout this frame
- FrameView* view = frame_->view();
- if (view)
- view->layoutIfNeededRecursive();
-}
-
-void WebFrameImpl::Paint(WebCanvas* canvas, const WebRect& rect) {
- if (rect.isEmpty())
- return;
- IntRect dirty_rect(webkit_glue::WebRectToIntRect(rect));
-#if WEBKIT_USING_CG
- GraphicsContext gc(canvas);
- WebCore::LocalCurrentGraphicsContext localContext(&gc);
-#elif WEBKIT_USING_SKIA
- PlatformContextSkia context(canvas);
-
- // PlatformGraphicsContext is actually a pointer to PlatformContextSkia
- GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context));
-#else
- notImplemented();
-#endif
- gc.save();
- if (frame_->document() && frameview()) {
- gc.clip(dirty_rect);
- frameview()->paint(&gc, dirty_rect);
- frame_->page()->inspectorController()->drawNodeHighlight(gc);
- } else {
- gc.fillRect(dirty_rect, Color::white);
- }
- gc.restore();
-}
-
-void WebFrameImpl::CreateFrameView() {
- ASSERT(frame_); // If frame_ doesn't exist, we probably didn't init properly.
-
- WebCore::Page* page = frame_->page();
- ASSERT(page);
-
- ASSERT(page->mainFrame() != NULL);
-
- bool is_main_frame = frame_ == page->mainFrame();
- if (is_main_frame && frame_->view())
- frame_->view()->setParentVisible(false);
-
- frame_->setView(0);
-
- WebViewImpl* web_view = GetWebViewImpl();
-
- RefPtr<WebCore::FrameView> view;
- if (is_main_frame) {
- IntSize size = webkit_glue::WebSizeToIntSize(web_view->size());
- view = FrameView::create(frame_, size);
- } else {
- view = FrameView::create(frame_);
- }
-
- frame_->setView(view);
-
- if (web_view->isTransparent())
- view->setTransparent(true);
-
- // TODO(darin): The Mac code has a comment about this possibly being
- // unnecessary. See installInFrame in WebCoreFrameBridge.mm
- if (frame_->ownerRenderer())
- frame_->ownerRenderer()->setWidget(view.get());
-
- if (HTMLFrameOwnerElement* owner = frame_->ownerElement()) {
- view->setCanHaveScrollbars(
- owner->scrollingMode() != WebCore::ScrollbarAlwaysOff);
- }
-
- if (is_main_frame)
- view->setParentVisible(true);
-}
-
-// static
-WebFrameImpl* WebFrameImpl::FromFrame(WebCore::Frame* frame) {
- if (!frame)
- return NULL;
- return static_cast<WebFrameLoaderClient*>(
- frame->loader()->client())->webframe();
-}
-
-WebViewImpl* WebFrameImpl::GetWebViewImpl() const {
- if (!frame_)
- return NULL;
-
- return WebViewImpl::FromPage(frame_->page());
-}
-
-WebDataSourceImpl* WebFrameImpl::GetDataSourceImpl() const {
- return static_cast<WebDataSourceImpl*>(dataSource());
-}
-
-WebDataSourceImpl* WebFrameImpl::GetProvisionalDataSourceImpl() const {
- return static_cast<WebDataSourceImpl*>(provisionalDataSource());
-}
-
-void WebFrameImpl::SetFindEndstateFocusAndSelection() {
- WebFrameImpl* main_frame_impl = GetWebViewImpl()->main_frame();
-
- if (this == main_frame_impl->active_match_frame() &&
- active_match_.get()) {
- // If the user has set the selection since the match was found, we
- // don't focus anything.
- VisibleSelection selection(frame()->selection()->selection());
- if (!selection.isNone())
- return;
-
- // Try to find the first focusable node up the chain, which will, for
- // example, focus links if we have found text within the link.
- Node* node = active_match_->firstNode();
- while (node && !node->isFocusable() && node != frame()->document())
- node = node->parent();
-
- if (node && node != frame()->document()) {
- // Found a focusable parent node. Set focus to it.
- frame()->document()->setFocusedNode(node);
- } else {
- // Iterate over all the nodes in the range until we find a focusable node.
- // This, for example, sets focus to the first link if you search for
- // text and text that is within one or more links.
- node = active_match_->firstNode();
- while (node && node != active_match_->pastLastNode()) {
- if (node->isFocusable()) {
- frame()->document()->setFocusedNode(node);
- break;
- }
- node = node->traverseNextNode();
- }
- }
- }
-}
-
-void WebFrameImpl::DidFail(const ResourceError& error, bool was_provisional) {
- if (!client())
- return;
- const WebURLError& web_error =
- webkit_glue::ResourceErrorToWebURLError(error);
- if (was_provisional) {
- client()->didFailProvisionalLoad(this, web_error);
- } else {
- client()->didFailLoad(this, web_error);
- }
-}
-
-void WebFrameImpl::SetAllowsScrolling(bool flag) {
- frame_->view()->setCanHaveScrollbars(flag);
-}
-
-void WebFrameImpl::RegisterPasswordListener(
- PassRefPtr<HTMLInputElement> input_element,
- PasswordAutocompleteListener* listener) {
- RefPtr<HTMLInputElement> element = input_element;
- ASSERT(password_listeners_.find(element) == password_listeners_.end());
- password_listeners_.set(element, listener);
-}
-
-PasswordAutocompleteListener* WebFrameImpl::GetPasswordListener(
- HTMLInputElement* input_element) {
- return password_listeners_.get(RefPtr<HTMLInputElement>(input_element));
-}
-
-// WebFrameImpl protected ------------------------------------------------------
-
-void WebFrameImpl::Closing() {
- frame_ = NULL;
-}
-
-// WebFrameImpl private --------------------------------------------------------
-
-void WebFrameImpl::InvalidateArea(AreaToInvalidate area) {
- ASSERT(frame() && frame()->view());
- FrameView* view = frame()->view();
-
- if ((area & INVALIDATE_ALL) == INVALIDATE_ALL) {
- view->invalidateRect(view->frameRect());
- } else {
- if ((area & INVALIDATE_CONTENT_AREA) == INVALIDATE_CONTENT_AREA) {
- IntRect content_area(
- view->x(), view->y(), view->visibleWidth(), view->visibleHeight());
- view->invalidateRect(content_area);
- }
-
- if ((area & INVALIDATE_SCROLLBAR) == INVALIDATE_SCROLLBAR) {
- // Invalidate the vertical scroll bar region for the view.
- IntRect scroll_bar_vert(
- view->x() + view->visibleWidth(), view->y(),
- WebCore::ScrollbarTheme::nativeTheme()->scrollbarThickness(),
- view->visibleHeight());
- view->invalidateRect(scroll_bar_vert);
- }
- }
-}
-
-void WebFrameImpl::AddMarker(WebCore::Range* range, bool active_match) {
- // Use a TextIterator to visit the potentially multiple nodes the range
- // covers.
- TextIterator markedText(range);
- for (; !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
- int exception = 0;
-
- WebCore::DocumentMarker marker = {
- WebCore::DocumentMarker::TextMatch,
- textPiece->startOffset(exception),
- textPiece->endOffset(exception),
- "",
- active_match };
-
- if (marker.endOffset > marker.startOffset) {
- // Find the node to add a marker to and add it.
- Node* node = textPiece->startContainer(exception);
- frame()->document()->addMarker(node, marker);
-
- // Rendered rects for markers in WebKit are not populated until each time
- // the markers are painted. However, we need it to happen sooner, because
- // the whole purpose of tickmarks on the scrollbar is to show where
- // matches off-screen are (that haven't been painted yet).
- Vector<WebCore::DocumentMarker> markers =
- frame()->document()->markersForNode(node);
- frame()->document()->setRenderedRectForMarker(
- textPiece->startContainer(exception),
- markers[markers.size() - 1],
- range->boundingBox());
- }
- }
-}
-
-void WebFrameImpl::SetMarkerActive(WebCore::Range* range, bool active) {
- if (!range)
- return;
-
- frame()->document()->setMarkersActive(range, active);
-}
-
-int WebFrameImpl::OrdinalOfFirstMatchForFrame(WebFrameImpl* frame) const {
- int ordinal = 0;
- WebFrameImpl* main_frame_impl = GetWebViewImpl()->main_frame();
- // Iterate from the main frame up to (but not including) |frame| and
- // add up the number of matches found so far.
- for (WebFrameImpl* it = main_frame_impl;
- it != frame;
- it = static_cast<WebFrameImpl*>(it->traverseNext(true))) {
- if (it->last_match_count_ > 0)
- ordinal += it->last_match_count_;
- }
-
- return ordinal;
-}
-
-bool WebFrameImpl::ShouldScopeMatches(const string16& search_text) {
- // Don't scope if we can't find a frame or if the frame is not visible.
- // The user may have closed the tab/application, so abort.
- if (!frame() || !hasVisibleContent())
- return false;
-
- ASSERT(frame()->document() && frame()->view());
-
- // If the frame completed the scoping operation and found 0 matches the last
- // time it was searched, then we don't have to search it again if the user is
- // just adding to the search string or sending the same search string again.
- if (scoping_complete_ &&
- !last_search_string_.empty() && last_match_count_ == 0) {
- // Check to see if the search string prefixes match.
- string16 previous_search_prefix =
- search_text.substr(0, last_search_string_.length());
-
- if (previous_search_prefix == last_search_string_) {
- return false; // Don't search this frame, it will be fruitless.
- }
- }
-
- return true;
-}
-
-void WebFrameImpl::ScopeStringMatchesSoon(
- int identifier, const WebString& search_text,
- const WebFindOptions& options, bool reset) {
- deferred_scoping_work_.append(new DeferredScopeStringMatches(
- this, identifier, search_text, options, reset));
-}
-
-void WebFrameImpl::CallScopeStringMatches(
- DeferredScopeStringMatches* caller, int identifier,
- const WebString& search_text, const WebFindOptions& options, bool reset) {
- deferred_scoping_work_.remove(deferred_scoping_work_.find(caller));
-
- scopeStringMatches(identifier, search_text, options, reset);
-
- // This needs to happen last since search_text is passed by reference.
- delete caller;
-}
-
-void WebFrameImpl::InvalidateIfNecessary() {
- if (last_match_count_ > next_invalidate_after_) {
- // TODO(finnur): (http://b/1088165) Optimize the drawing of the
- // tickmarks and remove this. This calculation sets a milestone for when
- // next to invalidate the scrollbar and the content area. We do this so that
- // we don't spend too much time drawing the scrollbar over and over again.
- // Basically, up until the first 500 matches there is no throttle. After the
- // first 500 matches, we set set the milestone further and further out (750,
- // 1125, 1688, 2K, 3K).
- static const int start_slowing_down_after = 500;
- static const int slowdown = 750;
- int i = (last_match_count_ / start_slowing_down_after);
- next_invalidate_after_ += i * slowdown;
-
- InvalidateArea(INVALIDATE_SCROLLBAR);
- }
-}
-
-void WebFrameImpl::ClearPasswordListeners() {
- for (PasswordListenerMap::iterator iter = password_listeners_.begin();
- iter != password_listeners_.end(); ++iter) {
- delete iter->second;
- }
- password_listeners_.clear();
-}
-
-void WebFrameImpl::LoadJavaScriptURL(const KURL& url) {
- // This is copied from FrameLoader::executeIfJavaScriptURL. Unfortunately,
- // we cannot just use that method since it is private, and it also doesn't
- // quite behave as we require it to for bookmarklets. The key difference is
- // that we need to suppress loading the string result from evaluating the JS
- // URL if executing the JS URL resulted in a location change. We also allow
- // a JS URL to be loaded even if scripts on the page are otherwise disabled.
-
- if (!frame_->document() || !frame_->page())
- return;
-
- String script =
- decodeURLEscapeSequences(url.string().substring(strlen("javascript:")));
- ScriptValue result = frame_->script()->executeScript(script, true);
-
- String script_result;
- if (!result.getString(script_result))
- return;
-
- SecurityOrigin* security_origin = frame_->document()->securityOrigin();
-
- if (!frame_->redirectScheduler()->locationChangePending()) {
- frame_->loader()->stopAllLoaders();
- frame_->loader()->begin(frame_->loader()->url(), true, security_origin);
- frame_->loader()->write(script_result);
- frame_->loader()->end();
- }
-}
diff --git a/webkit/glue/webframe_impl.h b/webkit/glue/webframe_impl.h
deleted file mode 100644
index f1d0548..0000000
--- a/webkit/glue/webframe_impl.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WEBKIT_GLUE_WEBFRAME_IMPL_H_
-#define WEBKIT_GLUE_WEBFRAME_IMPL_H_
-
-#include "Frame.h"
-#include "PlatformString.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/RefCounted.h>
-
-#include "webkit/api/public/WebFrame.h"
-#include "webkit/glue/webframeloaderclient_impl.h"
-
-class ChromePrintContext;
-class WebViewImpl;
-
-namespace gfx {
-class BitmapPlatformDevice;
-}
-
-namespace WebCore {
-class HistoryItem;
-class KURL;
-class Node;
-class Range;
-class SubstituteData;
-struct WindowFeatures;
-}
-
-namespace WebKit {
-class PasswordAutocompleteListener;
-class WebDataSourceImpl;
-class WebFrameClient;
-class WebView;
-}
-
-// Implementation of WebFrame, note that this is a reference counted object.
-class WebFrameImpl : public WebKit::WebFrame, public RefCounted<WebFrameImpl> {
- public:
- // WebFrame methods:
- virtual WebKit::WebString name() const;
- virtual WebKit::WebURL url() const;
- virtual WebKit::WebURL favIconURL() const;
- virtual WebKit::WebURL openSearchDescriptionURL() const;
- virtual WebKit::WebSize scrollOffset() const;
- virtual WebKit::WebSize contentsSize() const;
- virtual int contentsPreferredWidth() const;
- virtual bool hasVisibleContent() const;
- virtual WebKit::WebView* view() const;
- virtual WebKit::WebFrame* opener() const;
- virtual WebKit::WebFrame* parent() const;
- virtual WebKit::WebFrame* top() const;
- virtual WebKit::WebFrame* firstChild() const;
- virtual WebKit::WebFrame* lastChild() const;
- virtual WebKit::WebFrame* nextSibling() const;
- virtual WebKit::WebFrame* previousSibling() const;
- virtual WebKit::WebFrame* traverseNext(bool wrap) const;
- virtual WebKit::WebFrame* traversePrevious(bool wrap) const;
- virtual WebKit::WebFrame* findChildByName(const WebKit::WebString& name) const;
- virtual WebKit::WebFrame* findChildByExpression(
- const WebKit::WebString& xpath) const;
- virtual void forms(WebKit::WebVector<WebKit::WebForm>&) const;
- virtual WebKit::WebSecurityOrigin securityOrigin() const;
- virtual void grantUniversalAccess();
- virtual NPObject* windowObject() const;
- virtual void bindToWindowObject(
- const WebKit::WebString& name, NPObject* object);
- virtual void executeScript(const WebKit::WebScriptSource&);
- virtual void executeScriptInNewContext(
- const WebKit::WebScriptSource* sources, unsigned num_sources,
- int extension_group);
- virtual void executeScriptInIsolatedWorld(
- int world_id, const WebKit::WebScriptSource* sources,
- unsigned num_sources, int extension_group);
- virtual void addMessageToConsole(const WebKit::WebConsoleMessage&);
- virtual void collectGarbage();
-#if WEBKIT_USING_V8
- virtual v8::Local<v8::Context> mainWorldScriptContext() const;
-#endif
- virtual bool insertStyleText(
- const WebKit::WebString& css, const WebKit::WebString& id);
- virtual void reload();
- virtual void loadRequest(const WebKit::WebURLRequest& request);
- virtual void loadHistoryItem(const WebKit::WebHistoryItem& history_item);
- virtual void loadData(
- const WebKit::WebData& data, const WebKit::WebString& mime_type,
- const WebKit::WebString& text_encoding, const WebKit::WebURL& base_url,
- const WebKit::WebURL& unreachable_url, bool replace);
- virtual void loadHTMLString(
- const WebKit::WebData& html, const WebKit::WebURL& base_url,
- const WebKit::WebURL& unreachable_url, bool replace);
- virtual bool isLoading() const;
- virtual void stopLoading();
- virtual WebKit::WebDataSource* provisionalDataSource() const;
- virtual WebKit::WebDataSource* dataSource() const;
- virtual WebKit::WebHistoryItem previousHistoryItem() const;
- virtual WebKit::WebHistoryItem currentHistoryItem() const;
- virtual void enableViewSourceMode(bool enable);
- virtual bool isViewSourceModeEnabled() const;
- virtual void setReferrerForRequest(
- WebKit::WebURLRequest& request, const WebKit::WebURL& referrer);
- virtual void dispatchWillSendRequest(WebKit::WebURLRequest& request);
- virtual void commitDocumentData(const char* data, size_t length);
- virtual unsigned unloadListenerCount() const;
- virtual bool isProcessingUserGesture() const;
- virtual bool willSuppressOpenerInNewFrame() const;
- virtual void replaceSelection(const WebKit::WebString& text);
- virtual void insertText(const WebKit::WebString& text);
- virtual void setMarkedText(
- const WebKit::WebString& text, unsigned location, unsigned length);
- virtual void unmarkText();
- virtual bool hasMarkedText() const;
- virtual WebKit::WebRange markedRange() const;
- virtual bool executeCommand(const WebKit::WebString& command);
- virtual bool executeCommand(
- const WebKit::WebString& command, const WebKit::WebString& value);
- virtual bool isCommandEnabled(const WebKit::WebString& command) const;
- virtual void enableContinuousSpellChecking(bool enable);
- virtual bool isContinuousSpellCheckingEnabled() const;
- virtual bool hasSelection() const;
- virtual WebKit::WebRange selectionRange() const;
- virtual WebKit::WebString selectionAsText() const;
- virtual WebKit::WebString selectionAsMarkup() const;
- virtual int printBegin(const WebKit::WebSize& page_size);
- virtual float printPage(int page_to_print, WebKit::WebCanvas* canvas);
- virtual float getPrintPageShrink(int page);
- virtual void printEnd();
- virtual bool find(
- int identifier, const WebKit::WebString& search_text,
- const WebKit::WebFindOptions& options, bool wrap_within_frame,
- WebKit::WebRect* selection_rect);
- virtual void stopFinding(bool clear_selection);
- virtual void scopeStringMatches(
- int identifier, const WebKit::WebString& search_text,
- const WebKit::WebFindOptions& options, bool reset);
- virtual void cancelPendingScopingEffort();
- virtual void increaseMatchCount(int count, int identifier);
- virtual void resetMatchCount();
- virtual WebKit::WebURL completeURL(const WebKit::WebString& url) const;
- virtual WebKit::WebString contentAsText(size_t max_chars) const;
- virtual WebKit::WebString contentAsMarkup() const;
-
- static PassRefPtr<WebFrameImpl> create(WebKit::WebFrameClient* client);
- ~WebFrameImpl();
-
- static int live_object_count() {
- return live_object_count_;
- }
-
- // Called by the WebViewImpl to initialize its main frame:
- void InitMainFrame(WebViewImpl* webview_impl);
-
- PassRefPtr<WebCore::Frame> CreateChildFrame(
- const WebCore::FrameLoadRequest&,
- WebCore::HTMLFrameOwnerElement* owner_element);
-
- void Layout();
- void Paint(WebKit::WebCanvas* canvas, const WebKit::WebRect& rect);
-
- void CreateFrameView();
-
- WebCore::Frame* frame() const {
- return frame_;
- }
-
- static WebFrameImpl* FromFrame(WebCore::Frame* frame);
-
- WebViewImpl* GetWebViewImpl() const;
-
- WebCore::FrameView* frameview() const {
- return frame_ ? frame_->view() : NULL;
- }
-
- // Getters for the impls corresponding to Get(Provisional)DataSource. They
- // may return NULL if there is no corresponding data source.
- WebKit::WebDataSourceImpl* GetDataSourceImpl() const;
- WebKit::WebDataSourceImpl* GetProvisionalDataSourceImpl() const;
-
- // Returns which frame has an active match. This function should only be
- // called on the main frame, as it is the only frame keeping track. Returned
- // value can be NULL if no frame has an active match.
- const WebFrameImpl* active_match_frame() const {
- return active_match_frame_;
- }
-
- // When a Find operation ends, we want to set the selection to what was active
- // and set focus to the first focusable node we find (starting with the first
- // node in the matched range and going up the inheritance chain). If we find
- // nothing to focus we focus the first focusable node in the range. This
- // allows us to set focus to a link (when we find text inside a link), which
- // allows us to navigate by pressing Enter after closing the Find box.
- void SetFindEndstateFocusAndSelection();
-
- void DidFail(const WebCore::ResourceError& error, bool was_provisional);
-
- // Sets whether the WebFrameImpl allows its document to be scrolled.
- // If the parameter is true, allow the document to be scrolled.
- // Otherwise, disallow scrolling.
- void SetAllowsScrolling(bool flag);
-
- // Registers a listener for the specified user name input element. The
- // listener will receive notifications for blur and when autocomplete should
- // be triggered.
- // The WebFrameImpl becomes the owner of the passed listener.
- void RegisterPasswordListener(
- PassRefPtr<WebCore::HTMLInputElement> user_name_input_element,
- WebKit::PasswordAutocompleteListener* listener);
-
- // Returns the password autocomplete listener associated with the passed
- // user name input element, or NULL if none available.
- // Note that the returned listener is owner by the WebFrameImpl and should not
- // be kept around as it is deleted when the page goes away.
- WebKit::PasswordAutocompleteListener* GetPasswordListener(
- WebCore::HTMLInputElement* user_name_input_element);
-
- WebKit::WebFrameClient* client() const { return client_handle_->client(); }
- void drop_client() { client_handle_->drop_client(); }
-
- protected:
- friend class WebFrameLoaderClient;
-
- // A weak reference to the WebFrameClient. Each WebFrame in the hierarchy
- // owns a reference to a ClientHandle. When the main frame is destroyed, it
- // clears the WebFrameClient.
- class ClientHandle : public RefCounted<ClientHandle> {
- public:
- static PassRefPtr<ClientHandle> create(WebKit::WebFrameClient* client) {
- return adoptRef(new ClientHandle(client));
- }
- WebKit::WebFrameClient* client() { return client_; }
- void drop_client() { client_ = NULL; }
- private:
- ClientHandle(WebKit::WebFrameClient* client) : client_(client) {}
- WebKit::WebFrameClient* client_;
- };
-
- WebFrameImpl(PassRefPtr<ClientHandle> client_handle);
-
- // Informs the WebFrame that the Frame is being closed, called by the
- // WebFrameLoaderClient
- void Closing();
-
- // Used to check for leaks of this object.
- static int live_object_count_;
-
- WebFrameLoaderClient frame_loader_client_;
-
- RefPtr<ClientHandle> client_handle_;
-
- // This is a weak pointer to our corresponding WebCore frame. A reference to
- // ourselves is held while frame_ is valid. See our Closing method.
- WebCore::Frame* frame_;
-
- // A way for the main frame to keep track of which frame has an active
- // match. Should be NULL for all other frames.
- WebFrameImpl* active_match_frame_;
-
- // The range of the active match for the current frame.
- RefPtr<WebCore::Range> active_match_;
-
- // The index of the active match.
- int active_match_index_;
-
- // This flag is used by the scoping effort to determine if we need to figure
- // out which rectangle is the active match. Once we find the active
- // rectangle we clear this flag.
- bool locating_active_rect_;
-
- // The scoping effort can time out and we need to keep track of where we
- // ended our last search so we can continue from where we left of.
- RefPtr<WebCore::Range> resume_scoping_from_range_;
-
- // Keeps track of the last string this frame searched for. This is used for
- // short-circuiting searches in the following scenarios: When a frame has
- // been searched and returned 0 results, we don't need to search that frame
- // again if the user is just adding to the search (making it more specific).
- string16 last_search_string_;
-
- // Keeps track of how many matches this frame has found so far, so that we
- // don't loose count between scoping efforts, and is also used (in conjunction
- // with last_search_string_ and scoping_complete_) to figure out if we need to
- // search the frame again.
- int last_match_count_;
-
- // This variable keeps a cumulative total of matches found so far for ALL the
- // frames on the page, and is only incremented by calling IncreaseMatchCount
- // (on the main frame only). It should be -1 for all other frames.
- size_t total_matchcount_;
-
- // This variable keeps a cumulative total of how many frames are currently
- // scoping, and is incremented/decremented on the main frame only.
- // It should be -1 for all other frames.
- int frames_scoping_count_;
-
- // Keeps track of whether the scoping effort was completed (the user may
- // interrupt it before it completes by submitting a new search).
- bool scoping_complete_;
-
- // Keeps track of when the scoping effort should next invalidate the scrollbar
- // and the frame area.
- int next_invalidate_after_;
-
- private:
- class DeferredScopeStringMatches;
- friend class DeferredScopeStringMatches;
-
- // A bit mask specifying area of the frame to invalidate.
- enum AreaToInvalidate {
- INVALIDATE_NOTHING = 0,
- INVALIDATE_CONTENT_AREA = 1,
- INVALIDATE_SCROLLBAR = 2, // vertical scrollbar only.
- INVALIDATE_ALL = 3 // both content area and the scrollbar.
- };
-
- // Notifies the delegate about a new selection rect.
- void ReportFindInPageSelection(
- const WebKit::WebRect& selection_rect, int active_match_ordinal,
- int identifier);
-
- // Invalidates a certain area within the frame.
- void InvalidateArea(AreaToInvalidate area);
-
- // Add a WebKit TextMatch-highlight marker to nodes in a range.
- void AddMarker(WebCore::Range* range, bool active_match);
-
- // Sets the markers within a range as active or inactive.
- void SetMarkerActive(WebCore::Range* range, bool active);
-
- // Returns the ordinal of the first match in the frame specified. This
- // function enumerates the frames, starting with the main frame and up to (but
- // not including) the frame passed in as a parameter and counts how many
- // matches have been found.
- int OrdinalOfFirstMatchForFrame(WebFrameImpl* frame) const;
-
- // Determines whether the scoping effort is required for a particular frame.
- // It is not necessary if the frame is invisible, for example, or if this
- // is a repeat search that already returned nothing last time the same prefix
- // was searched.
- bool ShouldScopeMatches(const string16& search_text);
-
- // Queue up a deferred call to scopeStringMatches.
- void ScopeStringMatchesSoon(
- int identifier, const WebKit::WebString& search_text,
- const WebKit::WebFindOptions& options, bool reset);
-
- // Called by a DeferredScopeStringMatches instance.
- void CallScopeStringMatches(
- DeferredScopeStringMatches* deferred,
- int identifier, const WebKit::WebString& search_text,
- const WebKit::WebFindOptions& options, bool reset);
-
- // Determines whether to invalidate the content area and scrollbar.
- void InvalidateIfNecessary();
-
- // Clears the map of password listeners.
- void ClearPasswordListeners();
-
- void LoadJavaScriptURL(const WebCore::KURL& url);
-
- // A list of all of the pending calls to scopeStringMatches.
- Vector<DeferredScopeStringMatches*> deferred_scoping_work_;
-
- // Valid between calls to BeginPrint() and EndPrint(). Containts the print
- // information. Is used by PrintPage().
- OwnPtr<ChromePrintContext> print_context_;
-
- // The input fields that are interested in edit events and their associated
- // listeners.
- typedef HashMap<RefPtr<WebCore::HTMLInputElement>,
- WebKit::PasswordAutocompleteListener*> PasswordListenerMap;
- PasswordListenerMap password_listeners_;
-};
-
-#endif // WEBKIT_GLUE_WEBFRAME_IMPL_H_
diff --git a/webkit/glue/webframeloaderclient_impl.cc b/webkit/glue/webframeloaderclient_impl.cc
deleted file mode 100644
index ab4dbb7..0000000
--- a/webkit/glue/webframeloaderclient_impl.cc
+++ /dev/null
@@ -1,1339 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "config.h"
-
-#include "Chrome.h"
-#include "CString.h"
-#include "Document.h"
-#include "DocumentLoader.h"
-#include "HTMLAppletElement.h"
-#include "HTMLFormElement.h" // needed by FormState.h
-#include "HTMLNames.h"
-#include "FormState.h"
-#include "FrameLoader.h"
-#include "FrameLoadRequest.h"
-#include "HitTestResult.h"
-#include "MIMETypeRegistry.h"
-#include "MouseEvent.h"
-#include "Page.h"
-#include "PlatformString.h"
-#include "PluginData.h"
-#include "StringExtras.h"
-#include "WindowFeatures.h"
-#undef LOG
-
-#include "net/base/mime_util.h"
-#include "webkit/api/public/WebForm.h"
-#include "webkit/api/public/WebFrameClient.h"
-#include "webkit/api/public/WebNode.h"
-#include "webkit/api/public/WebPlugin.h"
-#include "webkit/api/public/WebPluginParams.h"
-#include "webkit/api/public/WebSecurityOrigin.h"
-#include "webkit/api/public/WebURL.h"
-#include "webkit/api/public/WebURLError.h"
-#include "webkit/api/public/WebVector.h"
-#include "webkit/api/public/WebViewClient.h"
-#include "webkit/api/src/WebDataSourceImpl.h"
-#include "webkit/api/src/WebPluginContainerImpl.h"
-#include "webkit/api/src/WebPluginLoadObserver.h"
-#include "webkit/api/src/WrappedResourceRequest.h"
-#include "webkit/api/src/WrappedResourceResponse.h"
-#include "webkit/glue/glue_util.h"
-#include "webkit/glue/webdevtoolsagent_impl.h"
-#include "webkit/glue/webframe_impl.h"
-#include "webkit/glue/webframeloaderclient_impl.h"
-#include "webkit/glue/webkit_glue.h"
-#include "webkit/glue/webview_impl.h"
-
-using namespace WebCore;
-
-using WebKit::WebData;
-using WebKit::WebDataSourceImpl;
-using WebKit::WebNavigationType;
-using WebKit::WebNavigationPolicy;
-using WebKit::WebNode;
-using WebKit::WebPlugin;
-using WebKit::WebPluginContainerImpl;
-using WebKit::WebPluginLoadObserver;
-using WebKit::WebPluginParams;
-using WebKit::WebString;
-using WebKit::WebURL;
-using WebKit::WebURLError;
-using WebKit::WebURLRequest;
-using WebKit::WebVector;
-using WebKit::WrappedResourceRequest;
-using WebKit::WrappedResourceResponse;
-
-// Domain for internal error codes.
-static const char kInternalErrorDomain[] = "WebKit";
-
-// An internal error code. Used to note a policy change error resulting from
-// dispatchDecidePolicyForMIMEType not passing the PolicyUse option.
-enum {
- ERR_POLICY_CHANGE = -10000,
-};
-
-static void CopyStringVector(
- const Vector<String>& input, WebVector<WebString>* output) {
- WebVector<WebString> result(input.size());
- for (size_t i = 0; i < input.size(); ++i)
- result[i] = webkit_glue::StringToWebString(input[i]);
- output->swap(result);
-}
-
-WebFrameLoaderClient::WebFrameLoaderClient(WebFrameImpl* frame)
- : webframe_(frame),
- has_representation_(false),
- sent_initial_response_to_plugin_(false),
- next_navigation_policy_(WebKit::WebNavigationPolicyIgnore) {
-}
-
-WebFrameLoaderClient::~WebFrameLoaderClient() {
-}
-
-void WebFrameLoaderClient::frameLoaderDestroyed() {
- // When the WebFrame was created, it had an extra reference given to it on
- // behalf of the Frame. Since the WebFrame owns us, this extra ref also
- // serves to keep us alive until the FrameLoader is done with us. The
- // FrameLoader calls this method when it's going away. Therefore, we balance
- // out that extra reference, which may cause 'this' to be deleted.
- webframe_->Closing();
- webframe_->deref();
-}
-
-void WebFrameLoaderClient::windowObjectCleared() {
- if (webframe_->client())
- webframe_->client()->didClearWindowObject(webframe_);
-
- WebViewImpl* webview = webframe_->GetWebViewImpl();
- if (webview) {
- WebDevToolsAgentImpl* tools_agent = webview->GetWebDevToolsAgentImpl();
- if (tools_agent)
- tools_agent->WindowObjectCleared(webframe_);
- }
-}
-
-void WebFrameLoaderClient::documentElementAvailable() {
- if (webframe_->client())
- webframe_->client()->didCreateDocumentElement(webframe_);
-}
-
-void WebFrameLoaderClient::didCreateScriptContextForFrame() {
- if (webframe_->client())
- webframe_->client()->didCreateScriptContext(webframe_);
-}
-
-void WebFrameLoaderClient::didDestroyScriptContextForFrame() {
- if (webframe_->client())
- webframe_->client()->didDestroyScriptContext(webframe_);
-}
-
-void WebFrameLoaderClient::didCreateIsolatedScriptContext() {
- if (webframe_->client())
- webframe_->client()->didCreateIsolatedScriptContext(webframe_);
-}
-
-void WebFrameLoaderClient::didPerformFirstNavigation() const {
-}
-
-void WebFrameLoaderClient::registerForIconNotification(bool listen){
-}
-
-bool WebFrameLoaderClient::hasWebView() const {
- return webframe_->GetWebViewImpl() != NULL;
-}
-
-bool WebFrameLoaderClient::hasFrameView() const {
- // The Mac port has this notion of a WebFrameView, which seems to be
- // some wrapper around an NSView. Since our equivalent is HWND, I guess
- // we have a "frameview" whenever we have the toplevel HWND.
- return webframe_->GetWebViewImpl() != NULL;
-}
-
-void WebFrameLoaderClient::makeDocumentView() {
- webframe_->CreateFrameView();
-}
-
-void WebFrameLoaderClient::makeRepresentation(DocumentLoader*) {
- has_representation_ = true;
-}
-
-void WebFrameLoaderClient::forceLayout() {
- // FIXME
-}
-void WebFrameLoaderClient::forceLayoutForNonHTML() {
- // FIXME
-}
-
-void WebFrameLoaderClient::setCopiesOnScroll() {
- // FIXME
-}
-
-void WebFrameLoaderClient::detachedFromParent2() {
- // Nothing to do here.
-}
-
-void WebFrameLoaderClient::detachedFromParent3() {
- // Close down the proxy. The purpose of this change is to make the
- // call to ScriptController::clearWindowShell a no-op when called from
- // Frame::pageDestroyed. Without this change, this call to clearWindowShell
- // will cause a crash. If you remove/modify this, just ensure that you can
- // go to a page and then navigate to a new page without getting any asserts
- // or crashes.
- webframe_->frame()->script()->proxy()->clearForClose();
-}
-
-// This function is responsible for associating the |identifier| with a given
-// subresource load. The following functions that accept an |identifier| are
-// called for each subresource, so they should not be dispatched to the
-// WebFrame.
-void WebFrameLoaderClient::assignIdentifierToInitialRequest(
- unsigned long identifier, DocumentLoader* loader,
- const ResourceRequest& request) {
- if (webframe_->client()) {
- WrappedResourceRequest webreq(request);
- webframe_->client()->assignIdentifierToRequest(
- webframe_, identifier, webreq);
- }
-}
-
-// Determines whether the request being loaded by |loader| is a frame or a
-// subresource. A subresource in this context is anything other than a frame --
-// this includes images and xmlhttp requests. It is important to note that a
-// subresource is NOT limited to stuff loaded through the frame's subresource
-// loader. Synchronous xmlhttp requests for example, do not go through the
-// subresource loader, but we still label them as TargetIsSubResource.
-//
-// The important edge cases to consider when modifying this function are
-// how synchronous resource loads are treated during load/unload threshold.
-static ResourceRequest::TargetType DetermineTargetTypeFromLoader(
- DocumentLoader* loader) {
- if (loader == loader->frameLoader()->provisionalDocumentLoader()) {
- if (loader->frameLoader()->isLoadingMainFrame()) {
- return ResourceRequest::TargetIsMainFrame;
- } else {
- return ResourceRequest::TargetIsSubFrame;
- }
- }
- return ResourceRequest::TargetIsSubResource;
-}
-
-void WebFrameLoaderClient::dispatchWillSendRequest(
- DocumentLoader* loader, unsigned long identifier, ResourceRequest& request,
- const ResourceResponse& redirect_response) {
-
- if (loader) {
- // We want to distinguish between a request for a document to be loaded into
- // the main frame, a sub-frame, or the sub-objects in that document.
- request.setTargetType(DetermineTargetTypeFromLoader(loader));
- }
-
- // FrameLoader::loadEmptyDocumentSynchronously() creates an empty document
- // with no URL. We don't like that, so we'll rename it to about:blank.
- if (request.url().isEmpty())
- request.setURL(KURL(ParsedURLString, "about:blank"));
- if (request.firstPartyForCookies().isEmpty())
- request.setFirstPartyForCookies(KURL(ParsedURLString, "about:blank"));
-
- // Give the WebFrameClient a crack at the request.
- if (webframe_->client()) {
- WrappedResourceRequest webreq(request);
- WrappedResourceResponse webresp(redirect_response);
- webframe_->client()->willSendRequest(
- webframe_, identifier, webreq, webresp);
- }
-}
-
-bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*,
- unsigned long identifier) {
- // FIXME
- // Intended to pass through to a method on the resource load delegate.
- // If implemented, that method controls whether the browser should ask the
- // networking layer for a stored default credential for the page (say from
- // the Mac OS keychain). If the method returns false, the user should be
- // presented with an authentication challenge whether or not the networking
- // layer has a credential stored.
- // This returns true for backward compatibility: the ability to override the
- // system credential store is new. (Actually, not yet fully implemented in
- // WebKit, as of this writing.)
- return true;
-}
-
-void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(
- DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) {
- // FIXME
-}
-
-void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(
- DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) {
- // FIXME
-}
-
-void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader,
- unsigned long identifier,
- const ResourceResponse& response) {
- if (webframe_->client()) {
- WrappedResourceResponse webresp(response);
- webframe_->client()->didReceiveResponse(webframe_, identifier, webresp);
- }
-}
-
-void WebFrameLoaderClient::dispatchDidReceiveContentLength(
- DocumentLoader* loader,
- unsigned long identifier,
- int length_received) {
-}
-
-// Called when a particular resource load completes
-void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader,
- unsigned long identifier) {
- if (webframe_->client())
- webframe_->client()->didFinishResourceLoad(webframe_, identifier);
-}
-
-void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader,
- unsigned long identifier,
- const ResourceError& error) {
- if (webframe_->client()) {
- webframe_->client()->didFailResourceLoad(
- webframe_, identifier, webkit_glue::ResourceErrorToWebURLError(error));
- }
-}
-
-void WebFrameLoaderClient::dispatchDidFinishDocumentLoad() {
- // A frame may be reused. This call ensures we don't hold on to our password
- // listeners and their associated HTMLInputElements.
- webframe_->ClearPasswordListeners();
-
- if (webframe_->client())
- webframe_->client()->didFinishDocumentLoad(webframe_);
-}
-
-bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(
- DocumentLoader* loader,
- const ResourceRequest& request,
- const ResourceResponse& response,
- int length) {
- if (webframe_->client()) {
- WrappedResourceRequest webreq(request);
- WrappedResourceResponse webresp(response);
- webframe_->client()->didLoadResourceFromMemoryCache(
- webframe_, webreq, webresp);
- }
- return false; // Do not suppress remaining notifications
-}
-
-void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(
- unsigned long identifier,
- const ScriptString& source) {
-}
-
-void WebFrameLoaderClient::dispatchDidHandleOnloadEvents() {
- if (webframe_->client())
- webframe_->client()->didHandleOnloadEvents(webframe_);
-}
-
-// Redirect Tracking
-// =================
-// We want to keep track of the chain of redirects that occur during page
-// loading. There are two types of redirects, server redirects which are HTTP
-// response codes, and client redirects which are document.location= and meta
-// refreshes.
-//
-// This outlines the callbacks that we get in different redirect situations,
-// and how each call modifies the redirect chain.
-//
-// Normal page load
-// ----------------
-// dispatchDidStartProvisionalLoad() -> adds URL to the redirect list
-// dispatchDidCommitLoad() -> DISPATCHES & clears list
-//
-// Server redirect (success)
-// -------------------------
-// dispatchDidStartProvisionalLoad() -> adds source URL
-// dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL
-// dispatchDidCommitLoad() -> DISPATCHES
-//
-// Client redirect (success)
-// -------------------------
-// (on page)
-// dispatchWillPerformClientRedirect() -> saves expected redirect
-// dispatchDidStartProvisionalLoad() -> appends redirect source (since
-// it matches the expected redirect)
-// and the current page as the dest)
-// dispatchDidCancelClientRedirect() -> clears expected redirect
-// dispatchDidCommitLoad() -> DISPATCHES
-//
-// Client redirect (cancelled)
-// (e.g meta-refresh trumped by manual doc.location change, or just cancelled
-// because a link was clicked that requires the meta refresh to be rescheduled
-// (the SOURCE URL may have changed).
-// ---------------------------
-// dispatchDidCancelClientRedirect() -> clears expected redirect
-// dispatchDidStartProvisionalLoad() -> adds only URL to redirect list
-// dispatchDidCommitLoad() -> DISPATCHES & clears list
-// rescheduled ? dispatchWillPerformClientRedirect() -> saves expected redirect
-// : nothing
-
-// Client redirect (failure)
-// -------------------------
-// (on page)
-// dispatchWillPerformClientRedirect() -> saves expected redirect
-// dispatchDidStartProvisionalLoad() -> appends redirect source (since
-// it matches the expected redirect)
-// and the current page as the dest)
-// dispatchDidCancelClientRedirect()
-// dispatchDidFailProvisionalLoad()
-//
-// Load 1 -> Server redirect to 2 -> client redirect to 3 -> server redirect to 4
-// ------------------------------------------------------------------------------
-// dispatchDidStartProvisionalLoad() -> adds source URL 1
-// dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL 2
-// dispatchDidCommitLoad() -> DISPATCHES 1+2
-// -- begin client redirect and NEW DATA SOURCE
-// dispatchWillPerformClientRedirect() -> saves expected redirect
-// dispatchDidStartProvisionalLoad() -> appends URL 2 and URL 3
-// dispatchDidReceiveServerRedirectForProvisionalLoad() -> appends destination URL 4
-// dispatchDidCancelClientRedirect() -> clears expected redirect
-// dispatchDidCommitLoad() -> DISPATCHES
-//
-// Interesting case with multiple location changes involving anchors.
-// Load page 1 containing future client-redirect (back to 1, e.g meta refresh) > Click
-// on a link back to the same page (i.e an anchor href) >
-// client-redirect finally fires (with new source, set to 1#anchor)
-// -----------------------------------------------------------------------------
-// dispatchWillPerformClientRedirect(non-zero 'interval' param) -> saves expected redirect
-// -- click on anchor href
-// dispatchDidCancelClientRedirect() -> clears expected redirect
-// dispatchDidStartProvisionalLoad() -> adds 1#anchor source
-// dispatchDidCommitLoad() -> DISPATCHES 1#anchor
-// dispatchWillPerformClientRedirect() -> saves exp. source (1#anchor)
-// -- redirect timer fires
-// dispatchDidStartProvisionalLoad() -> appends 1#anchor (src) and 1 (dest)
-// dispatchDidCancelClientRedirect() -> clears expected redirect
-// dispatchDidCommitLoad() -> DISPATCHES 1#anchor + 1
-//
-void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad() {
- WebDataSourceImpl* ds = webframe_->GetProvisionalDataSourceImpl();
- if (!ds) {
- // Got a server redirect when there is no provisional DS!
- ASSERT_NOT_REACHED();
- return;
- }
-
- // The server redirect may have been blocked.
- if (ds->request().isNull())
- return;
-
- // A provisional load should have started already, which should have put an
- // entry in our redirect chain.
- ASSERT(ds->hasRedirectChain());
-
- // The URL of the destination is on the provisional data source. We also need
- // to update the redirect chain to account for this addition (we do this
- // before the callback so the callback can look at the redirect chain to see
- // what happened).
- ds->appendRedirect(webkit_glue::WebURLToKURL(ds->request().url()));
-
- if (webframe_->client())
- webframe_->client()->didReceiveServerRedirectForProvisionalLoad(webframe_);
-}
-
-// Called on both success and failure of a client redirect.
-void WebFrameLoaderClient::dispatchDidCancelClientRedirect() {
- // No longer expecting a client redirect.
- if (webframe_->client()) {
- expected_client_redirect_src_ = KURL();
- expected_client_redirect_dest_ = KURL();
- webframe_->client()->didCancelClientRedirect(webframe_);
- }
-
- // No need to clear the redirect chain, since that data source has already
- // been deleted by the time this function is called.
-}
-
-void WebFrameLoaderClient::dispatchWillPerformClientRedirect(
- const KURL& url,
- double interval,
- double fire_date) {
- // Tells dispatchDidStartProvisionalLoad that if it sees this item it is a
- // redirect and the source item should be added as the start of the chain.
- expected_client_redirect_src_ = webkit_glue::WebURLToKURL(webframe_->url());
- expected_client_redirect_dest_ = url;
-
- // TODO(timsteele): bug 1135512. Webkit does not properly notify us of
- // cancelling http > file client redirects. Since the FrameLoader's policy
- // is to never carry out such a navigation anyway, the best thing we can do
- // for now to not get confused is ignore this notification.
- if (expected_client_redirect_dest_.isLocalFile() &&
- expected_client_redirect_src_.protocolInHTTPFamily()) {
- expected_client_redirect_src_ = KURL();
- expected_client_redirect_dest_ = KURL();
- return;
- }
-
- if (webframe_->client()) {
- webframe_->client()->willPerformClientRedirect(
- webframe_,
- webkit_glue::KURLToWebURL(expected_client_redirect_src_),
- webkit_glue::KURLToWebURL(expected_client_redirect_dest_),
- static_cast<unsigned int>(interval),
- static_cast<unsigned int>(fire_date));
- }
-}
-
-void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage() {
- // Anchor fragment navigations are not normal loads, so we need to synthesize
- // some events for our delegate.
- WebViewImpl* webview = webframe_->GetWebViewImpl();
- if (webview->client())
- webview->client()->didStartLoading();
-
- WebDataSourceImpl* ds = webframe_->GetDataSourceImpl();
- ASSERT(ds); // Should not be null when navigating to a reference fragment!
- if (ds) {
- KURL url = webkit_glue::WebURLToKURL(ds->request().url());
- KURL chain_end;
- if (ds->hasRedirectChain()) {
- chain_end = ds->endOfRedirectChain();
- ds->clearRedirectChain();
- }
-
- // Figure out if this location change is because of a JS-initiated client
- // redirect (e.g onload/setTimeout document.location.href=).
- // TODO(timsteele): (bugs 1085325, 1046841) We don't get proper redirect
- // performed/cancelled notifications across anchor navigations, so the
- // other redirect-tracking code in this class (see dispatch*ClientRedirect()
- // and dispatchDidStartProvisionalLoad) is insufficient to catch and
- // properly flag these transitions. Once a proper fix for this bug is
- // identified and applied the following block may no longer be required.
- bool was_client_redirect =
- (url == expected_client_redirect_dest_ &&
- chain_end == expected_client_redirect_src_) ||
- !webframe_->isProcessingUserGesture();
-
- if (was_client_redirect) {
- if (webframe_->client()) {
- webframe_->client()->didCompleteClientRedirect(
- webframe_, webkit_glue::KURLToWebURL(chain_end));
- }
- ds->appendRedirect(chain_end);
- // Make sure we clear the expected redirect since we just effectively
- // completed it.
- expected_client_redirect_src_ = KURL();
- expected_client_redirect_dest_ = KURL();
- }
-
- // Regardless of how we got here, we are navigating to a URL so we need to
- // add it to the redirect chain.
- ds->appendRedirect(url);
- }
-
- bool is_new_navigation;
- webview->DidCommitLoad(&is_new_navigation);
- if (webframe_->client()) {
- webframe_->client()->didChangeLocationWithinPage(
- webframe_, is_new_navigation);
- }
-
- if (webview->client())
- webview->client()->didStopLoading();
-}
-
-void WebFrameLoaderClient::dispatchWillClose() {
- if (webframe_->client())
- webframe_->client()->willClose(webframe_);
-}
-
-void WebFrameLoaderClient::dispatchDidReceiveIcon() {
- // The icon database is disabled, so this should never be called.
- ASSERT_NOT_REACHED();
-}
-
-void WebFrameLoaderClient::dispatchDidStartProvisionalLoad() {
- // In case a redirect occurs, we need this to be set so that the redirect
- // handling code can tell where the redirect came from. Server redirects
- // will occur on the provisional load, so we need to keep track of the most
- // recent provisional load URL.
- // See dispatchDidReceiveServerRedirectForProvisionalLoad.
- WebDataSourceImpl* ds = webframe_->GetProvisionalDataSourceImpl();
- if (!ds) {
- ASSERT_NOT_REACHED();
- return;
- }
- KURL url = webkit_glue::WebURLToKURL(ds->request().url());
-
- // Since the provisional load just started, we should have not gotten
- // any redirects yet.
- ASSERT(!ds->hasRedirectChain());
-
- // If this load is what we expected from a client redirect, treat it as a
- // redirect from that original page. The expected redirect urls will be
- // cleared by DidCancelClientRedirect.
- bool completing_client_redirect = false;
- if (expected_client_redirect_src_.isValid()) {
- // expected_client_redirect_dest_ could be something like
- // "javascript:history.go(-1)" thus we need to exclude url starts with
- // "javascript:". See bug: 1080873
- ASSERT(expected_client_redirect_dest_.protocolIs("javascript") ||
- expected_client_redirect_dest_ == url);
- ds->appendRedirect(expected_client_redirect_src_);
- completing_client_redirect = true;
- }
- ds->appendRedirect(url);
-
- if (webframe_->client()) {
- // As the comment for DidCompleteClientRedirect in webview_delegate.h
- // points out, whatever information its invocation contains should only
- // be considered relevant until the next provisional load has started.
- // So we first tell the delegate that the load started, and then tell it
- // about the client redirect the load is responsible for completing.
- webframe_->client()->didStartProvisionalLoad(webframe_);
- if (completing_client_redirect)
- webframe_->client()->didCompleteClientRedirect(
- webframe_, webkit_glue::KURLToWebURL(expected_client_redirect_src_));
- }
-}
-
-void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title) {
- if (webframe_->client()) {
- webframe_->client()->didReceiveTitle(
- webframe_, webkit_glue::StringToWebString(title));
- }
-}
-
-void WebFrameLoaderClient::dispatchDidCommitLoad() {
- WebViewImpl* webview = webframe_->GetWebViewImpl();
- bool is_new_navigation;
- webview->DidCommitLoad(&is_new_navigation);
-
- if (webframe_->client()) {
- webframe_->client()->didCommitProvisionalLoad(
- webframe_, is_new_navigation);
- }
-
- WebDevToolsAgentImpl* tools_agent = webview->GetWebDevToolsAgentImpl();
- if (tools_agent) {
- tools_agent->DidCommitLoadForFrame(webview, webframe_, is_new_navigation);
- }
-}
-
-void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(
- const ResourceError& error) {
- // If a policy change occured, then we do not want to inform the plugin
- // delegate. See bug 907789 for details.
- // TODO(darin): This means the plugin won't receive NPP_URLNotify, which
- // seems like it could result in a memory leak in the plugin!!
- if (error.domain() == kInternalErrorDomain &&
- error.errorCode() == ERR_POLICY_CHANGE) {
- webframe_->DidFail(cancelledError(error.failingURL()), true);
- return;
- }
-
- OwnPtr<WebPluginLoadObserver> plugin_load_observer = GetPluginLoadObserver();
- webframe_->DidFail(error, true);
- if (plugin_load_observer)
- plugin_load_observer->didFailLoading(error);
-}
-
-void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error) {
- OwnPtr<WebPluginLoadObserver> plugin_load_observer = GetPluginLoadObserver();
- webframe_->DidFail(error, false);
- if (plugin_load_observer)
- plugin_load_observer->didFailLoading(error);
-
- // Don't clear the redirect chain, this will happen in the middle of client
- // redirects, and we need the context. The chain will be cleared when the
- // provisional load succeeds or fails, not the "real" one.
-}
-
-void WebFrameLoaderClient::dispatchDidFinishLoad() {
- OwnPtr<WebPluginLoadObserver> plugin_load_observer = GetPluginLoadObserver();
-
- if (webframe_->client())
- webframe_->client()->didFinishLoad(webframe_);
-
- if (plugin_load_observer)
- plugin_load_observer->didFinishLoading();
-
- // Don't clear the redirect chain, this will happen in the middle of client
- // redirects, and we need the context. The chain will be cleared when the
- // provisional load succeeds or fails, not the "real" one.
-}
-
-void WebFrameLoaderClient::dispatchDidFirstLayout() {
-}
-
-void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout() {
- // FIXME: called when webkit finished layout of a page that was visually
- // non-empty.
- // All resources have not necessarily finished loading.
-}
-
-Frame* WebFrameLoaderClient::dispatchCreatePage() {
- struct WebCore::WindowFeatures features;
- Page* new_page = webframe_->frame()->page()->chrome()->createWindow(
- webframe_->frame(), FrameLoadRequest(), features);
-
- // Make sure that we have a valid disposition. This should have been set in
- // the preceeding call to dispatchDecidePolicyForNewWindowAction.
- ASSERT(next_navigation_policy_ != WebKit::WebNavigationPolicyIgnore);
- WebNavigationPolicy policy = next_navigation_policy_;
- next_navigation_policy_ = WebKit::WebNavigationPolicyIgnore;
-
- // createWindow can return NULL (e.g., popup blocker denies the window).
- if (!new_page)
- return NULL;
-
- WebViewImpl::FromPage(new_page)->set_initial_navigation_policy(policy);
- return new_page->mainFrame();
-}
-
-void WebFrameLoaderClient::dispatchShow() {
- WebViewImpl* webview = webframe_->GetWebViewImpl();
- if (webview && webview->client())
- webview->client()->show(webview->initial_navigation_policy());
-}
-
-static bool TreatAsAttachment(const ResourceResponse& response) {
- const String& content_disposition =
- response.httpHeaderField("Content-Disposition");
- if (content_disposition.isEmpty())
- return false;
-
- // Some broken sites just send
- // Content-Disposition: ; filename="file"
- // screen those out here.
- if (content_disposition.startsWith(";"))
- return false;
-
- if (content_disposition.startsWith("inline", false))
- return false;
-
- // Some broken sites just send
- // Content-Disposition: filename="file"
- // without a disposition token... screen those out.
- if (content_disposition.startsWith("filename", false))
- return false;
-
- // Also in use is Content-Disposition: name="file"
- if (content_disposition.startsWith("name", false))
- return false;
-
- // We have a content-disposition of "attachment" or unknown.
- // RFC 2183, section 2.8 says that an unknown disposition
- // value should be treated as "attachment"
- return true;
-}
-
-void WebFrameLoaderClient::dispatchDecidePolicyForMIMEType(
- FramePolicyFunction function,
- const String& mime_type,
- const ResourceRequest&) {
- const ResourceResponse& response =
- webframe_->frame()->loader()->activeDocumentLoader()->response();
-
- PolicyAction action;
-
- int status_code = response.httpStatusCode();
- if (status_code == 204 || status_code == 205) {
- // The server does not want us to replace the page contents.
- action = PolicyIgnore;
- } else if (TreatAsAttachment(response)) {
- // The server wants us to download instead of replacing the page contents.
- // Downloading is handled by the embedder, but we still get the initial
- // response so that we can ignore it and clean up properly.
- action = PolicyIgnore;
- } else if (!canShowMIMEType(mime_type)) {
- // Make sure that we can actually handle this type internally.
- action = PolicyIgnore;
- } else {
- // OK, we will render this page.
- action = PolicyUse;
- }
-
- // NOTE: ERR_POLICY_CHANGE will be generated when action is not PolicyUse.
- (webframe_->frame()->loader()->policyChecker()->*function)(action);
-}
-
-void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(
- WebCore::FramePolicyFunction function,
- const WebCore::NavigationAction& action,
- const WebCore::ResourceRequest& request,
- PassRefPtr<WebCore::FormState> form_state,
- const WebCore::String& frame_name) {
- WebNavigationPolicy navigation_policy;
- if (!ActionSpecifiesNavigationPolicy(action, &navigation_policy))
- navigation_policy = WebKit::WebNavigationPolicyNewForegroundTab;
-
- PolicyAction policy_action;
- if (navigation_policy == WebKit::WebNavigationPolicyDownload) {
- policy_action = PolicyDownload;
- } else {
- policy_action = PolicyUse;
-
- // Remember the disposition for when dispatchCreatePage is called. It is
- // unfortunate that WebCore does not provide us with any context when
- // creating or showing the new window that would allow us to avoid having
- // to keep this state.
- next_navigation_policy_ = navigation_policy;
- }
- (webframe_->frame()->loader()->policyChecker()->*function)(policy_action);
-}
-
-void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(
- WebCore::FramePolicyFunction function,
- const WebCore::NavigationAction& action,
- const WebCore::ResourceRequest& request,
- PassRefPtr<WebCore::FormState> form_state) {
- PolicyAction policy_action = PolicyIgnore;
-
- // It is valid for this function to be invoked in code paths where the
- // the webview is closed.
- // The NULL check here is to fix a crash that seems strange
- // (see - https://bugs.webkit.org/show_bug.cgi?id=23554).
- if (webframe_->client() && !request.url().isNull()) {
- WebNavigationPolicy navigation_policy =
- WebKit::WebNavigationPolicyCurrentTab;
- ActionSpecifiesNavigationPolicy(action, &navigation_policy);
-
- // Give the delegate a chance to change the navigation policy.
- const WebDataSourceImpl* ds = webframe_->GetProvisionalDataSourceImpl();
- if (ds) {
- KURL url = webkit_glue::WebURLToKURL(ds->request().url());
- if (url.protocolIs(WebKit::backForwardNavigationScheme)) {
- HandleBackForwardNavigation(url);
- navigation_policy = WebKit::WebNavigationPolicyIgnore;
- } else {
- bool is_redirect = ds->hasRedirectChain();
-
- WebNavigationType webnav_type =
- WebDataSourceImpl::toWebNavigationType(action.type());
-
- RefPtr<WebCore::Node> node;
- for (const Event* event = action.event(); event;
- event = event->underlyingEvent()) {
- if (event->isMouseEvent()) {
- const MouseEvent* mouse_event =
- static_cast<const MouseEvent*>(event);
- node = webframe_->frame()->eventHandler()->hitTestResultAtPoint(
- mouse_event->absoluteLocation(), false).innerNonSharedNode();
- break;
- }
- }
- WebNode originating_node = webkit_glue::NodeToWebNode(node);
-
- navigation_policy = webframe_->client()->decidePolicyForNavigation(
- webframe_, ds->request(), webnav_type, originating_node,
- navigation_policy, is_redirect);
- }
- }
-
- if (navigation_policy == WebKit::WebNavigationPolicyCurrentTab) {
- policy_action = PolicyUse;
- } else if (navigation_policy == WebKit::WebNavigationPolicyDownload) {
- policy_action = PolicyDownload;
- } else {
- if (navigation_policy != WebKit::WebNavigationPolicyIgnore) {
- WrappedResourceRequest webreq(request);
- webframe_->client()->loadURLExternally(
- webframe_, webreq, navigation_policy);
- }
- policy_action = PolicyIgnore;
- }
- }
-
- (webframe_->frame()->loader()->policyChecker()->*function)(policy_action);
-}
-
-void WebFrameLoaderClient::cancelPolicyCheck() {
- // FIXME
-}
-
-void WebFrameLoaderClient::dispatchUnableToImplementPolicy(
- const ResourceError& error) {
- WebKit::WebURLError url_error =
- webkit_glue::ResourceErrorToWebURLError(error);
- webframe_->client()->unableToImplementPolicyWithError(webframe_, url_error);
-}
-
-void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function,
- PassRefPtr<FormState> form_ref) {
- if (webframe_->client()) {
- webframe_->client()->willSubmitForm(
- webframe_, webkit_glue::HTMLFormElementToWebForm(form_ref->form()));
- }
- (webframe_->frame()->loader()->policyChecker()->*function)(PolicyUse);
-}
-
-void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*) {
- // FIXME
-}
-
-void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*) {
- has_representation_ = true;
-}
-
-void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*,
- const ResourceError& error) {
- if (plugin_widget_.get()) {
- if (sent_initial_response_to_plugin_) {
- plugin_widget_->didFailLoading(error);
- sent_initial_response_to_plugin_ = false;
- }
- plugin_widget_ = NULL;
- }
-}
-
-void WebFrameLoaderClient::postProgressStartedNotification() {
- WebViewImpl* webview = webframe_->GetWebViewImpl();
- if (webview && webview->client())
- webview->client()->didStartLoading();
-}
-
-void WebFrameLoaderClient::postProgressEstimateChangedNotification() {
- // FIXME
-}
-
-void WebFrameLoaderClient::postProgressFinishedNotification() {
- // TODO(ericroman): why might the webview be null?
- // http://b/1234461
- WebViewImpl* webview = webframe_->GetWebViewImpl();
- if (webview && webview->client())
- webview->client()->didStopLoading();
-}
-
-void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready) {
- // FIXME
-}
-
-// Creates a new connection and begins downloading from that (contrast this
-// with |download|).
-void WebFrameLoaderClient::startDownload(const ResourceRequest& request) {
- if (webframe_->client()) {
- WrappedResourceRequest webreq(request);
- webframe_->client()->loadURLExternally(
- webframe_, webreq, WebKit::WebNavigationPolicyDownload);
- }
-}
-
-void WebFrameLoaderClient::willChangeTitle(DocumentLoader*) {
- // FIXME
-}
-
-void WebFrameLoaderClient::didChangeTitle(DocumentLoader*) {
- // FIXME
-}
-
-// Called whenever data is received.
-void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length) {
- if (!plugin_widget_.get()) {
- if (webframe_->client()) {
- bool preventDefault = false;
- webframe_->client()->didReceiveDocumentData(webframe_, data, length, preventDefault);
- if (!preventDefault)
- webframe_->commitDocumentData(data, length);
- }
- }
-
- // If we are sending data to WebCore::MediaDocument, we should stop here
- // and cancel the request.
- if (webframe_->frame()->document() &&
- webframe_->frame()->document()->isMediaDocument()) {
- loader->cancelMainResourceLoad(
- pluginWillHandleLoadError(loader->response()));
- }
-
- // The plugin widget could have been created in the webframe_->DidReceiveData
- // function.
- if (plugin_widget_.get()) {
- if (!sent_initial_response_to_plugin_) {
- sent_initial_response_to_plugin_ = true;
- plugin_widget_->didReceiveResponse(
- webframe_->frame()->loader()->activeDocumentLoader()->response());
- }
- plugin_widget_->didReceiveData(data, length);
- }
-}
-
-void WebFrameLoaderClient::finishedLoading(DocumentLoader* dl) {
- if (plugin_widget_.get()) {
- plugin_widget_->didFinishLoading();
- plugin_widget_ = NULL;
- sent_initial_response_to_plugin_ = false;
- } else {
- // This is necessary to create an empty document. See bug 634004.
- // However, we only want to do this if makeRepresentation has been called, to
- // match the behavior on the Mac.
- if (has_representation_)
- dl->frameLoader()->setEncoding("", false);
- }
-}
-
-void WebFrameLoaderClient::updateGlobalHistory() {
-}
-
-void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() {
-}
-
-bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const {
- // FIXME
- return true;
-}
-
-void WebFrameLoaderClient::didDisplayInsecureContent() {
- if (webframe_->client())
- webframe_->client()->didDisplayInsecureContent(webframe_);
-}
-
-void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin) {
- if (webframe_->client()) {
- webframe_->client()->didRunInsecureContent(webframe_,
- webkit_glue::SecurityOriginToWebSecurityOrigin(origin));
- }
-}
-
-ResourceError WebFrameLoaderClient::blockedError(const WebCore::ResourceRequest&) {
- // FIXME
- return ResourceError();
-}
-
-ResourceError WebFrameLoaderClient::cancelledError(
- const ResourceRequest& request) {
- if (!webframe_->client())
- return ResourceError();
-
- return webkit_glue::WebURLErrorToResourceError(
- webframe_->client()->cancelledError(
- webframe_, WrappedResourceRequest(request)));
-}
-
-ResourceError WebFrameLoaderClient::cannotShowURLError(
- const ResourceRequest& request) {
- if (!webframe_->client())
- return ResourceError();
-
- return webkit_glue::WebURLErrorToResourceError(
- webframe_->client()->cannotHandleRequestError(
- webframe_, WrappedResourceRequest(request)));
-}
-
-ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(
- const ResourceRequest& request) {
- return ResourceError(kInternalErrorDomain, ERR_POLICY_CHANGE,
- request.url().string(), String());
-}
-
-ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse&) {
- // FIXME
- return ResourceError();
-}
-
-ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse&) {
- // FIXME
- return ResourceError();
-}
-
-ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const WebCore::ResourceResponse&) {
- // FIXME
- return ResourceError();
-}
-
-bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error) {
- // This method is called when we fail to load the URL for an <object> tag
- // that has fallback content (child elements) and is being loaded as a frame.
- // The error parameter indicates the reason for the load failure.
- // We should let the fallback content load only if this wasn't a cancelled
- // request.
- // Note: The mac version also has a case for "WebKitErrorPluginWillHandleLoad"
- ResourceError cancelled_error = cancelledError(ResourceRequest());
- return error.errorCode() != cancelled_error.errorCode() ||
- error.domain() != cancelled_error.domain();
-}
-
-bool WebFrameLoaderClient::canHandleRequest(
- const ResourceRequest& request) const {
- return webframe_->client()->canHandleRequest(
- webframe_, WrappedResourceRequest(request));
-}
-
-bool WebFrameLoaderClient::canShowMIMEType(const String& mime_type) const {
- // This method is called to determine if the media type can be shown
- // "internally" (i.e. inside the browser) regardless of whether or not the
- // browser or a plugin is doing the rendering.
-
- // mime_type strings are supposed to be ASCII, but if they are not for some
- // reason, then it just means that the mime type will fail all of these "is
- // supported" checks and go down the path of an unhandled mime type.
- if (net::IsSupportedMimeType(
- webkit_glue::CStringToStdString(mime_type.latin1())))
- return true;
-
- // If Chrome is started with the --disable-plugins switch, pluginData is null.
- WebCore::PluginData* plugin_data = webframe_->frame()->page()->pluginData();
-
- // See if the type is handled by an installed plugin, if so, we can show it.
- // TODO(beng): (http://b/1085524) This is the place to stick a preference to
- // disable full page plugins (optionally for certain types!)
- return !mime_type.isEmpty() && plugin_data && plugin_data->supportsMimeType(mime_type);
-}
-
-bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const {
- // FIXME
- return false;
-}
-
-String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const {
- // This appears to generate MIME types for protocol handlers that are handled
- // internally. The only place I can find in the WebKit code that uses this
- // function is WebView::registerViewClass, where it is used as part of the
- // process by which custom view classes for certain document representations
- // are registered.
- String mimetype("x-apple-web-kit/");
- mimetype.append(URLScheme.lower());
- return mimetype;
-}
-
-void WebFrameLoaderClient::frameLoadCompleted() {
- // FIXME: the mac port also conditionally calls setDrawsBackground:YES on
- // it's ScrollView here.
-
- // This comment from the Mac port:
- // Note: Can be called multiple times.
- // Even if already complete, we might have set a previous item on a frame that
- // didn't do any data loading on the past transaction. Make sure to clear these out.
-
- // FIXME: setPreviousHistoryItem() no longer exists. http://crbug.com/8566
- // webframe_->frame()->loader()->setPreviousHistoryItem(0);
-}
-
-void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*) {
- // FIXME
-}
-
-
-void WebFrameLoaderClient::restoreViewState() {
- // FIXME: probably scrolls to last position when you go back or forward
-}
-
-void WebFrameLoaderClient::provisionalLoadStarted() {
- // FIXME: On mac, this does various caching stuff
-}
-
-void WebFrameLoaderClient::didFinishLoad() {
- OwnPtr<WebPluginLoadObserver> plugin_load_observer = GetPluginLoadObserver();
- if (plugin_load_observer)
- plugin_load_observer->didFinishLoading();
-}
-
-void WebFrameLoaderClient::prepareForDataSourceReplacement() {
- // FIXME
-}
-
-PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(
- const ResourceRequest& request,
- const SubstituteData& data) {
- RefPtr<WebDataSourceImpl> ds = WebDataSourceImpl::create(request, data);
- if (webframe_->client())
- webframe_->client()->didCreateDataSource(webframe_, ds.get());
- return ds.release();
-}
-
-void WebFrameLoaderClient::setTitle(const String& title, const KURL& url) {
- // FIXME: monitor for changes in WebFrameLoaderClient.mm
- // FIXME: Set the title of the current history item. HistoryItemImpl's setter
- // will notify its clients (e.g. the history database) that the title
- // has changed.
- //
- // e.g.:
- // WebHistoryItem* item =
- // webframe_->GetWebViewImpl()->GetBackForwardList()->GetCurrentItem();
- // WebHistoryItemImpl* item_impl = static_cast<WebHistoryItemImpl*>(item);
- //
- // item_impl->SetTitle(webkit_glue::StringToStdWString(title));
-}
-
-String WebFrameLoaderClient::userAgent(const KURL& url) {
- return webkit_glue::StdStringToString(
- webkit_glue::GetUserAgent(webkit_glue::KURLToGURL(url)));
-}
-
-void WebFrameLoaderClient::savePlatformDataToCachedFrame(WebCore::CachedFrame*) {
- // The page cache should be disabled.
- ASSERT_NOT_REACHED();
-}
-
-void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(WebCore::CachedFrame*) {
- ASSERT_NOT_REACHED();
-}
-
-// Called when the FrameLoader goes into a state in which a new page load
-// will occur.
-void WebFrameLoaderClient::transitionToCommittedForNewPage() {
- makeDocumentView();
-}
-
-bool WebFrameLoaderClient::canCachePage() const {
- // Since we manage the cache, always report this page as non-cacheable to
- // FrameLoader.
- return false;
-}
-
-// Downloading is handled in the browser process, not WebKit. If we get to this
-// point, our download detection code in the ResourceDispatcherHost is broken!
-void WebFrameLoaderClient::download(ResourceHandle* handle,
- const ResourceRequest& request,
- const ResourceRequest& initialRequest,
- const ResourceResponse& response) {
- ASSERT_NOT_REACHED();
-}
-
-PassRefPtr<Frame> WebFrameLoaderClient::createFrame(
- const KURL& url,
- const String& name,
- HTMLFrameOwnerElement* owner_element,
- const String& referrer,
- bool allows_scrolling,
- int margin_width,
- int margin_height) {
- FrameLoadRequest frame_request(ResourceRequest(url, referrer), name);
- return webframe_->CreateChildFrame(frame_request, owner_element);
-}
-
-PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(
- const IntSize& size, // TODO(erikkay): how do we use this?
- HTMLPlugInElement* element,
- const KURL& url,
- const Vector<String>& param_names,
- const Vector<String>& param_values,
- const String& mime_type,
- bool load_manually) {
-#if !PLATFORM(WIN_OS)
- // WebCore asks us to make a plugin even if we don't have a
- // registered handler, with a comment saying it's so we can display
- // the broken plugin icon. In Chromium, we normally register a
- // fallback plugin handler that allows you to install a missing
- // plugin. Since we don't yet have a default plugin handler, we
- // need to return NULL here rather than going through all the
- // plugin-creation IPCs only to discover we don't have a plugin
- // registered, which causes a crash.
- // TODO(evanm): remove me once we have a default plugin.
- if (objectContentType(url, mime_type) != ObjectContentNetscapePlugin)
- return NULL;
-#endif
-
- if (!webframe_->client())
- return NULL;
-
- WebPluginParams params;
- params.url = webkit_glue::KURLToWebURL(url);
- params.mimeType = webkit_glue::StringToWebString(mime_type);
- CopyStringVector(param_names, &params.attributeNames);
- CopyStringVector(param_values, &params.attributeValues);
- params.loadManually = load_manually;
-
- WebPlugin* webplugin = webframe_->client()->createPlugin(webframe_, params);
- if (!webplugin)
- return NULL;
-
- // The container takes ownership of the WebPlugin.
- RefPtr<WebPluginContainerImpl> container =
- WebPluginContainerImpl::create(element, webplugin);
-
- if (!webplugin->initialize(container.get()))
- return NULL;
-
- // The element might have been removed during plugin initialization!
- if (!element->renderer())
- return NULL;
-
- return container;
-}
-
-// This method gets called when a plugin is put in place of html content
-// (e.g., acrobat reader).
-void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget) {
- plugin_widget_ = static_cast<WebPluginContainerImpl*>(pluginWidget);
- ASSERT(plugin_widget_.get());
-}
-
-PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(
- const IntSize& size,
- HTMLAppletElement* element,
- const KURL& /* base_url */,
- const Vector<String>& param_names,
- const Vector<String>& param_values) {
- return createPlugin(size, element, KURL(), param_names, param_values,
- "application/x-java-applet", false);
-}
-
-ObjectContentType WebFrameLoaderClient::objectContentType(
- const KURL& url,
- const String& explicit_mime_type) {
- // This code is based on Apple's implementation from
- // WebCoreSupport/WebFrameBridge.mm.
-
- String mime_type = explicit_mime_type;
- if (mime_type.isEmpty()) {
- // Try to guess the MIME type based off the extension.
- String filename = url.lastPathComponent();
- int extension_pos = filename.reverseFind('.');
- if (extension_pos >= 0)
- mime_type = MIMETypeRegistry::getMIMETypeForPath(url.path());
-
- if (mime_type.isEmpty())
- return ObjectContentFrame;
- }
-
- if (MIMETypeRegistry::isSupportedImageMIMEType(mime_type))
- return ObjectContentImage;
-
- // If Chrome is started with the --disable-plugins switch, pluginData is null.
- PluginData* plugin_data = webframe_->frame()->page()->pluginData();
- if (plugin_data && plugin_data->supportsMimeType(mime_type))
- return ObjectContentNetscapePlugin;
-
- if (MIMETypeRegistry::isSupportedNonImageMIMEType(mime_type))
- return ObjectContentFrame;
-
- return ObjectContentNone;
-}
-
-String WebFrameLoaderClient::overrideMediaType() const {
- // FIXME
- return String();
-}
-
-bool WebFrameLoaderClient::ActionSpecifiesNavigationPolicy(
- const WebCore::NavigationAction& action,
- WebNavigationPolicy* policy) {
- if ((action.type() != NavigationTypeLinkClicked) ||
- !action.event()->isMouseEvent())
- return false;
-
- const MouseEvent* event = static_cast<const MouseEvent*>(action.event());
- return WebViewImpl::NavigationPolicyFromMouseEvent(event->button(),
- event->ctrlKey(), event->shiftKey(), event->altKey(), event->metaKey(),
- policy);
-}
-
-void WebFrameLoaderClient::HandleBackForwardNavigation(const KURL& url) {
- ASSERT(url.protocolIs(WebKit::backForwardNavigationScheme));
-
- bool ok;
- int offset = url.lastPathComponent().toIntStrict(&ok);
- if (!ok)
- return;
-
- WebViewImpl* webview = webframe_->GetWebViewImpl();
- if (webview->client())
- webview->client()->navigateBackForwardSoon(offset);
-}
-
-PassOwnPtr<WebPluginLoadObserver> WebFrameLoaderClient::GetPluginLoadObserver() {
- WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader(
- webframe_->frame()->loader()->activeDocumentLoader());
- return ds->releasePluginLoadObserver();
-}
diff --git a/webkit/glue/webframeloaderclient_impl.h b/webkit/glue/webframeloaderclient_impl.h
deleted file mode 100644
index fdf5de7..0000000
--- a/webkit/glue/webframeloaderclient_impl.h
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef WEBKIT_GLUE_WEBFRAMELOADERCLIENT_IMPL_H_
-#define WEBKIT_GLUE_WEBFRAMELOADERCLIENT_IMPL_H_
-
-#include "FrameLoaderClient.h"
-#include "KURL.h"
-#include <wtf/PassOwnPtr.h>
-#include <wtf/RefPtr.h>
-
-#include "webkit/api/public/WebNavigationPolicy.h"
-
-class WebFrameImpl;
-
-namespace WebKit {
-class WebPluginContainerImpl;
-class WebPluginLoadObserver;
-}
-
-class WebFrameLoaderClient : public WebCore::FrameLoaderClient {
- public:
- WebFrameLoaderClient(WebFrameImpl* webframe);
- virtual ~WebFrameLoaderClient();
-
- WebFrameImpl* webframe() const { return webframe_; }
-
- // WebCore::FrameLoaderClient ----------------------------------------------
-
- virtual void frameLoaderDestroyed();
-
- // Notifies the WebView delegate that the JS window object has been cleared,
- // giving it a chance to bind native objects to the window before script
- // parsing begins.
- virtual void windowObjectCleared();
- virtual void documentElementAvailable();
-
- // A frame's V8 context was created or destroyed.
- virtual void didCreateScriptContextForFrame();
- virtual void didDestroyScriptContextForFrame();
-
- // A context untied to a frame was created (through evaluateInNewContext).
- // This context is not tied to the lifetime of its frame, and is destroyed
- // in garbage collection.
- virtual void didCreateIsolatedScriptContext();
-
- virtual bool hasWebView() const; // mainly for assertions
- virtual bool hasFrameView() const; // ditto
-
- virtual void makeRepresentation(WebCore::DocumentLoader*);
- virtual void forceLayout();
- virtual void forceLayoutForNonHTML();
-
- virtual void setCopiesOnScroll();
-
- virtual void detachedFromParent2();
- virtual void detachedFromParent3();
-
- virtual void assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest&);
-
- virtual void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse);
- virtual bool shouldUseCredentialStorage(WebCore::DocumentLoader*, unsigned long identifier);
- virtual void dispatchDidReceiveAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&);
- virtual void dispatchDidCancelAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&);
- virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&);
- virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int lengthReceived);
- virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier);
- virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&);
- virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int length);
- virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const WebCore::ScriptString&);
-
- virtual void dispatchDidHandleOnloadEvents();
- virtual void dispatchDidReceiveServerRedirectForProvisionalLoad();
- virtual void dispatchDidCancelClientRedirect();
- virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate);
- virtual void dispatchDidChangeLocationWithinPage();
- virtual void dispatchWillClose();
- virtual void dispatchDidReceiveIcon();
- virtual void dispatchDidStartProvisionalLoad();
- virtual void dispatchDidReceiveTitle(const WebCore::String& title);
- virtual void dispatchDidCommitLoad();
- virtual void dispatchDidFailProvisionalLoad(const WebCore::ResourceError&);
- virtual void dispatchDidFailLoad(const WebCore::ResourceError&);
- virtual void dispatchDidFinishDocumentLoad();
- virtual void dispatchDidFinishLoad();
- virtual void dispatchDidFirstLayout();
- virtual void dispatchDidFirstVisuallyNonEmptyLayout();
-
- virtual WebCore::Frame* dispatchCreatePage();
- virtual void dispatchShow();
-
- virtual void dispatchDecidePolicyForMIMEType(WebCore::FramePolicyFunction function, const WebCore::String& mime_type, const WebCore::ResourceRequest&);
- virtual void dispatchDecidePolicyForNewWindowAction(WebCore::FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState> form_state, const WebCore::String& frame_name);
- virtual void dispatchDecidePolicyForNavigationAction(WebCore::FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState> form_state);
- virtual void cancelPolicyCheck();
-
- virtual void dispatchUnableToImplementPolicy(const WebCore::ResourceError&);
-
- virtual void dispatchWillSubmitForm(WebCore::FramePolicyFunction, PassRefPtr<WebCore::FormState>);
-
- virtual void dispatchDidLoadMainResource(WebCore::DocumentLoader*);
- virtual void revertToProvisionalState(WebCore::DocumentLoader*);
- virtual void setMainDocumentError(WebCore::DocumentLoader*, const WebCore::ResourceError&);
-
- // Maybe these should go into a ProgressTrackerClient some day
- virtual void willChangeEstimatedProgress() { }
- virtual void didChangeEstimatedProgress() { }
- virtual void postProgressStartedNotification();
- virtual void postProgressEstimateChangedNotification();
- virtual void postProgressFinishedNotification();
-
- virtual void setMainFrameDocumentReady(bool);
-
- virtual void startDownload(const WebCore::ResourceRequest&);
-
- virtual void willChangeTitle(WebCore::DocumentLoader*);
- virtual void didChangeTitle(WebCore::DocumentLoader*);
-
- virtual void committedLoad(WebCore::DocumentLoader*, const char*, int);
- virtual void finishedLoading(WebCore::DocumentLoader*);
-
- virtual void updateGlobalHistory();
- virtual void updateGlobalHistoryRedirectLinks();
-
- virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const;
-
- virtual void didDisplayInsecureContent();
- virtual void didRunInsecureContent(WebCore::SecurityOrigin*);
-
- virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&);
- virtual WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&);
- virtual WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&);
- virtual WebCore::ResourceError interruptForPolicyChangeError(const WebCore::ResourceRequest&);
-
- virtual WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&);
- virtual WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&);
- virtual WebCore::ResourceError pluginWillHandleLoadError(const WebCore::ResourceResponse&);
-
- virtual bool shouldFallBack(const WebCore::ResourceError&);
-
- virtual bool canHandleRequest(const WebCore::ResourceRequest&) const;
- virtual bool canShowMIMEType(const WebCore::String& MIMEType) const;
- virtual bool representationExistsForURLScheme(const WebCore::String& URLScheme) const;
- virtual WebCore::String generatedMIMETypeForURLScheme(const WebCore::String& URLScheme) const;
-
- virtual void frameLoadCompleted();
- virtual void saveViewStateToItem(WebCore::HistoryItem*);
- virtual void restoreViewState();
- virtual void provisionalLoadStarted();
- virtual void didFinishLoad();
- virtual void prepareForDataSourceReplacement();
-
- virtual PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(
- const WebCore::ResourceRequest&,
- const WebCore::SubstituteData&);
- virtual void setTitle(const WebCore::String& title, const WebCore::KURL&);
-
- virtual WebCore::String userAgent(const WebCore::KURL&);
-
- virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*);
- virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*);
- virtual void transitionToCommittedForNewPage();
-
- virtual bool canCachePage() const;
- virtual void download(WebCore::ResourceHandle* handle,
- const WebCore::ResourceRequest& request,
- const WebCore::ResourceRequest& initialRequest,
- const WebCore::ResourceResponse& response);
- virtual PassRefPtr<WebCore::Frame> createFrame(
- const WebCore::KURL& url,
- const WebCore::String& name,
- WebCore::HTMLFrameOwnerElement* ownerElement,
- const WebCore::String& referrer,
- bool allowsScrolling, int marginWidth,
- int marginHeight);
- virtual PassRefPtr<WebCore::Widget> createPlugin(const WebCore::IntSize&,
- WebCore::HTMLPlugInElement*,
- const WebCore::KURL&,
- const WTF::Vector<WebCore::String>&,
- const WTF::Vector<WebCore::String>&,
- const WebCore::String&,
- bool loadManually);
- virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget);
-
- virtual PassRefPtr<WebCore::Widget> createJavaAppletWidget(
- const WebCore::IntSize&,
- WebCore::HTMLAppletElement*,
- const WebCore::KURL& /* base_url */,
- const WTF::Vector<WebCore::String>& paramNames,
- const WTF::Vector<WebCore::String>& paramValues);
-
- virtual WebCore::ObjectContentType objectContentType(
- const WebCore::KURL& url, const WebCore::String& mimeType);
- virtual WebCore::String overrideMediaType() const;
-
- virtual void didPerformFirstNavigation() const;
-
- virtual void registerForIconNotification(bool listen = true);
-
- private:
- void makeDocumentView();
-
- // Given a NavigationAction, determine the associated WebNavigationPolicy.
- // For example, a middle click means "open in background tab".
- static bool ActionSpecifiesNavigationPolicy(
- const WebCore::NavigationAction& action,
- WebKit::WebNavigationPolicy* policy);
-
- // Called when a dummy back-forward navigation is intercepted.
- void HandleBackForwardNavigation(const WebCore::KURL&);
-
- PassOwnPtr<WebKit::WebPluginLoadObserver> GetPluginLoadObserver();
-
- // The WebFrame that owns this object and manages its lifetime. Therefore,
- // the web frame object is guaranteed to exist.
- WebFrameImpl* webframe_;
-
- // True if makeRepresentation was called. We don't actually have a concept
- // of a "representation", but we need to know when we're expected to have one.
- // See finishedLoading().
- bool has_representation_;
-
- // Used to help track client redirects. When a provisional load starts, it
- // has no redirects in its chain. But in the case of client redirects, we want
- // to add that initial load as a redirect. When we get a new provisional load
- // and the dest URL matches that load, we know that it was the result of a
- // previous client redirect and the source should be added as a redirect.
- // Both should be empty if unused.
- WebCore::KURL expected_client_redirect_src_;
- WebCore::KURL expected_client_redirect_dest_;
-
- // Contains a pointer to the plugin widget.
- WTF::RefPtr<WebKit::WebPluginContainerImpl> plugin_widget_;
-
- // Indicates if we need to send over the initial notification to the plugin
- // which specifies that the plugin should be ready to accept data.
- bool sent_initial_response_to_plugin_;
-
- // The navigation policy to use for the next call to dispatchCreatePage.
- WebKit::WebNavigationPolicy next_navigation_policy_;
-};
-
-#endif // #ifndef WEBKIT_GLUE_WEBFRAMELOADERCLIENT_IMPL_H_
diff --git a/webkit/glue/webkit_glue.cc b/webkit/glue/webkit_glue.cc
index 233170c..d3e5b72 100644
--- a/webkit/glue/webkit_glue.cc
+++ b/webkit/glue/webkit_glue.cc
@@ -44,19 +44,21 @@
#if defined(OS_WIN)
#include "webkit/api/public/win/WebInputEventFactory.h"
#endif
+#include "webkit/api/src/WebFrameImpl.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/glue/glue_serialize.h"
#include "webkit/glue/glue_util.h"
-#include "webkit/glue/webframe_impl.h"
-#include "webkit/glue/webview_impl.h"
#include "webkit_version.h" // Generated
using WebKit::WebCanvas;
using WebKit::WebFrame;
+using WebKit::WebFrameImpl;
using WebKit::WebHistoryItem;
using WebKit::WebString;
using WebKit::WebVector;
using WebKit::WebView;
+using WebKit::WebViewImpl;
namespace {
@@ -123,7 +125,7 @@ std::wstring DumpFramesAsText(WebFrame* web_frame, bool recursive) {
WebCore::Frame* child = webFrameImpl->frame()->tree()->firstChild();
for (; child; child = child->tree()->nextSibling()) {
result.append(
- DumpFramesAsText(WebFrameImpl::FromFrame(child), recursive));
+ DumpFramesAsText(WebFrameImpl::fromFrame(child), recursive));
}
}
@@ -155,7 +157,7 @@ bool CounterValueForElementById(WebFrame* web_frame, const std::string& id,
std::wstring DumpFrameScrollPosition(WebFrame* web_frame, bool recursive) {
WebFrameImpl* webFrameImpl = static_cast<WebFrameImpl*>(web_frame);
- WebCore::IntSize offset = webFrameImpl->frameview()->scrollOffset();
+ WebCore::IntSize offset = webFrameImpl->frameView()->scrollOffset();
std::wstring result;
if (offset.width() > 0 || offset.height() > 0) {
@@ -170,7 +172,7 @@ std::wstring DumpFrameScrollPosition(WebFrame* web_frame, bool recursive) {
if (recursive) {
WebCore::Frame* child = webFrameImpl->frame()->tree()->firstChild();
for (; child; child = child->tree()->nextSibling()) {
- result.append(DumpFrameScrollPosition(WebFrameImpl::FromFrame(child),
+ result.append(DumpFrameScrollPosition(WebFrameImpl::fromFrame(child),
recursive));
}
}
@@ -274,7 +276,7 @@ void DumpLeakedObject(const char* file, int line, const char* object, int count)
void CheckForLeaks() {
#ifndef NDEBUG
- int count = WebFrameImpl::live_object_count();
+ int count = WebFrameImpl::liveObjectCount();
if (count)
DumpLeakedObject(__FILE__, __LINE__, "WebFrame", count);
#endif
diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc
index 7560c70..d29f73d 100644
--- a/webkit/glue/webkitclient_impl.cc
+++ b/webkit/glue/webkitclient_impl.cc
@@ -33,6 +33,8 @@
#include "webkit/api/public/WebURL.h"
#include "webkit/api/public/WebViewClient.h"
#include "webkit/api/src/ChromeClientImpl.h"
+#include "webkit/api/src/WebFrameImpl.h"
+#include "webkit/api/src/WebViewImpl.h"
#include "webkit/api/src/WebWorkerClientImpl.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/plugins/plugin_instance.h"
@@ -40,7 +42,6 @@
#include "webkit/glue/webplugininfo.h"
#include "webkit/glue/websocketstreamhandle_impl.h"
#include "webkit/glue/weburlloader_impl.h"
-#include "webkit/glue/webview_impl.h"
using WebKit::ChromeClientImpl;
using WebKit::WebApplicationCacheHost;
@@ -48,6 +49,7 @@ using WebKit::WebApplicationCacheHostClient;
using WebKit::WebCookie;
using WebKit::WebCursorInfo;
using WebKit::WebData;
+using WebKit::WebFrameImpl;
using WebKit::WebLocalizedString;
using WebKit::WebPluginListBuilder;
using WebKit::WebStorageNamespace;
@@ -57,6 +59,7 @@ using WebKit::WebThemeEngine;
using WebKit::WebURL;
using WebKit::WebURLLoader;
using WebKit::WebVector;
+using WebKit::WebViewImpl;
using WebKit::WebWidgetClient;
using WebKit::WebWorkerClientImpl;
@@ -417,7 +420,7 @@ bool WebKitClientImpl::makeAllDirectories(
WebKit::WebMediaPlayer* WebKitClientImpl::createWebMediaPlayer(
WebKit::WebMediaPlayerClient* client, WebCore::Frame* frame) {
- WebFrameImpl* webframe = WebFrameImpl::FromFrame(frame);
+ WebFrameImpl* webframe = WebFrameImpl::fromFrame(frame);
if (!webframe->client())
return NULL;
@@ -443,7 +446,7 @@ void WebKitClientImpl::notifyJSOutOfMemory(WebCore::Frame* frame) {
if (!frame)
return;
- WebFrameImpl* webframe = WebFrameImpl::FromFrame(frame);
+ WebFrameImpl* webframe = WebFrameImpl::fromFrame(frame);
if (!webframe->client())
return;
webframe->client()->didExhaustMemoryAvailableForScript(webframe);
diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc
deleted file mode 100644
index 97dce63..0000000
--- a/webkit/glue/webview_impl.cc
+++ /dev/null
@@ -1,1925 +0,0 @@
-// Copyright (c) 2007-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "config.h"
-
-#include "AXObjectCache.h"
-#include "CSSStyleSelector.h"
-#include "CSSValueKeywords.h"
-#include "Cursor.h"
-#include "Document.h"
-#include "DocumentLoader.h"
-#include "DragController.h"
-#include "DragData.h"
-#include "Editor.h"
-#include "EventHandler.h"
-#include "FocusController.h"
-#include "FontDescription.h"
-#include "FrameLoader.h"
-#include "FrameTree.h"
-#include "FrameView.h"
-#include "GraphicsContext.h"
-#include "HTMLNames.h"
-#include "HTMLInputElement.h"
-#include "HTMLMediaElement.h"
-#include "HitTestResult.h"
-#include "Image.h"
-#include "InspectorController.h"
-#include "IntRect.h"
-#include "KeyboardCodes.h"
-#include "KeyboardEvent.h"
-#include "MIMETypeRegistry.h"
-#include "NodeRenderStyle.h"
-#include "Page.h"
-#include "PageGroup.h"
-#include "Pasteboard.h"
-#include "PlatformContextSkia.h"
-#include "PlatformKeyboardEvent.h"
-#include "PlatformMouseEvent.h"
-#include "PlatformWheelEvent.h"
-#include "PluginInfoStore.h"
-#include "PopupMenuChromium.h"
-#include "PopupMenuClient.h"
-#include "RenderView.h"
-#include "ResourceHandle.h"
-#include "SecurityOrigin.h"
-#include "SelectionController.h"
-#include "Settings.h"
-#include "TypingCommand.h"
-#if PLATFORM(WIN_OS)
-#include "KeyboardCodesWin.h"
-#include "RenderThemeChromiumWin.h"
-#else
-#include "KeyboardCodesPosix.h"
-#include "RenderTheme.h"
-#endif
-#undef LOG
-
-#include "webkit/api/public/WebAccessibilityObject.h"
-#include "webkit/api/public/WebDragData.h"
-#include "webkit/api/public/WebInputEvent.h"
-#include "webkit/api/public/WebMediaPlayerAction.h"
-#include "webkit/api/public/WebPoint.h"
-#include "webkit/api/public/WebRect.h"
-#include "webkit/api/public/WebString.h"
-#include "webkit/api/public/WebVector.h"
-#include "webkit/api/public/WebViewClient.h"
-#include "webkit/api/src/DOMUtilitiesPrivate.h"
-#include "webkit/api/src/WebInputEventConversion.h"
-#include "webkit/api/src/WebPopupMenuImpl.h"
-#include "webkit/api/src/WebSettingsImpl.h"
-#include "webkit/glue/glue_util.h"
-#include "webkit/glue/webdevtoolsagent_impl.h"
-#include "webkit/glue/webkit_glue.h"
-#include "webkit/glue/webview_impl.h"
-
-// Get rid of WTF's pow define so we can use std::pow.
-#undef pow
-#include <cmath> // for std::pow
-
-using namespace WebCore;
-
-using WebKit::ChromeClientImpl;
-using WebKit::EditorClientImpl;
-using WebKit::PlatformKeyboardEventBuilder;
-using WebKit::PlatformMouseEventBuilder;
-using WebKit::PlatformWheelEventBuilder;
-using WebKit::WebAccessibilityObject;
-using WebKit::WebCanvas;
-using WebKit::WebCompositionCommand;
-using WebKit::WebCompositionCommandConfirm;
-using WebKit::WebCompositionCommandDiscard;
-using WebKit::WebDevToolsAgent;
-using WebKit::WebDevToolsAgentClient;
-using WebKit::WebDragData;
-using WebKit::WebDragOperation;
-using WebKit::WebDragOperationCopy;
-using WebKit::WebDragOperationNone;
-using WebKit::WebDragOperationsMask;
-using WebKit::WebFrame;
-using WebKit::WebFrameClient;
-using WebKit::WebInputEvent;
-using WebKit::WebKeyboardEvent;
-using WebKit::WebMediaPlayerAction;
-using WebKit::WebMouseEvent;
-using WebKit::WebMouseWheelEvent;
-using WebKit::WebNavigationPolicy;
-using WebKit::WebNode;
-using WebKit::WebPoint;
-using WebKit::WebPopupMenuImpl;
-using WebKit::WebRect;
-using WebKit::WebSettings;
-using WebKit::WebSettingsImpl;
-using WebKit::WebSize;
-using WebKit::WebString;
-using WebKit::WebTextDirection;
-using WebKit::WebTextDirectionDefault;
-using WebKit::WebTextDirectionLeftToRight;
-using WebKit::WebTextDirectionRightToLeft;
-using WebKit::WebURL;
-using WebKit::WebVector;
-using WebKit::WebViewClient;
-
-using webkit_glue::AccessibilityObjectToWebAccessibilityObject;
-
-// Change the text zoom level by kTextSizeMultiplierRatio each time the user
-// zooms text in or out (ie., change by 20%). The min and max values limit
-// text zoom to half and 3x the original text size. These three values match
-// those in Apple's port in WebKit/WebKit/WebView/WebView.mm
-static const double kTextSizeMultiplierRatio = 1.2;
-static const double kMinTextSizeMultiplier = 0.5;
-static const double kMaxTextSizeMultiplier = 3.0;
-
-// The group name identifies a namespace of pages. Page group is used on OSX
-// for some programs that use HTML views to display things that don't seem like
-// web pages to the user (so shouldn't have visited link coloring). We only use
-// one page group.
-// FIXME: This needs to go into the WebKit API implementation and be hidden
-// from the API's users.
-const char* pageGroupName = "default";
-
-// Ensure that the WebKit::WebDragOperation enum values stay in sync with
-// the original WebCore::DragOperation constants.
-#define COMPILE_ASSERT_MATCHING_ENUM(webcore_name) \
- COMPILE_ASSERT(int(WebCore::webcore_name) == int(WebKit::Web##webcore_name),\
- dummy##webcore_name)
-COMPILE_ASSERT_MATCHING_ENUM(DragOperationNone);
-COMPILE_ASSERT_MATCHING_ENUM(DragOperationCopy);
-COMPILE_ASSERT_MATCHING_ENUM(DragOperationLink);
-COMPILE_ASSERT_MATCHING_ENUM(DragOperationGeneric);
-COMPILE_ASSERT_MATCHING_ENUM(DragOperationPrivate);
-COMPILE_ASSERT_MATCHING_ENUM(DragOperationMove);
-COMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete);
-COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery);
-
-// AutocompletePopupMenuClient
-class AutocompletePopupMenuClient : public WebCore::PopupMenuClient {
- public:
- AutocompletePopupMenuClient(WebViewImpl* webview) : text_field_(NULL),
- selected_index_(0),
- webview_(webview) {
- }
-
- void Init(WebCore::HTMLInputElement* text_field,
- const WebVector<WebString>& suggestions,
- int default_suggestion_index) {
- ASSERT(default_suggestion_index < static_cast<int>(suggestions.size()));
- text_field_ = text_field;
- selected_index_ = default_suggestion_index;
- SetSuggestions(suggestions);
-
- FontDescription font_description;
- webview_->theme()->systemFont(CSSValueWebkitControl, font_description);
- // Use a smaller font size to match IE/Firefox.
- // TODO(jcampan): http://crbug.com/7376 use the system size instead of a
- // fixed font size value.
- font_description.setComputedSize(12.0);
- Font font(font_description, 0, 0);
- font.update(text_field->document()->styleSelector()->fontSelector());
- // The direction of text in popup menu is set the same as the direction of
- // the input element: text_field.
- style_.set(new PopupMenuStyle(Color::black, Color::white, font, true,
- Length(WebCore::Fixed), text_field->renderer()->style()->direction()));
- }
-
- virtual ~AutocompletePopupMenuClient() {
- }
-
- // WebCore::PopupMenuClient implementation.
- virtual void valueChanged(unsigned listIndex, bool fireEvents = true) {
- text_field_->setValue(suggestions_[listIndex]);
- EditorClientImpl* editor =
- static_cast<EditorClientImpl*>(webview_->page()->editorClient());
- ASSERT(editor);
- editor->onAutofillSuggestionAccepted(
- static_cast<WebCore::HTMLInputElement*>(text_field_.get()));
- }
-
- virtual WebCore::String itemText(unsigned list_index) const {
- return suggestions_[list_index];
- }
-
- virtual WebCore::String itemToolTip(unsigned last_index) const {
- notImplemented();
- return WebCore::String();
- }
-
- virtual bool itemIsEnabled(unsigned listIndex) const {
- return true;
- }
-
- virtual PopupMenuStyle itemStyle(unsigned listIndex) const {
- return *style_;
- }
-
- virtual PopupMenuStyle menuStyle() const {
- return *style_;
- }
-
- virtual int clientInsetLeft() const {
- return 0;
- }
- virtual int clientInsetRight() const {
- return 0;
- }
- virtual int clientPaddingLeft() const {
- // Bug http://crbug.com/7708 seems to indicate the style can be NULL.
- WebCore::RenderStyle* style = GetTextFieldStyle();
- return style ? webview_->theme()->popupInternalPaddingLeft(style) : 0;
- }
- virtual int clientPaddingRight() const {
- // Bug http://crbug.com/7708 seems to indicate the style can be NULL.
- WebCore::RenderStyle* style = GetTextFieldStyle();
- return style ? webview_->theme()->popupInternalPaddingRight(style) : 0;
- }
- virtual int listSize() const {
- return suggestions_.size();
- }
- virtual int selectedIndex() const {
- return selected_index_;
- }
- virtual void popupDidHide() {
- webview_->AutoCompletePopupDidHide();
- }
- virtual bool itemIsSeparator(unsigned listIndex) const {
- return false;
- }
- virtual bool itemIsLabel(unsigned listIndex) const {
- return false;
- }
- virtual bool itemIsSelected(unsigned listIndex) const {
- return false;
- }
- virtual bool shouldPopOver() const {
- return false;
- }
- virtual bool valueShouldChangeOnHotTrack() const {
- return false;
- }
-
- virtual void setTextFromItem(unsigned listIndex) {
- text_field_->setValue(suggestions_[listIndex]);
- }
-
- virtual FontSelector* fontSelector() const {
- return text_field_->document()->styleSelector()->fontSelector();
- }
-
- virtual HostWindow* hostWindow() const {
- return text_field_->document()->view()->hostWindow();
- }
-
- virtual PassRefPtr<Scrollbar> createScrollbar(
- ScrollbarClient* client,
- ScrollbarOrientation orientation,
- ScrollbarControlSize size) {
- RefPtr<Scrollbar> widget = Scrollbar::createNativeScrollbar(client,
- orientation,
- size);
- return widget.release();
- }
-
- // AutocompletePopupMenuClient specific methods:
- void SetSuggestions(const WebVector<WebString>& suggestions) {
- suggestions_.clear();
- for (size_t i = 0; i < suggestions.size(); ++i)
- suggestions_.append(webkit_glue::WebStringToString(suggestions[i]));
- // Try to preserve selection if possible.
- if (selected_index_ >= static_cast<int>(suggestions.size()))
- selected_index_ = -1;
- }
-
- void RemoveItemAtIndex(int index) {
- ASSERT(index >= 0 && index < static_cast<int>(suggestions_.size()));
- suggestions_.remove(index);
- }
-
- WebCore::HTMLInputElement* text_field() const {
- return text_field_.get();
- }
-
- WebCore::RenderStyle* GetTextFieldStyle() const {
- WebCore::RenderStyle* style = text_field_->computedStyle();
- if (!style) {
- // It seems we can only have an NULL style in a TextField if the node is
- // dettached, in which case we the popup shoud not be showing. Please
- // report this in http://crbug.com/7708 and include the page you were
- // visiting.
- ASSERT_NOT_REACHED();
- }
- return style;
- }
-
- private:
- RefPtr<WebCore::HTMLInputElement> text_field_;
- Vector<WebCore::String> suggestions_;
- int selected_index_;
- WebViewImpl* webview_;
- OwnPtr<PopupMenuStyle> style_;
-};
-
-// Note that focusOnShow is false so that the autocomplete popup is shown not
-// activated. We need the page to still have focus so the user can keep typing
-// while the popup is showing.
-static const WebCore::PopupContainerSettings kAutocompletePopupSettings = {
- false, // focusOnShow
- false, // setTextOnIndexChange
- false, // acceptOnAbandon
- true, // loopSelectionNavigation
- true, // restrictWidthOfListBox. Same as other browser (Fx, IE, and safari)
- // For autocomplete, we use the direction of the input field as the direction
- // of the popup items. The main reason is to keep the display of items in
- // drop-down the same as the items in the input field.
- WebCore::PopupContainerSettings::DOMElementDirection,
-};
-
-// WebView ----------------------------------------------------------------
-
-namespace WebKit {
-
-// static
-WebView* WebView::create(WebViewClient* client) {
- return new WebViewImpl(client);
-}
-
-// static
-void WebView::updateVisitedLinkState(unsigned long long link_hash) {
- WebCore::Page::visitedStateChanged(
- WebCore::PageGroup::pageGroup(pageGroupName), link_hash);
-}
-
-// static
-void WebView::resetVisitedLinkState() {
- WebCore::Page::allVisitedStateChanged(
- WebCore::PageGroup::pageGroup(pageGroupName));
-}
-
-} // namespace WebKit
-
-void WebViewImpl::initializeMainFrame(WebFrameClient* frame_client) {
- // NOTE: The WebFrameImpl takes a reference to itself within InitMainFrame
- // and releases that reference once the corresponding Frame is destroyed.
- RefPtr<WebFrameImpl> main_frame = WebFrameImpl::create(frame_client);
-
- main_frame->InitMainFrame(this);
-
- if (client_) {
- WebDevToolsAgentClient* tools_client = client_->devToolsAgentClient();
- if (tools_client)
- devtools_agent_.set(new WebDevToolsAgentImpl(this, tools_client));
- }
-
- // Restrict the access to the local file system
- // (see WebView.mm WebView::_commonInitializationWithFrameName).
- SecurityOrigin::setLocalLoadPolicy(
- SecurityOrigin::AllowLocalLoadsForLocalOnly);
-}
-
-WebViewImpl::WebViewImpl(WebViewClient* client)
- : client_(client),
- ALLOW_THIS_IN_INITIALIZER_LIST(back_forward_list_client_impl_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(chrome_client_impl_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(context_menu_client_impl_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(drag_client_impl_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(editor_client_impl_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(inspector_client_impl_(this)),
- observed_new_navigation_(false),
-#ifndef NDEBUG
- new_navigation_loader_(NULL),
-#endif
- zoom_level_(0),
- context_menu_allowed_(false),
- doing_drag_and_drop_(false),
- ignore_input_events_(false),
- suppress_next_keypress_event_(false),
- initial_navigation_policy_(WebKit::WebNavigationPolicyIgnore),
- ime_accept_events_(true),
- drag_target_dispatch_(false),
- drag_identity_(0),
- drop_effect_(DROP_EFFECT_DEFAULT),
- operations_allowed_(WebKit::WebDragOperationNone),
- drag_operation_(WebKit::WebDragOperationNone),
- autocomplete_popup_showing_(false),
- is_transparent_(false),
- tabs_to_links_(false) {
- // WebKit/win/WebView.cpp does the same thing, except they call the
- // KJS specific wrapper around this method. We need to have threading
- // initialized because CollatorICU requires it.
- WTF::initializeThreading();
-
- // set to impossible point so we always get the first mouse pos
- last_mouse_position_ = WebPoint(-1, -1);
-
- // the page will take ownership of the various clients
- page_.set(new Page(&chrome_client_impl_,
- &context_menu_client_impl_,
- &editor_client_impl_,
- &drag_client_impl_,
- &inspector_client_impl_,
- NULL));
-
- page_->backForwardList()->setClient(&back_forward_list_client_impl_);
- page_->setGroupName(pageGroupName);
-}
-
-WebViewImpl::~WebViewImpl() {
- ASSERT(page_ == NULL);
-}
-
-RenderTheme* WebViewImpl::theme() const {
- return page_.get() ? page_->theme() : RenderTheme::defaultTheme().get();
-}
-
-bool WebViewImpl::tabKeyCyclesThroughElements() const {
- ASSERT(page_.get());
- return page_->tabKeyCyclesThroughElements();
-}
-
-void WebViewImpl::setTabKeyCyclesThroughElements(bool value) {
- if (page_ != NULL) {
- page_->setTabKeyCyclesThroughElements(value);
- }
-}
-
-void WebViewImpl::MouseMove(const WebMouseEvent& event) {
- if (!main_frame() || !main_frame()->frameview())
- return;
-
- last_mouse_position_ = WebPoint(event.x, event.y);
-
- // We call mouseMoved here instead of handleMouseMovedEvent because we need
- // our ChromeClientImpl to receive changes to the mouse position and
- // tooltip text, and mouseMoved handles all of that.
- main_frame()->frame()->eventHandler()->mouseMoved(
- PlatformMouseEventBuilder(main_frame()->frameview(), event));
-}
-
-void WebViewImpl::MouseLeave(const WebMouseEvent& event) {
- // This event gets sent as the main frame is closing. In that case, just
- // ignore it.
- if (!main_frame() || !main_frame()->frameview())
- return;
-
- client_->setMouseOverURL(WebURL());
-
- main_frame()->frame()->eventHandler()->handleMouseMoveEvent(
- PlatformMouseEventBuilder(main_frame()->frameview(), event));
-}
-
-void WebViewImpl::MouseDown(const WebMouseEvent& event) {
- if (!main_frame() || !main_frame()->frameview())
- return;
-
- last_mouse_down_point_ = WebPoint(event.x, event.y);
-
- // If a text field that has focus is clicked again, we should display the
- // autocomplete popup.
- RefPtr<Node> clicked_node;
- if (event.button == WebMouseEvent::ButtonLeft) {
- RefPtr<Node> focused_node = GetFocusedNode();
- if (focused_node.get() &&
- WebKit::toHTMLInputElement(focused_node.get())) {
- IntPoint point(event.x, event.y);
- point = page_->mainFrame()->view()->windowToContents(point);
- HitTestResult result(point);
- result = page_->mainFrame()->eventHandler()->hitTestResultAtPoint(point,
- false);
- if (result.innerNonSharedNode() == focused_node) {
- // Already focused text field was clicked, let's remember this. If
- // focus has not changed after the mouse event is processed, we'll
- // trigger the autocomplete.
- clicked_node = focused_node;
- }
- }
- }
-
- main_frame()->frame()->eventHandler()->handleMousePressEvent(
- PlatformMouseEventBuilder(main_frame()->frameview(), event));
-
- if (clicked_node.get() && clicked_node == GetFocusedNode()) {
- // Focus has not changed, show the autocomplete popup.
- static_cast<EditorClientImpl*>(page_->editorClient())->
- showFormAutofillForNode(clicked_node.get());
- }
-
- // Dispatch the contextmenu event regardless of if the click was swallowed.
- // On Windows, we handle it on mouse up, not down.
-#if PLATFORM(DARWIN)
- if (event.button == WebMouseEvent::ButtonRight ||
- (event.button == WebMouseEvent::ButtonLeft &&
- event.modifiers & WebMouseEvent::ControlKey)) {
- MouseContextMenu(event);
- }
-#elif PLATFORM(LINUX)
- if (event.button == WebMouseEvent::ButtonRight)
- MouseContextMenu(event);
-#endif
-}
-
-void WebViewImpl::MouseContextMenu(const WebMouseEvent& event) {
- if (!main_frame() || !main_frame()->frameview())
- return;
-
- page_->contextMenuController()->clearContextMenu();
-
- PlatformMouseEventBuilder pme(main_frame()->frameview(), event);
-
- // Find the right target frame. See issue 1186900.
- HitTestResult result = HitTestResultForWindowPos(pme.pos());
- Frame* target_frame;
- if (result.innerNonSharedNode())
- target_frame = result.innerNonSharedNode()->document()->frame();
- else
- target_frame = page_->focusController()->focusedOrMainFrame();
-
-#if PLATFORM(WIN_OS)
- target_frame->view()->setCursor(pointerCursor());
-#endif
-
- context_menu_allowed_ = true;
- target_frame->eventHandler()->sendContextMenuEvent(pme);
- context_menu_allowed_ = false;
- // Actually showing the context menu is handled by the ContextMenuClient
- // implementation...
-}
-
-void WebViewImpl::MouseUp(const WebMouseEvent& event) {
- if (!main_frame() || !main_frame()->frameview())
- return;
-
-#if PLATFORM(LINUX)
- // If the event was a middle click, attempt to copy text into the focused
- // frame. We execute this before we let the page have a go at the event
- // because the page may change what is focused during in its event handler.
- //
- // This code is in the mouse up handler. There is some debate about putting
- // this here, as opposed to the mouse down handler.
- // xterm: pastes on up.
- // GTK: pastes on down.
- // Firefox: pastes on up.
- // Midori: couldn't paste at all with 0.1.2
- //
- // There is something of a webcompat angle to this well, as highlighted by
- // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
- // down then the text is pasted just before the onclick handler runs and
- // clears the text box. So it's important this happens after the
- // handleMouseReleaseEvent() earlier in this function
- if (event.button == WebMouseEvent::ButtonMiddle) {
- Frame* focused = GetFocusedWebCoreFrame();
- IntPoint click_point(last_mouse_down_point_.x, last_mouse_down_point_.y);
- click_point = page_->mainFrame()->view()->windowToContents(click_point);
- HitTestResult hit_test_result =
- focused->eventHandler()->hitTestResultAtPoint(click_point, false, false,
- ShouldHitTestScrollbars);
- // We don't want to send a paste when middle clicking a scroll bar or a
- // link (which will navigate later in the code).
- if (!hit_test_result.scrollbar() && !hit_test_result.isLiveLink() &&
- focused) {
- Editor* editor = focused->editor();
- Pasteboard* pasteboard = Pasteboard::generalPasteboard();
- bool oldSelectionMode = pasteboard->isSelectionMode();
- pasteboard->setSelectionMode(true);
- editor->command(AtomicString("Paste")).execute();
- pasteboard->setSelectionMode(oldSelectionMode);
- }
- }
-#endif
-
- mouseCaptureLost();
- main_frame()->frame()->eventHandler()->handleMouseReleaseEvent(
- PlatformMouseEventBuilder(main_frame()->frameview(), event));
-
-#if PLATFORM(WIN_OS)
- // Dispatch the contextmenu event regardless of if the click was swallowed.
- // On Mac/Linux, we handle it on mouse down, not up.
- if (event.button == WebMouseEvent::ButtonRight)
- MouseContextMenu(event);
-#endif
-}
-
-void WebViewImpl::MouseWheel(const WebMouseWheelEvent& event) {
- PlatformWheelEventBuilder platform_event(main_frame()->frameview(), event);
- main_frame()->frame()->eventHandler()->handleWheelEvent(platform_event);
-}
-
-bool WebViewImpl::KeyEvent(const WebKeyboardEvent& event) {
- ASSERT((event.type == WebInputEvent::RawKeyDown) ||
- (event.type == WebInputEvent::KeyDown) ||
- (event.type == WebInputEvent::KeyUp));
-
- // Please refer to the comments explaining the suppress_next_keypress_event_
- // member.
- // The suppress_next_keypress_event_ is set if the KeyDown is handled by
- // Webkit. A keyDown event is typically associated with a keyPress(char)
- // event and a keyUp event. We reset this flag here as this is a new keyDown
- // event.
- suppress_next_keypress_event_ = false;
-
- // Give autocomplete a chance to consume the key events it is interested in.
- if (AutocompleteHandleKeyEvent(event))
- return true;
-
- Frame* frame = GetFocusedWebCoreFrame();
- if (!frame)
- return false;
-
- EventHandler* handler = frame->eventHandler();
- if (!handler)
- return KeyEventDefault(event);
-
-#if PLATFORM(WIN_OS) || PLATFORM(LINUX)
- if (((event.modifiers == 0) && (event.windowsKeyCode == VKEY_APPS)) ||
- ((event.modifiers == WebInputEvent::ShiftKey) &&
- (event.windowsKeyCode == VKEY_F10))) {
- SendContextMenuEvent(event);
- return true;
- }
-#endif
-
- // It's not clear if we should continue after detecting a capslock keypress.
- // I'll err on the side of continuing, which is the pre-existing behaviour.
- if (event.windowsKeyCode == VKEY_CAPITAL)
- handler->capsLockStateMayHaveChanged();
-
- PlatformKeyboardEventBuilder evt(event);
-
- if (handler->keyEvent(evt)) {
- if (WebInputEvent::RawKeyDown == event.type && !evt.isSystemKey())
- suppress_next_keypress_event_ = true;
- return true;
- }
-
- return KeyEventDefault(event);
-}
-
-bool WebViewImpl::AutocompleteHandleKeyEvent(const WebKeyboardEvent& event) {
- if (!autocomplete_popup_showing_ ||
- // Home and End should be left to the text field to process.
- event.windowsKeyCode == VKEY_HOME ||
- event.windowsKeyCode == VKEY_END) {
- return false;
- }
-
- // Pressing delete triggers the removal of the selected suggestion from the
- // DB.
- if (event.windowsKeyCode == VKEY_DELETE &&
- autocomplete_popup_->selectedIndex() != -1) {
- Node* node = GetFocusedNode();
- if (!node || (node->nodeType() != WebCore::Node::ELEMENT_NODE)) {
- ASSERT_NOT_REACHED();
- return false;
- }
- WebCore::Element* element = static_cast<WebCore::Element*>(node);
- if (!element->hasLocalName(WebCore::HTMLNames::inputTag)) {
- ASSERT_NOT_REACHED();
- return false;
- }
-
- int selected_index = autocomplete_popup_->selectedIndex();
- WebCore::HTMLInputElement* input_element =
- static_cast<WebCore::HTMLInputElement*>(element);
- const WebString& name = webkit_glue::StringToWebString(
- input_element->name());
- const WebString& value = webkit_glue::StringToWebString(
- autocomplete_popup_client_->itemText(selected_index));
- client_->removeAutofillSuggestions(name, value);
- // Update the entries in the currently showing popup to reflect the
- // deletion.
- autocomplete_popup_client_->RemoveItemAtIndex(selected_index);
- RefreshAutofillPopup();
- return false;
- }
-
- if (!autocomplete_popup_->isInterestedInEventForKey(event.windowsKeyCode))
- return false;
-
- if (autocomplete_popup_->handleKeyEvent(
- PlatformKeyboardEventBuilder(event))) {
- // We need to ignore the next Char event after this otherwise pressing
- // enter when selecting an item in the menu will go to the page.
- if (WebInputEvent::RawKeyDown == event.type)
- suppress_next_keypress_event_ = true;
- return true;
- }
-
- return false;
-}
-
-bool WebViewImpl::CharEvent(const WebKeyboardEvent& event) {
- ASSERT(event.type == WebInputEvent::Char);
-
- // Please refer to the comments explaining the suppress_next_keypress_event_
- // member.
- // The suppress_next_keypress_event_ is set if the KeyDown is handled by
- // Webkit. A keyDown event is typically associated with a keyPress(char)
- // event and a keyUp event. We reset this flag here as it only applies
- // to the current keyPress event.
- if (suppress_next_keypress_event_) {
- suppress_next_keypress_event_ = false;
- return true;
- }
-
- Frame* frame = GetFocusedWebCoreFrame();
- if (!frame)
- return false;
-
- EventHandler* handler = frame->eventHandler();
- if (!handler)
- return KeyEventDefault(event);
-
- PlatformKeyboardEventBuilder evt(event);
- if (!evt.isCharacterKey())
- return true;
-
- // Safari 3.1 does not pass off windows system key messages (WM_SYSCHAR) to
- // the eventHandler::keyEvent. We mimic this behavior on all platforms since
- // for now we are converting other platform's key events to windows key
- // events.
- if (evt.isSystemKey())
- return handler->handleAccessKey(evt);
-
- if (!handler->keyEvent(evt))
- return KeyEventDefault(event);
-
- return true;
-}
-
-/*
-* The WebViewImpl::SendContextMenuEvent function is based on the Webkit
-* function
-* bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam) in
-* webkit\webkit\win\WebView.cpp. The only significant change in this
-* function is the code to convert from a Keyboard event to the Right
-* Mouse button up event.
-*
-* This function is an ugly copy/paste and should be cleaned up when the
-* WebKitWin version is cleaned: https://bugs.webkit.org/show_bug.cgi?id=20438
-*/
-#if PLATFORM(WIN_OS) || PLATFORM(LINUX)
-// TODO(pinkerton): implement on non-windows
-bool WebViewImpl::SendContextMenuEvent(const WebKeyboardEvent& event) {
- static const int kContextMenuMargin = 1;
- Frame* main_frame = page()->mainFrame();
- FrameView* view = main_frame->view();
- if (!view)
- return false;
-
- IntPoint coords(-1, -1);
-#if PLATFORM(WIN_OS)
- int right_aligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
-#else
- int right_aligned = 0;
-#endif
- IntPoint location;
-
- // The context menu event was generated from the keyboard, so show the
- // context menu by the current selection.
- Position start = main_frame->selection()->selection().start();
- Position end = main_frame->selection()->selection().end();
-
- if (!start.node() || !end.node()) {
- location =
- IntPoint(right_aligned ? view->contentsWidth() - kContextMenuMargin
- : kContextMenuMargin, kContextMenuMargin);
- } else {
- RenderObject* renderer = start.node()->renderer();
- if (!renderer)
- return false;
-
- RefPtr<Range> selection = main_frame->selection()->toNormalizedRange();
- IntRect first_rect = main_frame->firstRectForRange(selection.get());
-
- int x = right_aligned ? first_rect.right() : first_rect.x();
- location = IntPoint(x, first_rect.bottom());
- }
-
- location = view->contentsToWindow(location);
- // FIXME: The IntSize(0, -1) is a hack to get the hit-testing to result in
- // the selected element. Ideally we'd have the position of a context menu
- // event be separate from its target node.
- coords = location + IntSize(0, -1);
-
- // The contextMenuController() holds onto the last context menu that was
- // popped up on the page until a new one is created. We need to clear
- // this menu before propagating the event through the DOM so that we can
- // detect if we create a new menu for this event, since we won't create
- // a new menu if the DOM swallows the event and the defaultEventHandler does
- // not run.
- page()->contextMenuController()->clearContextMenu();
-
- Frame* focused_frame = page()->focusController()->focusedOrMainFrame();
- focused_frame->view()->setCursor(pointerCursor());
- WebMouseEvent mouse_event;
- mouse_event.button = WebMouseEvent::ButtonRight;
- mouse_event.x = coords.x();
- mouse_event.y = coords.y();
- mouse_event.type = WebInputEvent::MouseUp;
-
- PlatformMouseEventBuilder platform_event(view, mouse_event);
-
- context_menu_allowed_ = true;
- bool handled =
- focused_frame->eventHandler()->sendContextMenuEvent(platform_event);
- context_menu_allowed_ = false;
- return handled;
-}
-#endif
-
-bool WebViewImpl::KeyEventDefault(const WebKeyboardEvent& event) {
- Frame* frame = GetFocusedWebCoreFrame();
- if (!frame)
- return false;
-
- switch (event.type) {
- case WebInputEvent::Char: {
- if (event.windowsKeyCode == VKEY_SPACE) {
- int key_code = ((event.modifiers & WebInputEvent::ShiftKey) ?
- VKEY_PRIOR : VKEY_NEXT);
- return ScrollViewWithKeyboard(key_code, event.modifiers);
- }
- break;
- }
-
- case WebInputEvent::RawKeyDown: {
- if (event.modifiers == WebInputEvent::ControlKey) {
- switch (event.windowsKeyCode) {
- case 'A':
- focusedFrame()->executeCommand(WebString::fromUTF8("SelectAll"));
- return true;
- case VKEY_INSERT:
- case 'C':
- focusedFrame()->executeCommand(WebString::fromUTF8("Copy"));
- return true;
- // Match FF behavior in the sense that Ctrl+home/end are the only Ctrl
- // key combinations which affect scrolling. Safari is buggy in the
- // sense that it scrolls the page for all Ctrl+scrolling key
- // combinations. For e.g. Ctrl+pgup/pgdn/up/down, etc.
- case VKEY_HOME:
- case VKEY_END:
- break;
- default:
- return false;
- }
- }
- if (!event.isSystemKey && !(event.modifiers & WebInputEvent::ShiftKey)) {
- return ScrollViewWithKeyboard(event.windowsKeyCode, event.modifiers);
- }
- break;
- }
-
- default:
- break;
- }
- return false;
-}
-
-bool WebViewImpl::ScrollViewWithKeyboard(int key_code, int modifiers) {
- ScrollDirection scroll_direction;
- ScrollGranularity scroll_granularity;
-
- switch (key_code) {
- case VKEY_LEFT:
- scroll_direction = ScrollLeft;
- scroll_granularity = ScrollByLine;
- break;
- case VKEY_RIGHT:
- scroll_direction = ScrollRight;
- scroll_granularity = ScrollByLine;
- break;
- case VKEY_UP:
- scroll_direction = ScrollUp;
- scroll_granularity = ScrollByLine;
- break;
- case VKEY_DOWN:
- scroll_direction = ScrollDown;
- scroll_granularity = ScrollByLine;
- break;
- case VKEY_HOME:
- scroll_direction = ScrollUp;
- scroll_granularity = ScrollByDocument;
- break;
- case VKEY_END:
- scroll_direction = ScrollDown;
- scroll_granularity = ScrollByDocument;
- break;
- case VKEY_PRIOR: // page up
- scroll_direction = ScrollUp;
- scroll_granularity = ScrollByPage;
- break;
- case VKEY_NEXT: // page down
- scroll_direction = ScrollDown;
- scroll_granularity = ScrollByPage;
- break;
- default:
- return false;
- }
-
- return PropagateScroll(scroll_direction, scroll_granularity);
-}
-
-bool WebViewImpl::PropagateScroll(
- WebCore::ScrollDirection scroll_direction,
- WebCore::ScrollGranularity scroll_granularity) {
-
- Frame* frame = GetFocusedWebCoreFrame();
- if (!frame)
- return false;
-
- bool scroll_handled =
- frame->eventHandler()->scrollOverflow(scroll_direction,
- scroll_granularity);
- Frame* current_frame = frame;
- while (!scroll_handled && current_frame) {
- scroll_handled = current_frame->view()->scroll(scroll_direction,
- scroll_granularity);
- current_frame = current_frame->tree()->parent();
- }
- return scroll_handled;
-}
-
-Frame* WebViewImpl::GetFocusedWebCoreFrame() {
- return page_.get() ? page_->focusController()->focusedOrMainFrame() : NULL;
-}
-
-// static
-WebViewImpl* WebViewImpl::FromPage(WebCore::Page* page) {
- if (!page)
- return NULL;
-
- return static_cast<ChromeClientImpl*>(page->chrome()->client())->webview();
-}
-
-// WebWidget ------------------------------------------------------------------
-
-void WebViewImpl::close() {
- RefPtr<WebFrameImpl> main_frame;
-
- if (page_.get()) {
- // Initiate shutdown for the entire frameset. This will cause a lot of
- // notifications to be sent.
- if (page_->mainFrame()) {
- main_frame = WebFrameImpl::FromFrame(page_->mainFrame());
- page_->mainFrame()->loader()->frameDetached();
- }
- page_.clear();
- }
-
- // Should happen after page_.reset().
- if (devtools_agent_.get())
- devtools_agent_.clear();
-
- // We drop the client after the page has been destroyed to support the
- // WebFrameClient::didDestroyScriptContext method.
- if (main_frame)
- main_frame->drop_client();
-
- // Reset the delegate to prevent notifications being sent as we're being
- // deleted.
- client_ = NULL;
-
- deref(); // Balances ref() acquired in WebView::create
-}
-
-void WebViewImpl::resize(const WebSize& new_size) {
- if (size_ == new_size)
- return;
- size_ = new_size;
-
- if (main_frame()->frameview()) {
- main_frame()->frameview()->resize(size_.width, size_.height);
- main_frame()->frame()->eventHandler()->sendResizeEvent();
- }
-
- if (client_) {
- WebRect damaged_rect(0, 0, size_.width, size_.height);
- client_->didInvalidateRect(damaged_rect);
- }
-}
-
-void WebViewImpl::layout() {
- WebFrameImpl* webframe = main_frame();
- if (webframe) {
- // In order for our child HWNDs (NativeWindowWidgets) to update properly,
- // they need to be told that we are updating the screen. The problem is
- // that the native widgets need to recalculate their clip region and not
- // overlap any of our non-native widgets. To force the resizing, call
- // setFrameRect(). This will be a quick operation for most frames, but
- // the NativeWindowWidgets will update a proper clipping region.
- FrameView* view = webframe->frameview();
- if (view)
- view->setFrameRect(view->frameRect());
-
- // setFrameRect may have the side-effect of causing existing page
- // layout to be invalidated, so layout needs to be called last.
-
- webframe->Layout();
- }
-}
-
-void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect) {
- WebFrameImpl* webframe = main_frame();
- if (webframe)
- webframe->Paint(canvas, rect);
-}
-
-// TODO(eseidel): g_current_input_event should be removed once
-// ChromeClient:show() can get the current-event information from WebCore.
-/* static */
-const WebInputEvent* WebViewImpl::g_current_input_event = NULL;
-
-bool WebViewImpl::handleInputEvent(const WebInputEvent& input_event) {
- // If we've started a drag and drop operation, ignore input events until
- // we're done.
- if (doing_drag_and_drop_)
- return true;
-
- if (ignore_input_events_)
- return true;
-
- // TODO(eseidel): Remove g_current_input_event.
- // This only exists to allow ChromeClient::show() to know which mouse button
- // triggered a window.open event.
- // Safari must perform a similar hack, ours is in our WebKit glue layer
- // theirs is in the application. This should go when WebCore can be fixed
- // to pass more event information to ChromeClient::show()
- g_current_input_event = &input_event;
-
- bool handled = true;
-
- // TODO(jcampan): WebKit seems to always return false on mouse events
- // processing methods. For now we'll assume it has processed them (as we are
- // only interested in whether keyboard events are processed).
- switch (input_event.type) {
- case WebInputEvent::MouseMove:
- MouseMove(*static_cast<const WebMouseEvent*>(&input_event));
- break;
-
- case WebInputEvent::MouseLeave:
- MouseLeave(*static_cast<const WebMouseEvent*>(&input_event));
- break;
-
- case WebInputEvent::MouseWheel:
- MouseWheel(*static_cast<const WebMouseWheelEvent*>(&input_event));
- break;
-
- case WebInputEvent::MouseDown:
- MouseDown(*static_cast<const WebMouseEvent*>(&input_event));
- break;
-
- case WebInputEvent::MouseUp:
- MouseUp(*static_cast<const WebMouseEvent*>(&input_event));
- break;
-
- case WebInputEvent::RawKeyDown:
- case WebInputEvent::KeyDown:
- case WebInputEvent::KeyUp:
- handled = KeyEvent(*static_cast<const WebKeyboardEvent*>(&input_event));
- break;
-
- case WebInputEvent::Char:
- handled = CharEvent(*static_cast<const WebKeyboardEvent*>(&input_event));
- break;
- default:
- handled = false;
- }
-
- g_current_input_event = NULL;
-
- return handled;
-}
-
-void WebViewImpl::mouseCaptureLost() {
-}
-
-void WebViewImpl::setFocus(bool enable) {
- page_->focusController()->setFocused(enable);
- if (enable) {
- // Note that we don't call setActive() when disabled as this cause extra
- // focus/blur events to be dispatched.
- page_->focusController()->setActive(true);
- ime_accept_events_ = true;
- } else {
- HideAutoCompletePopup();
-
- // Clear focus on the currently focused frame if any.
- if (!page_.get())
- return;
-
- Frame* frame = page_->mainFrame();
- if (!frame)
- return;
-
- RefPtr<Frame> focused_frame = page_->focusController()->focusedFrame();
- if (focused_frame.get()) {
- // Finish an ongoing composition to delete the composition node.
- Editor* editor = focused_frame->editor();
- if (editor && editor->hasComposition())
- editor->confirmComposition();
- ime_accept_events_ = false;
- }
- }
-}
-
-bool WebViewImpl::handleCompositionEvent(WebCompositionCommand command,
- int cursor_position,
- int target_start,
- int target_end,
- const WebString& ime_string) {
- Frame* focused = GetFocusedWebCoreFrame();
- if (!focused || !ime_accept_events_) {
- return false;
- }
- Editor* editor = focused->editor();
- if (!editor)
- return false;
- if (!editor->canEdit()) {
- // The input focus has been moved to another WebWidget object.
- // We should use this |editor| object only to complete the ongoing
- // composition.
- if (!editor->hasComposition())
- return false;
- }
-
- // We should verify the parent node of this IME composition node are
- // editable because JavaScript may delete a parent node of the composition
- // node. In this case, WebKit crashes while deleting texts from the parent
- // node, which doesn't exist any longer.
- PassRefPtr<Range> range = editor->compositionRange();
- if (range) {
- const Node* node = range->startPosition().node();
- if (!node || !node->isContentEditable())
- return false;
- }
-
- if (command == WebCompositionCommandDiscard) {
- // A browser process sent an IPC message which does not contain a valid
- // string, which means an ongoing composition has been canceled.
- // If the ongoing composition has been canceled, replace the ongoing
- // composition string with an empty string and complete it.
- WebCore::String empty_string;
- WTF::Vector<WebCore::CompositionUnderline> empty_underlines;
- editor->setComposition(empty_string, empty_underlines, 0, 0);
- } else {
- // A browser process sent an IPC message which contains a string to be
- // displayed in this Editor object.
- // To display the given string, set the given string to the
- // m_compositionNode member of this Editor object and display it.
- if (target_start < 0)
- target_start = 0;
- if (target_end < 0)
- target_end = static_cast<int>(ime_string.length());
- WebCore::String composition_string(
- webkit_glue::WebStringToString(ime_string));
- // Create custom underlines.
- // To emphasize the selection, the selected region uses a solid black
- // for its underline while other regions uses a pale gray for theirs.
- WTF::Vector<WebCore::CompositionUnderline> underlines(3);
- underlines[0].startOffset = 0;
- underlines[0].endOffset = target_start;
- underlines[0].thick = true;
- underlines[0].color.setRGB(0xd3, 0xd3, 0xd3);
- underlines[1].startOffset = target_start;
- underlines[1].endOffset = target_end;
- underlines[1].thick = true;
- underlines[1].color.setRGB(0x00, 0x00, 0x00);
- underlines[2].startOffset = target_end;
- underlines[2].endOffset = static_cast<int>(ime_string.length());
- underlines[2].thick = true;
- underlines[2].color.setRGB(0xd3, 0xd3, 0xd3);
- // When we use custom underlines, WebKit ("InlineTextBox.cpp" Line 282)
- // prevents from writing a text in between 'selectionStart' and
- // 'selectionEnd' somehow.
- // Therefore, we use the 'cursor_position' for these arguments so that
- // there are not any characters in the above region.
- editor->setComposition(composition_string, underlines,
- cursor_position, cursor_position);
- // The given string is a result string, which means the ongoing
- // composition has been completed. I have to call the
- // Editor::confirmCompletion() and complete this composition.
- if (command == WebCompositionCommandConfirm)
- editor->confirmComposition();
- }
-
- return editor->hasComposition();
-}
-
-bool WebViewImpl::queryCompositionStatus(bool* enable_ime,
- WebRect* caret_rect) {
- // Store whether the selected node needs IME and the caret rectangle.
- // This process consists of the following four steps:
- // 1. Retrieve the selection controller of the focused frame;
- // 2. Retrieve the caret rectangle from the controller;
- // 3. Convert the rectangle, which is relative to the parent view, to the
- // one relative to the client window, and;
- // 4. Store the converted rectangle.
- const Frame* focused = GetFocusedWebCoreFrame();
- if (!focused)
- return false;
-
- const Editor* editor = focused->editor();
- if (!editor || !editor->canEdit())
- return false;
-
- SelectionController* controller = focused->selection();
- if (!controller)
- return false;
-
- const Node* node = controller->start().node();
- if (!node)
- return false;
-
- *enable_ime = node->shouldUseInputMethod() &&
- !controller->isInPasswordField();
- const FrameView* view = node->document()->view();
- if (!view)
- return false;
-
- *caret_rect = webkit_glue::IntRectToWebRect(
- view->contentsToWindow(controller->absoluteCaretBounds()));
- return true;
-}
-
-void WebViewImpl::setTextDirection(WebTextDirection direction) {
- // The Editor::setBaseWritingDirection() function checks if we can change
- // the text direction of the selected node and updates its DOM "dir"
- // attribute and its CSS "direction" property.
- // So, we just call the function as Safari does.
- const Frame* focused = GetFocusedWebCoreFrame();
- if (!focused)
- return;
-
- Editor* editor = focused->editor();
- if (!editor || !editor->canEdit())
- return;
-
- switch (direction) {
- case WebTextDirectionDefault:
- editor->setBaseWritingDirection(WebCore::NaturalWritingDirection);
- break;
-
- case WebTextDirectionLeftToRight:
- editor->setBaseWritingDirection(WebCore::LeftToRightWritingDirection);
- break;
-
- case WebTextDirectionRightToLeft:
- editor->setBaseWritingDirection(WebCore::RightToLeftWritingDirection);
- break;
-
- default:
- notImplemented();
- break;
- }
-}
-
-// WebView --------------------------------------------------------------------
-
-WebSettings* WebViewImpl::settings() {
- if (!web_settings_.get())
- web_settings_.set(new WebSettingsImpl(page_->settings()));
- ASSERT(web_settings_.get());
- return web_settings_.get();
-}
-
-WebString WebViewImpl::pageEncoding() const {
- if (!page_.get())
- return WebString();
-
- String encoding_name = page_->mainFrame()->loader()->encoding();
- return webkit_glue::StringToWebString(encoding_name);
-}
-
-void WebViewImpl::setPageEncoding(const WebString& encoding_name) {
- if (!page_.get())
- return;
-
- // Only change override encoding, don't change default encoding.
- // Note that the new encoding must be NULL if it isn't supposed to be set.
- String new_encoding_name;
- if (!encoding_name.isEmpty())
- new_encoding_name = webkit_glue::WebStringToString(encoding_name);
- page_->mainFrame()->loader()->reloadWithOverrideEncoding(new_encoding_name);
-}
-
-bool WebViewImpl::dispatchBeforeUnloadEvent() {
- // TODO(creis): This should really cause a recursive depth-first walk of all
- // frames in the tree, calling each frame's onbeforeunload. At the moment,
- // we're consistent with Safari 3.1, not IE/FF.
- Frame* frame = page_->focusController()->focusedOrMainFrame();
- if (!frame)
- return true;
-
- return frame->shouldClose();
-}
-
-void WebViewImpl::dispatchUnloadEvent() {
- // Run unload handlers.
- page_->mainFrame()->loader()->closeURL();
-}
-
-WebFrame* WebViewImpl::mainFrame() {
- return main_frame();
-}
-
-WebFrame* WebViewImpl::findFrameByName(
- const WebString& name, WebFrame* relative_to_frame) {
- String name_str = webkit_glue::WebStringToString(name);
- if (!relative_to_frame)
- relative_to_frame = mainFrame();
- Frame* frame = static_cast<WebFrameImpl*>(relative_to_frame)->frame();
- frame = frame->tree()->find(name_str);
- return WebFrameImpl::FromFrame(frame);
-}
-
-WebFrame* WebViewImpl::focusedFrame() {
- return WebFrameImpl::FromFrame(GetFocusedWebCoreFrame());
-}
-
-void WebViewImpl::setFocusedFrame(WebFrame* frame) {
- if (!frame) {
- // Clears the focused frame if any.
- Frame* frame = GetFocusedWebCoreFrame();
- if (frame)
- frame->selection()->setFocused(false);
- return;
- }
- WebFrameImpl* frame_impl = static_cast<WebFrameImpl*>(frame);
- WebCore::Frame* webcore_frame = frame_impl->frame();
- webcore_frame->page()->focusController()->setFocusedFrame(webcore_frame);
-}
-
-void WebViewImpl::setInitialFocus(bool reverse) {
- if (!page_.get())
- return;
-
- // Since we don't have a keyboard event, we'll create one.
- WebKeyboardEvent keyboard_event;
- keyboard_event.type = WebInputEvent::RawKeyDown;
- if (reverse)
- keyboard_event.modifiers = WebInputEvent::ShiftKey;
-
- // VK_TAB which is only defined on Windows.
- keyboard_event.windowsKeyCode = 0x09;
- PlatformKeyboardEventBuilder platform_event(keyboard_event);
- RefPtr<KeyboardEvent> webkit_event =
- KeyboardEvent::create(platform_event, NULL);
- page()->focusController()->setInitialFocus(
- reverse ? WebCore::FocusDirectionBackward :
- WebCore::FocusDirectionForward,
- webkit_event.get());
-}
-
-void WebViewImpl::clearFocusedNode() {
- if (!page_.get())
- return;
-
- RefPtr<Frame> frame = page_->mainFrame();
- if (!frame.get())
- return;
-
- RefPtr<Document> document = frame->document();
- if (!document.get())
- return;
-
- RefPtr<Node> old_focused_node = document->focusedNode();
-
- // Clear the focused node.
- document->setFocusedNode(NULL);
-
- if (!old_focused_node.get())
- return;
-
- // If a text field has focus, we need to make sure the selection controller
- // knows to remove selection from it. Otherwise, the text field is still
- // processing keyboard events even though focus has been moved to the page and
- // keystrokes get eaten as a result.
- if (old_focused_node->hasTagName(HTMLNames::textareaTag) ||
- (old_focused_node->hasTagName(HTMLNames::inputTag) &&
- static_cast<HTMLInputElement*>(old_focused_node.get())->isTextField())) {
- // Clear the selection.
- SelectionController* selection = frame->selection();
- selection->clear();
- }
-}
-
-void WebViewImpl::zoomIn(bool text_only) {
- Frame* frame = main_frame()->frame();
- double multiplier = std::min(std::pow(kTextSizeMultiplierRatio,
- zoom_level_ + 1),
- kMaxTextSizeMultiplier);
- float zoom_factor = static_cast<float>(multiplier);
- if (zoom_factor != frame->zoomFactor()) {
- ++zoom_level_;
- frame->setZoomFactor(zoom_factor, text_only);
- }
-}
-
-void WebViewImpl::zoomOut(bool text_only) {
- Frame* frame = main_frame()->frame();
- double multiplier = std::max(std::pow(kTextSizeMultiplierRatio,
- zoom_level_ - 1),
- kMinTextSizeMultiplier);
- float zoom_factor = static_cast<float>(multiplier);
- if (zoom_factor != frame->zoomFactor()) {
- --zoom_level_;
- frame->setZoomFactor(zoom_factor, text_only);
- }
-}
-
-void WebViewImpl::zoomDefault() {
- // We don't change the zoom mode (text only vs. full page) here. We just want
- // to reset whatever is already set.
- zoom_level_ = 0;
- main_frame()->frame()->setZoomFactor(
- 1.0f,
- main_frame()->frame()->isZoomFactorTextOnly());
-}
-
-void WebViewImpl::performMediaPlayerAction(const WebMediaPlayerAction& action,
- const WebPoint& location) {
- HitTestResult result =
- HitTestResultForWindowPos(webkit_glue::WebPointToIntPoint(location));
- WTF::RefPtr<WebCore::Node> node = result.innerNonSharedNode();
- if (!node->hasTagName(WebCore::HTMLNames::videoTag) &&
- !node->hasTagName(WebCore::HTMLNames::audioTag))
- return;
-
- WTF::RefPtr<WebCore::HTMLMediaElement> media_element =
- static_pointer_cast<WebCore::HTMLMediaElement>(node);
- switch (action.type) {
- case WebMediaPlayerAction::Play:
- if (action.enable) {
- media_element->play();
- } else {
- media_element->pause();
- }
- break;
- case WebMediaPlayerAction::Mute:
- media_element->setMuted(action.enable);
- break;
- case WebMediaPlayerAction::Loop:
- media_element->setLoop(action.enable);
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-}
-
-void WebViewImpl::copyImageAt(const WebPoint& point) {
- if (!page_.get())
- return;
-
- HitTestResult result =
- HitTestResultForWindowPos(webkit_glue::WebPointToIntPoint(point));
-
- if (result.absoluteImageURL().isEmpty()) {
- // There isn't actually an image at these coordinates. Might be because
- // the window scrolled while the context menu was open or because the page
- // changed itself between when we thought there was an image here and when
- // we actually tried to retreive the image.
- //
- // TODO: implement a cache of the most recent HitTestResult to avoid having
- // to do two hit tests.
- return;
- }
-
- page_->mainFrame()->editor()->copyImage(result);
-}
-
-void WebViewImpl::dragSourceEndedAt(
- const WebPoint& client_point,
- const WebPoint& screen_point,
- WebDragOperation operation) {
- PlatformMouseEvent pme(webkit_glue::WebPointToIntPoint(client_point),
- webkit_glue::WebPointToIntPoint(screen_point),
- LeftButton, MouseEventMoved, 0, false, false, false,
- false, 0);
- page_->mainFrame()->eventHandler()->dragSourceEndedAt(pme,
- static_cast<WebCore::DragOperation>(operation));
-}
-
-void WebViewImpl::dragSourceMovedTo(
- const WebPoint& client_point,
- const WebPoint& screen_point) {
- PlatformMouseEvent pme(webkit_glue::WebPointToIntPoint(client_point),
- webkit_glue::WebPointToIntPoint(screen_point),
- LeftButton, MouseEventMoved, 0, false, false, false,
- false, 0);
- page_->mainFrame()->eventHandler()->dragSourceMovedTo(pme);
-}
-
-void WebViewImpl::dragSourceSystemDragEnded() {
- // It's possible for us to get this callback while not doing a drag if
- // it's from a previous page that got unloaded.
- if (doing_drag_and_drop_) {
- page_->dragController()->dragEnded();
- doing_drag_and_drop_ = false;
- }
-}
-
-WebDragOperation WebViewImpl::dragTargetDragEnter(
- const WebDragData& web_drag_data, int identity,
- const WebPoint& client_point,
- const WebPoint& screen_point,
- WebDragOperationsMask operations_allowed) {
- ASSERT(!current_drag_data_.get());
-
- current_drag_data_ =
- webkit_glue::WebDragDataToChromiumDataObject(web_drag_data);
- drag_identity_ = identity;
- operations_allowed_ = operations_allowed;
-
- DragData drag_data(
- current_drag_data_.get(),
- webkit_glue::WebPointToIntPoint(client_point),
- webkit_glue::WebPointToIntPoint(screen_point),
- static_cast<WebCore::DragOperation>(operations_allowed));
-
- drop_effect_ = DROP_EFFECT_DEFAULT;
- drag_target_dispatch_ = true;
- DragOperation effect = page_->dragController()->dragEntered(&drag_data);
- // Mask the operation against the drag source's allowed operations.
- if ((effect & drag_data.draggingSourceOperationMask()) != effect) {
- effect = DragOperationNone;
- }
- drag_target_dispatch_ = false;
-
- if (drop_effect_ != DROP_EFFECT_DEFAULT)
- drag_operation_ = (drop_effect_ != DROP_EFFECT_NONE) ?
- WebDragOperationCopy : WebDragOperationNone;
- else
- drag_operation_ = static_cast<WebDragOperation>(effect);
- return drag_operation_;
-}
-
-WebDragOperation WebViewImpl::dragTargetDragOver(
- const WebPoint& client_point,
- const WebPoint& screen_point,
- WebDragOperationsMask operations_allowed) {
- ASSERT(current_drag_data_.get());
-
- operations_allowed_ = operations_allowed;
- DragData drag_data(
- current_drag_data_.get(),
- webkit_glue::WebPointToIntPoint(client_point),
- webkit_glue::WebPointToIntPoint(screen_point),
- static_cast<WebCore::DragOperation>(operations_allowed));
-
- drop_effect_ = DROP_EFFECT_DEFAULT;
- drag_target_dispatch_ = true;
- DragOperation effect = page_->dragController()->dragUpdated(&drag_data);
- // Mask the operation against the drag source's allowed operations.
- if ((effect & drag_data.draggingSourceOperationMask()) != effect) {
- effect = DragOperationNone;
- }
- drag_target_dispatch_ = false;
-
- if (drop_effect_ != DROP_EFFECT_DEFAULT)
- drag_operation_ = (drop_effect_ != DROP_EFFECT_NONE) ?
- WebDragOperationCopy : WebDragOperationNone;
- else
- drag_operation_ = static_cast<WebDragOperation>(effect);
- return drag_operation_;
-}
-
-void WebViewImpl::dragTargetDragLeave() {
- ASSERT(current_drag_data_.get());
-
- DragData drag_data(
- current_drag_data_.get(),
- IntPoint(),
- IntPoint(),
- static_cast<WebCore::DragOperation>(operations_allowed_));
-
- drag_target_dispatch_ = true;
- page_->dragController()->dragExited(&drag_data);
- drag_target_dispatch_ = false;
-
- current_drag_data_ = NULL;
- drop_effect_ = DROP_EFFECT_DEFAULT;
- drag_operation_ = WebDragOperationNone;
- drag_identity_ = 0;
-}
-
-void WebViewImpl::dragTargetDrop(const WebPoint& client_point,
- const WebPoint& screen_point) {
- ASSERT(current_drag_data_.get());
-
- // If this webview transitions from the "drop accepting" state to the "not
- // accepting" state, then our IPC message reply indicating that may be in-
- // flight, or else delayed by javascript processing in this webview. If a
- // drop happens before our IPC reply has reached the browser process, then
- // the browser forwards the drop to this webview. So only allow a drop to
- // proceed if our webview drag_operation_ state is not DragOperationNone.
-
- if (drag_operation_ == WebDragOperationNone) { // IPC RACE CONDITION: do not allow this drop.
- dragTargetDragLeave();
- return;
- }
-
- DragData drag_data(
- current_drag_data_.get(),
- webkit_glue::WebPointToIntPoint(client_point),
- webkit_glue::WebPointToIntPoint(screen_point),
- static_cast<WebCore::DragOperation>(operations_allowed_));
-
- drag_target_dispatch_ = true;
- page_->dragController()->performDrag(&drag_data);
- drag_target_dispatch_ = false;
-
- current_drag_data_ = NULL;
- drop_effect_ = DROP_EFFECT_DEFAULT;
- drag_operation_ = WebDragOperationNone;
- drag_identity_ = 0;
-}
-
-int WebViewImpl::dragIdentity() {
- if (drag_target_dispatch_)
- return drag_identity_;
- return 0;
-}
-
-void WebViewImpl::inspectElementAt(const WebPoint& point) {
- if (!page_.get())
- return;
-
- if (point.x == -1 || point.y == -1) {
- page_->inspectorController()->inspect(NULL);
- } else {
- HitTestResult result =
- HitTestResultForWindowPos(webkit_glue::WebPointToIntPoint(point));
-
- if (!result.innerNonSharedNode())
- return;
-
- page_->inspectorController()->inspect(result.innerNonSharedNode());
- }
-}
-
-WebString WebViewImpl::inspectorSettings() const {
- return inspector_settings_;
-}
-
-void WebViewImpl::setInspectorSettings(const WebString& settings) {
- inspector_settings_ = settings;
-}
-
-WebDevToolsAgent* WebViewImpl::devToolsAgent() {
- return devtools_agent_.get();
-}
-
-WebAccessibilityObject WebViewImpl::accessibilityObject() {
- if (!main_frame())
- return WebAccessibilityObject();
-
- WebCore::Document* document = main_frame()->frame()->document();
-
- return AccessibilityObjectToWebAccessibilityObject(
- document->axObjectCache()->getOrCreate(document->renderer()));
-}
-
-void WebViewImpl::applyAutofillSuggestions(
- const WebNode& node,
- const WebVector<WebString>& suggestions,
- int default_suggestion_index) {
- if (!page_.get() || suggestions.isEmpty()) {
- HideAutoCompletePopup();
- return;
- }
-
- ASSERT(default_suggestion_index < static_cast<int>(suggestions.size()));
-
- if (RefPtr<Frame> focused = page_->focusController()->focusedFrame()) {
- RefPtr<Document> document = focused->document();
- if (!document.get()) {
- HideAutoCompletePopup();
- return;
- }
-
- RefPtr<Node> focused_node = document->focusedNode();
- // If the node for which we queried the autofill suggestions is not the
- // focused node, then we have nothing to do.
- // TODO(jcampan): also check the carret is at the end and that the text has
- // not changed.
- if (!focused_node.get() ||
- focused_node != webkit_glue::WebNodeToNode(node)) {
- HideAutoCompletePopup();
- return;
- }
-
- if (!focused_node->hasTagName(WebCore::HTMLNames::inputTag)) {
- ASSERT_NOT_REACHED();
- return;
- }
-
- WebCore::HTMLInputElement* input_elem =
- static_cast<WebCore::HTMLInputElement*>(focused_node.get());
-
- // The first time the autocomplete is shown we'll create the client and the
- // popup.
- if (!autocomplete_popup_client_.get())
- autocomplete_popup_client_.set(new AutocompletePopupMenuClient(this));
- autocomplete_popup_client_->Init(input_elem,
- suggestions,
- default_suggestion_index);
- if (!autocomplete_popup_.get()) {
- autocomplete_popup_ =
- WebCore::PopupContainer::create(autocomplete_popup_client_.get(),
- kAutocompletePopupSettings);
- }
-
- if (autocomplete_popup_showing_) {
- autocomplete_popup_client_->SetSuggestions(suggestions);
- RefreshAutofillPopup();
- } else {
- autocomplete_popup_->show(focused_node->getRect(),
- focused_node->ownerDocument()->view(), 0);
- autocomplete_popup_showing_ = true;
- }
- }
-}
-
-void WebViewImpl::hideAutofillPopup() {
- HideAutoCompletePopup();
-}
-
-// WebView --------------------------------------------------------------------
-
-bool WebViewImpl::setDropEffect(bool accept) {
- if (drag_target_dispatch_) {
- drop_effect_ = accept ? DROP_EFFECT_COPY : DROP_EFFECT_NONE;
- return true;
- } else {
- return false;
- }
-}
-
-WebDevToolsAgentImpl* WebViewImpl::GetWebDevToolsAgentImpl() {
- return devtools_agent_.get();
-}
-
-void WebViewImpl::setIsTransparent(bool is_transparent) {
- // Set any existing frames to be transparent.
- WebCore::Frame* frame = page_->mainFrame();
- while (frame) {
- frame->view()->setTransparent(is_transparent);
- frame = frame->tree()->traverseNext();
- }
-
- // Future frames check this to know whether to be transparent.
- is_transparent_ = is_transparent;
-}
-
-bool WebViewImpl::isTransparent() const {
- return is_transparent_;
-}
-
-void WebViewImpl::setIsActive(bool active) {
- if (page() && page()->focusController())
- page()->focusController()->setActive(active);
-}
-
-bool WebViewImpl::isActive() const {
- return (page() && page()->focusController())
- ? page()->focusController()->isActive()
- : false;
-}
-
-void WebViewImpl::DidCommitLoad(bool* is_new_navigation) {
- if (is_new_navigation)
- *is_new_navigation = observed_new_navigation_;
-
-#ifndef NDEBUG
- ASSERT(!observed_new_navigation_ ||
- page_->mainFrame()->loader()->documentLoader() == new_navigation_loader_);
- new_navigation_loader_ = NULL;
-#endif
- observed_new_navigation_ = false;
-}
-
-// static
-bool WebViewImpl::NavigationPolicyFromMouseEvent(unsigned short button,
- bool ctrl, bool shift,
- bool alt, bool meta,
- WebNavigationPolicy* policy) {
-#if PLATFORM(WIN_OS) || PLATFORM(LINUX) || PLATFORM(FREEBSD)
- const bool new_tab_modifier = (button == 1) || ctrl;
-#elif PLATFORM(DARWIN)
- const bool new_tab_modifier = (button == 1) || meta;
-#endif
- if (!new_tab_modifier && !shift && !alt)
- return false;
-
- ASSERT(policy);
- if (new_tab_modifier) {
- if (shift) {
- *policy = WebKit::WebNavigationPolicyNewForegroundTab;
- } else {
- *policy = WebKit::WebNavigationPolicyNewBackgroundTab;
- }
- } else {
- if (shift) {
- *policy = WebKit::WebNavigationPolicyNewWindow;
- } else {
- *policy = WebKit::WebNavigationPolicyDownload;
- }
- }
- return true;
-}
-
-void WebViewImpl::StartDragging(const WebPoint& event_pos,
- const WebDragData& drag_data,
- WebDragOperationsMask mask) {
- if (!client_)
- return;
- ASSERT(!doing_drag_and_drop_);
- doing_drag_and_drop_ = true;
- client_->startDragging(event_pos, drag_data, mask);
-}
-
-void WebViewImpl::SetCurrentHistoryItem(WebCore::HistoryItem* item) {
- back_forward_list_client_impl_.SetCurrentHistoryItem(item);
-}
-
-WebCore::HistoryItem* WebViewImpl::GetPreviousHistoryItem() {
- return back_forward_list_client_impl_.GetPreviousHistoryItem();
-}
-
-void WebViewImpl::ObserveNewNavigation() {
- observed_new_navigation_ = true;
-#ifndef NDEBUG
- new_navigation_loader_ = page_->mainFrame()->loader()->documentLoader();
-#endif
-}
-
-void WebViewImpl::HideAutoCompletePopup() {
- if (autocomplete_popup_showing_) {
- autocomplete_popup_->hidePopup();
- AutoCompletePopupDidHide();
- }
-}
-
-void WebViewImpl::AutoCompletePopupDidHide() {
- autocomplete_popup_showing_ = false;
-}
-
-void WebViewImpl::SetIgnoreInputEvents(bool new_value) {
- ASSERT(ignore_input_events_ != new_value);
- ignore_input_events_ = new_value;
-}
-
-#if ENABLE(NOTIFICATIONS)
-WebKit::NotificationPresenterImpl* WebViewImpl::GetNotificationPresenter() {
- if (!notification_presenter_.isInitialized() && client_)
- notification_presenter_.initialize(client_->notificationPresenter());
- return &notification_presenter_;
-}
-#endif
-
-void WebViewImpl::RefreshAutofillPopup() {
- ASSERT(autocomplete_popup_showing_);
-
- // Hide the popup if it has become empty.
- if (autocomplete_popup_client_->listSize() == 0) {
- HideAutoCompletePopup();
- return;
- }
-
- IntRect old_bounds = autocomplete_popup_->boundsRect();
- autocomplete_popup_->refresh();
- IntRect new_bounds = autocomplete_popup_->boundsRect();
- // Let's resize the backing window if necessary.
- if (old_bounds != new_bounds) {
- WebPopupMenuImpl* popup_menu =
- static_cast<WebPopupMenuImpl*>(autocomplete_popup_->client());
- popup_menu->client()->setWindowRect(
- webkit_glue::IntRectToWebRect(new_bounds));
- }
-}
-
-Node* WebViewImpl::GetFocusedNode() {
- Frame* frame = page_->focusController()->focusedFrame();
- if (!frame)
- return NULL;
-
- Document* document = frame->document();
- if (!document)
- return NULL;
-
- return document->focusedNode();
-}
-
-HitTestResult WebViewImpl::HitTestResultForWindowPos(const IntPoint& pos) {
- IntPoint doc_point(
- page_->mainFrame()->view()->windowToContents(pos));
- return page_->mainFrame()->eventHandler()->
- hitTestResultAtPoint(doc_point, false);
-}
-
-void WebViewImpl::setTabsToLinks(bool enable) {
- tabs_to_links_ = enable;
-}
-
-bool WebViewImpl::tabsToLinks() const {
- return tabs_to_links_;
-}
diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h
deleted file mode 100644
index 977b597..0000000
--- a/webkit/glue/webview_impl.h
+++ /dev/null
@@ -1,401 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef WEBKIT_GLUE_WEBVIEW_IMPL_H_
-#define WEBKIT_GLUE_WEBVIEW_IMPL_H_
-
-#include <wtf/OwnPtr.h>
-#include <wtf/RefCounted.h>
-
-#include "webkit/api/public/WebPoint.h"
-#include "webkit/api/public/WebSize.h"
-#include "webkit/api/public/WebString.h"
-#include "webkit/api/public/WebView.h"
-#include "webkit/api/src/BackForwardListClientImpl.h"
-#include "webkit/api/src/ChromeClientImpl.h"
-#include "webkit/api/src/ContextMenuClientImpl.h"
-#include "webkit/api/src/DragClientImpl.h"
-#include "webkit/api/src/EditorClientImpl.h"
-#include "webkit/api/src/InspectorClientImpl.h"
-#include "webkit/api/src/NotificationPresenterImpl.h"
-#include "webkit/glue/webframe_impl.h"
-
-namespace WebCore {
-class ChromiumDataObject;
-class Frame;
-class HistoryItem;
-class HitTestResult;
-class KeyboardEvent;
-class Page;
-class PlatformKeyboardEvent;
-class PopupContainer;
-class Range;
-class RenderTheme;
-class Widget;
-}
-
-namespace WebKit {
-class ContextMenuClientImpl;
-class WebAccessibilityObject;
-class WebKeyboardEvent;
-class WebMouseEvent;
-class WebMouseWheelEvent;
-class WebSettingsImpl;
-}
-
-namespace webkit_glue {
-class ImageResourceFetcher;
-}
-
-class AutocompletePopupMenuClient;
-class WebHistoryItemImpl;
-class WebDevToolsAgentImpl;
-
-class WebViewImpl : public WebKit::WebView, public RefCounted<WebViewImpl> {
- public:
- // WebWidget methods:
- virtual void close();
- virtual WebKit::WebSize size() { return size_; }
- virtual void resize(const WebKit::WebSize& new_size);
- virtual void layout();
- virtual void paint(WebKit::WebCanvas* canvas,
- const WebKit::WebRect& rect);
- virtual bool handleInputEvent(const WebKit::WebInputEvent& input_event);
- virtual void mouseCaptureLost();
- virtual void setFocus(bool enable);
- virtual bool handleCompositionEvent(WebKit::WebCompositionCommand command,
- int cursor_position,
- int target_start,
- int target_end,
- const WebKit::WebString& text);
- virtual bool queryCompositionStatus(bool* enabled,
- WebKit::WebRect* caret_rect);
- virtual void setTextDirection(WebKit::WebTextDirection direction);
-
- // WebView methods:
- virtual void initializeMainFrame(WebKit::WebFrameClient*);
- virtual WebKit::WebSettings* settings();
- virtual WebKit::WebString pageEncoding() const;
- virtual void setPageEncoding(const WebKit::WebString& encoding);
- virtual bool isTransparent() const;
- virtual void setIsTransparent(bool value);
- virtual bool tabsToLinks() const;
- virtual void setTabsToLinks(bool value);
- virtual bool tabKeyCyclesThroughElements() const;
- virtual void setTabKeyCyclesThroughElements(bool value);
- virtual bool isActive() const;
- virtual void setIsActive(bool value);
- virtual bool dispatchBeforeUnloadEvent();
- virtual void dispatchUnloadEvent();
- virtual WebKit::WebFrame* mainFrame();
- virtual WebKit::WebFrame* findFrameByName(
- const WebKit::WebString& name, WebKit::WebFrame* relative_to_frame);
- virtual WebKit::WebFrame* focusedFrame();
- virtual void setFocusedFrame(WebKit::WebFrame* frame);
- virtual void setInitialFocus(bool reverse);
- virtual void clearFocusedNode();
- virtual void zoomIn(bool text_only);
- virtual void zoomOut(bool text_only);
- virtual void zoomDefault();
- virtual void performMediaPlayerAction(
- const WebKit::WebMediaPlayerAction& action,
- const WebKit::WebPoint& location);
- virtual void copyImageAt(const WebKit::WebPoint& point);
- virtual void dragSourceEndedAt(
- const WebKit::WebPoint& client_point,
- const WebKit::WebPoint& screen_point,
- WebKit::WebDragOperation operation);
- virtual void dragSourceMovedTo(
- const WebKit::WebPoint& client_point,
- const WebKit::WebPoint& screen_point);
- virtual void dragSourceSystemDragEnded();
- virtual WebKit::WebDragOperation dragTargetDragEnter(
- const WebKit::WebDragData& drag_data, int identity,
- const WebKit::WebPoint& client_point,
- const WebKit::WebPoint& screen_point,
- WebKit::WebDragOperationsMask operations_allowed);
- virtual WebKit::WebDragOperation dragTargetDragOver(
- const WebKit::WebPoint& client_point,
- const WebKit::WebPoint& screen_point,
- WebKit::WebDragOperationsMask operations_allowed);
- virtual void dragTargetDragLeave();
- virtual void dragTargetDrop(
- const WebKit::WebPoint& client_point,
- const WebKit::WebPoint& screen_point);
- virtual int dragIdentity();
- virtual bool setDropEffect(bool accept);
- virtual void inspectElementAt(const WebKit::WebPoint& point);
- virtual WebKit::WebString inspectorSettings() const;
- virtual void setInspectorSettings(const WebKit::WebString& settings);
- virtual WebKit::WebDevToolsAgent* devToolsAgent();
- virtual WebKit::WebAccessibilityObject accessibilityObject();
- virtual void applyAutofillSuggestions(
- const WebKit::WebNode&,
- const WebKit::WebVector<WebKit::WebString>& suggestions,
- int defaultSuggestionIndex);
- virtual void hideAutofillPopup();
-
- // WebViewImpl
-
- void SetIgnoreInputEvents(bool new_value);
- WebDevToolsAgentImpl* GetWebDevToolsAgentImpl();
-
- const WebKit::WebPoint& last_mouse_down_point() const {
- return last_mouse_down_point_;
- }
-
- WebCore::Frame* GetFocusedWebCoreFrame();
-
- // Returns the currently focused Node or NULL if no node has focus.
- WebCore::Node* GetFocusedNode();
-
- static WebViewImpl* FromPage(WebCore::Page* page);
-
- WebKit::WebViewClient* client() {
- return client_;
- }
-
- // Returns the page object associated with this view. This may be NULL when
- // the page is shutting down, but will be valid at all other times.
- WebCore::Page* page() const {
- return page_.get();
- }
-
- WebCore::RenderTheme* theme() const;
-
- // Returns the main frame associated with this view. This may be NULL when
- // the page is shutting down, but will be valid at all other times.
- WebFrameImpl* main_frame() {
- return page_.get() ? WebFrameImpl::FromFrame(page_->mainFrame()) : NULL;
- }
-
- // History related methods:
- void SetCurrentHistoryItem(WebCore::HistoryItem* item);
- WebCore::HistoryItem* GetPreviousHistoryItem();
- void ObserveNewNavigation();
-
- // Event related methods:
- void MouseMove(const WebKit::WebMouseEvent& mouse_event);
- void MouseLeave(const WebKit::WebMouseEvent& mouse_event);
- void MouseDown(const WebKit::WebMouseEvent& mouse_event);
- void MouseUp(const WebKit::WebMouseEvent& mouse_event);
- void MouseContextMenu(const WebKit::WebMouseEvent& mouse_event);
- void MouseDoubleClick(const WebKit::WebMouseEvent& mouse_event);
- void MouseWheel(const WebKit::WebMouseWheelEvent& wheel_event);
- bool KeyEvent(const WebKit::WebKeyboardEvent& key_event);
- bool CharEvent(const WebKit::WebKeyboardEvent& key_event);
-
- // Handles context menu events orignated via the the keyboard. These
- // include the VK_APPS virtual key and the Shift+F10 combine.
- // Code is based on the Webkit function
- // bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam) in
- // webkit\webkit\win\WebView.cpp. The only significant change in this
- // function is the code to convert from a Keyboard event to the Right
- // Mouse button down event.
- bool SendContextMenuEvent(const WebKit::WebKeyboardEvent& event);
-
- // Notifies the WebView that a load has been committed.
- // is_new_navigation will be true if a new session history item should be
- // created for that load.
- void DidCommitLoad(bool* is_new_navigation);
-
- bool context_menu_allowed() const {
- return context_menu_allowed_;
- }
-
- // Set the disposition for how this webview is to be initially shown.
- void set_initial_navigation_policy(WebKit::WebNavigationPolicy policy) {
- initial_navigation_policy_ = policy;
- }
- WebKit::WebNavigationPolicy initial_navigation_policy() const {
- return initial_navigation_policy_;
- }
-
- // Determines whether a page should e.g. be opened in a background tab.
- // Returns false if it has no opinion, in which case it doesn't set *policy.
- static bool NavigationPolicyFromMouseEvent(
- unsigned short button,
- bool ctrl,
- bool shift,
- bool alt,
- bool meta,
- WebKit::WebNavigationPolicy* policy);
-
- // Start a system drag and drop operation.
- void StartDragging(
- const WebKit::WebPoint& event_pos,
- const WebKit::WebDragData& drag_data,
- WebKit::WebDragOperationsMask drag_source_operation_mask);
-
- // Hides the autocomplete popup if it is showing.
- void HideAutoCompletePopup();
- void AutoCompletePopupDidHide();
-
-#if ENABLE(NOTIFICATIONS)
- // Returns the provider of desktop notifications.
- WebKit::NotificationPresenterImpl* GetNotificationPresenter();
-#endif
-
- // Tries to scroll a frame or any parent of a frame. Returns true if the view
- // was scrolled.
- bool PropagateScroll(WebCore::ScrollDirection scroll_direction,
- WebCore::ScrollGranularity scroll_granularity);
-
- protected:
- friend class WebKit::WebView; // So WebView::Create can call our constructor
- friend class WTF::RefCounted<WebViewImpl>;
-
- WebViewImpl(WebKit::WebViewClient* client);
- ~WebViewImpl();
-
- void ModifySelection(uint32 message,
- WebCore::Frame* frame,
- const WebCore::PlatformKeyboardEvent& e);
-
- WebKit::WebViewClient* client_;
-
- WebKit::BackForwardListClientImpl back_forward_list_client_impl_;
- WebKit::ChromeClientImpl chrome_client_impl_;
- WebKit::ContextMenuClientImpl context_menu_client_impl_;
- WebKit::DragClientImpl drag_client_impl_;
- WebKit::EditorClientImpl editor_client_impl_;
- WebKit::InspectorClientImpl inspector_client_impl_;
-
- WebKit::WebSize size_;
-
- WebKit::WebPoint last_mouse_position_;
- OwnPtr<WebCore::Page> page_;
-
- // This flag is set when a new navigation is detected. It is used to satisfy
- // the corresponding argument to WebFrameClient::didCommitProvisionalLoad.
- bool observed_new_navigation_;
-#ifndef NDEBUG
- // Used to assert that the new navigation we observed is the same navigation
- // when we make use of observed_new_navigation_.
- const WebCore::DocumentLoader* new_navigation_loader_;
-#endif
-
- // An object that can be used to manipulate page_->settings() without linking
- // against WebCore. This is lazily allocated the first time GetWebSettings()
- // is called.
- OwnPtr<WebKit::WebSettingsImpl> web_settings_;
-
- // A copy of the web drop data object we received from the browser.
- RefPtr<WebCore::ChromiumDataObject> current_drag_data_;
-
- private:
- // Returns true if the event was actually processed.
- bool KeyEventDefault(const WebKit::WebKeyboardEvent& event);
-
- // Returns true if the autocomple has consumed the event.
- bool AutocompleteHandleKeyEvent(const WebKit::WebKeyboardEvent& event);
-
- // Repaints the autofill popup. Should be called when the suggestions have
- // changed. Note that this should only be called when the autofill popup is
- // showing.
- void RefreshAutofillPopup();
-
- // Returns true if the view was scrolled.
- bool ScrollViewWithKeyboard(int key_code, int modifiers);
-
- // Converts |pos| from window coordinates to contents coordinates and gets
- // the HitTestResult for it.
- WebCore::HitTestResult HitTestResultForWindowPos(
- const WebCore::IntPoint& pos);
-
- // The point relative to the client area where the mouse was last pressed
- // down. This is used by the drag client to determine what was under the
- // mouse when the drag was initiated. We need to track this here in
- // WebViewImpl since DragClient::startDrag does not pass the position the
- // mouse was at when the drag was initiated, only the current point, which
- // can be misleading as it is usually not over the element the user actually
- // dragged by the time a drag is initiated.
- WebKit::WebPoint last_mouse_down_point_;
-
- // Keeps track of the current text zoom level. 0 means no zoom, positive
- // values mean larger text, negative numbers mean smaller.
- int zoom_level_;
-
- bool context_menu_allowed_;
-
- bool doing_drag_and_drop_;
-
- bool ignore_input_events_;
-
- // Webkit expects keyPress events to be suppressed if the associated keyDown
- // event was handled. Safari implements this behavior by peeking out the
- // associated WM_CHAR event if the keydown was handled. We emulate
- // this behavior by setting this flag if the keyDown was handled.
- bool suppress_next_keypress_event_;
-
- // The policy for how this webview is to be initially shown.
- WebKit::WebNavigationPolicy initial_navigation_policy_;
-
- // Represents whether or not this object should process incoming IME events.
- bool ime_accept_events_;
-
- // True while dispatching system drag and drop events to drag/drop targets
- // within this WebView.
- bool drag_target_dispatch_;
-
- // Valid when drag_target_dispatch_ is true; the identity of the drag data
- // copied from the WebDropData object sent from the browser process.
- int32 drag_identity_;
-
- // Valid when drag_target_dispatch_ is true. Used to override the default
- // browser drop effect with the effects "none" or "copy".
- enum DragTargetDropEffect {
- DROP_EFFECT_DEFAULT = -1,
- DROP_EFFECT_NONE,
- DROP_EFFECT_COPY
- } drop_effect_;
-
- // The available drag operations (copy, move link...) allowed by the source.
- WebKit::WebDragOperation operations_allowed_;
-
- // The current drag operation as negotiated by the source and destination.
- // When not equal to DragOperationNone, the drag data can be dropped onto the
- // current drop target in this WebView (the drop target can accept the drop).
- WebKit::WebDragOperation drag_operation_;
-
- // The autocomplete popup. Kept around and reused every-time new suggestions
- // should be shown.
- RefPtr<WebCore::PopupContainer> autocomplete_popup_;
-
- // Whether the autocomplete popup is currently showing.
- bool autocomplete_popup_showing_;
-
- // The autocomplete client.
- OwnPtr<AutocompletePopupMenuClient> autocomplete_popup_client_;
-
- OwnPtr<WebDevToolsAgentImpl> devtools_agent_;
-
- // Whether the webview is rendering transparently.
- bool is_transparent_;
-
- // Whether the user can press tab to focus links.
- bool tabs_to_links_;
-
- // Inspector settings.
- WebKit::WebString inspector_settings_;
-
-#if ENABLE(NOTIFICATIONS)
- // The provider of desktop notifications;
- WebKit::NotificationPresenterImpl notification_presenter_;
-#endif
-
- // HACK: current_input_event is for ChromeClientImpl::show(), until we can fix
- // WebKit to pass enough information up into ChromeClient::show() so we can
- // decide if the window.open event was caused by a middle-mouse click
- public:
- static const WebKit::WebInputEvent* current_input_event() {
- return g_current_input_event;
- }
- private:
- static const WebKit::WebInputEvent* g_current_input_event;
-
- DISALLOW_COPY_AND_ASSIGN(WebViewImpl);
-};
-
-#endif // WEBKIT_GLUE_WEBVIEW_IMPL_H_
diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp
index 578fbc9..39d8fa3 100644
--- a/webkit/webkit.gyp
+++ b/webkit/webkit.gyp
@@ -172,6 +172,8 @@
'api/public/win/WebScreenInfoFactory.h',
'api/src/ApplicationCacheHost.cpp',
'api/src/AssertMatchingEnums.cpp',
+ 'api/src/AutocompletePopupMenuClient.cpp',
+ 'api/src/AutocompletePopupMenuClient.h',
'api/src/BackForwardListClientImpl.cpp',
'api/src/BackForwardListClientImpl.h',
'api/src/ChromeClientImpl.cpp',
@@ -187,6 +189,9 @@
'api/src/DragClientImpl.h',
'api/src/EditorClientImpl.cpp',
'api/src/EditorClientImpl.h',
+ 'api/src/FrameLoaderClientImpl.cpp',
+ 'api/src/FrameLoaderClientImpl.h',
+ 'api/src/EmptyWebFrameClientImpl.h',
'api/src/gtk/WebFontInfo.cpp',
'api/src/gtk/WebFontInfo.h',
'api/src/gtk/WebInputEventFactory.cpp',
@@ -231,6 +236,8 @@
'api/src/WebFileChooserCompletionImpl.h',
'api/src/WebFontCache.cpp',
'api/src/WebForm.cpp',
+ 'api/src/WebFrameImpl.cpp',
+ 'api/src/WebFrameImpl.h',
'api/src/WebHistoryItem.cpp',
'api/src/WebHTTPBody.cpp',
'api/src/WebImageCG.cpp',
@@ -271,6 +278,8 @@
'api/src/WebURLResponse.cpp',
'api/src/WebURLResponsePrivate.h',
'api/src/WebURLError.cpp',
+ 'api/src/WebViewImpl.cpp',
+ 'api/src/WebViewImpl.h',
'api/src/WebWorkerClientImpl.cpp',
'api/src/WebWorkerClientImpl.h',
'api/src/WebWorkerImpl.cpp',
@@ -645,10 +654,6 @@
'glue/webdropdata.cc',
'glue/webdropdata_win.cc',
'glue/webdropdata.h',
- 'glue/webframe_impl.cc',
- 'glue/webframe_impl.h',
- 'glue/webframeloaderclient_impl.cc',
- 'glue/webframeloaderclient_impl.h',
'glue/webkit_glue.cc',
'glue/webkit_glue.h',
'glue/webkitclient_impl.cc',
@@ -672,8 +677,6 @@
'glue/webthemeengine_impl_win.cc',
'glue/weburlloader_impl.cc',
'glue/weburlloader_impl.h',
- 'glue/webview_impl.cc',
- 'glue/webview_impl.h',
'glue/window_open_disposition.h',
'glue/window_open_disposition.cc',