diff options
Diffstat (limited to 'webkit/glue')
25 files changed, 95 insertions, 6291 deletions
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, ¶ms.attributeNames); - CopyStringVector(param_values, ¶ms.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 ¬ification_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_ |