--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKit/wx/WebView.cpp Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,1056 @@
+/*
+ * Copyright (C) 2007 Kevin Ollivier 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.
+ */
+
+#include "config.h"
+#include "Cache.h"
+#include "ContextMenu.h"
+#include "ContextMenuItem.h"
+#include "ContextMenuController.h"
+#include "Document.h"
+#include "Element.h"
+#include "Editor.h"
+#include "EmptyClients.h"
+#include "EventHandler.h"
+#include "FileChooser.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "HTMLFormElement.h"
+#include "Logging.h"
+#include "markup.h"
+#include "Page.h"
+#include "PlatformKeyboardEvent.h"
+#include "PlatformMouseEvent.h"
+#include "PlatformString.h"
+#include "PlatformWheelEvent.h"
+#include "PluginHalterClient.h"
+#include "RenderObject.h"
+#include "RenderView.h"
+#include "ResourceHandleManager.h"
+#include "Scrollbar.h"
+#include "SelectionController.h"
+#include "Settings.h"
+#include "SubstituteData.h"
+#include "Threading.h"
+#if __WXMSW__
+#include "WebCoreInstanceHandle.h"
+#endif
+
+#include "ChromeClientWx.h"
+#include "ContextMenuClientWx.h"
+#include "DragClientWx.h"
+#include "EditorClientWx.h"
+#include "FrameLoaderClientWx.h"
+#include "InspectorClientWx.h"
+
+#include "ScriptController.h"
+#include "JSDOMBinding.h"
+#include <runtime/JSValue.h>
+#include <runtime/UString.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(DATABASE)
+#include "AbstractDatabase.h"
+#include "DatabaseTracker.h"
+#endif
+
+#include "wx/wxprec.h"
+#ifndef WX_PRECOMP
+ #include "wx/wx.h"
+#endif
+
+#include "WebFrame.h"
+#include "WebView.h"
+#include "WebViewPrivate.h"
+
+#include <wx/defs.h>
+#include <wx/dcbuffer.h>
+#include <wx/dcgraph.h>
+
+#if defined(_MSC_VER)
+int rint(double val)
+{
+ return (int)(val < 0 ? val - 0.5 : val + 0.5);
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// wxWebView Events
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD)
+
+wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win)
+{
+ SetEventType( wxEVT_WEBVIEW_LOAD);
+ SetEventObject( win );
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD)
+
+wxWebViewBeforeLoadEvent::wxWebViewBeforeLoadEvent(wxWindow* win)
+{
+ m_cancelled = false;
+ SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW)
+
+wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win)
+{
+ SetEventType(wxEVT_WEBVIEW_NEW_WINDOW);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK)
+
+wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win)
+{
+ SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE)
+
+wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win)
+{
+ SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT)
+
+wxWebViewAlertEvent::wxWebViewAlertEvent(wxWindow* win)
+{
+ SetEventType(wxEVT_WEBVIEW_JS_ALERT);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM)
+
+wxWebViewConfirmEvent::wxWebViewConfirmEvent(wxWindow* win)
+{
+ SetEventType(wxEVT_WEBVIEW_JS_CONFIRM);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT)
+
+wxWebViewPromptEvent::wxWebViewPromptEvent(wxWindow* win)
+{
+ SetEventType(wxEVT_WEBVIEW_JS_PROMPT);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE)
+
+wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win)
+{
+ SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent, wxCommandEvent)
+
+DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED)
+
+wxWebViewWindowObjectClearedEvent::wxWebViewWindowObjectClearedEvent(wxWindow* win)
+{
+ SetEventType(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED);
+ SetEventObject(win);
+ if (win)
+ SetId(win->GetId());
+}
+
+
+//---------------------------------------------------------
+// DOM Element info data type
+//---------------------------------------------------------
+
+wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() :
+ m_domElement(NULL),
+ m_isSelected(false),
+ m_text(wxEmptyString),
+ m_imageSrc(wxEmptyString),
+ m_link(wxEmptyString)
+{
+}
+
+static wxWebViewCachePolicy gs_cachePolicy;
+
+/* static */
+void wxWebView::SetCachePolicy(const wxWebViewCachePolicy& cachePolicy)
+{
+ WebCore::Cache* globalCache = WebCore::cache();
+ globalCache->setCapacities(cachePolicy.GetMinDeadCapacity(),
+ cachePolicy.GetMaxDeadCapacity(),
+ cachePolicy.GetCapacity());
+
+ // store a copy since there is no getter for Cache values
+ gs_cachePolicy = cachePolicy;
+}
+
+/* static */
+wxWebViewCachePolicy wxWebView::GetCachePolicy()
+{
+ return gs_cachePolicy;
+}
+
+#if OS(DARWIN)
+// prototype - function is in WebSystemInterface.mm
+void InitWebCoreSystemInterface(void);
+#endif
+
+BEGIN_EVENT_TABLE(wxWebView, wxWindow)
+ EVT_PAINT(wxWebView::OnPaint)
+ EVT_SIZE(wxWebView::OnSize)
+ EVT_MOUSE_EVENTS(wxWebView::OnMouseEvents)
+ EVT_CONTEXT_MENU(wxWebView::OnContextMenuEvents)
+ EVT_KEY_DOWN(wxWebView::OnKeyEvents)
+ EVT_KEY_UP(wxWebView::OnKeyEvents)
+ EVT_CHAR(wxWebView::OnKeyEvents)
+ EVT_SET_FOCUS(wxWebView::OnSetFocus)
+ EVT_KILL_FOCUS(wxWebView::OnKillFocus)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow)
+
+const wxChar* wxWebViewNameStr = wxT("webView");
+
+wxWebView::wxWebView() :
+ m_textMagnifier(1.0),
+ m_isEditable(false),
+ m_isInitialized(false),
+ m_beingDestroyed(false),
+ m_mouseWheelZooms(false),
+ m_title(wxEmptyString)
+{
+}
+
+wxWebView::wxWebView(wxWindow* parent, int id, const wxPoint& position,
+ const wxSize& size, long style, const wxString& name) :
+ m_textMagnifier(1.0),
+ m_isEditable(false),
+ m_isInitialized(false),
+ m_beingDestroyed(false),
+ m_mouseWheelZooms(false),
+ m_title(wxEmptyString)
+{
+ Create(parent, id, position, size, style, name);
+}
+
+bool wxWebView::Create(wxWindow* parent, int id, const wxPoint& position,
+ const wxSize& size, long style, const wxString& name)
+{
+#if OS(DARWIN)
+ InitWebCoreSystemInterface();
+#endif
+
+ if ( (style & wxBORDER_MASK) == 0)
+ style |= wxBORDER_NONE;
+
+ if (!wxWindow::Create(parent, id, position, size, style, name))
+ return false;
+
+ WTF::initializeThreading();
+ WTF::initializeMainThread();
+
+// This is necessary because we are using SharedTimerWin.cpp on Windows,
+// due to a problem with exceptions getting eaten when using the callback
+// approach to timers (which wx itself uses).
+#if __WXMSW__
+ WebCore::setInstanceHandle(wxGetInstance());
+#endif
+
+ // this helps reduce flicker on platforms like MSW
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+
+ m_impl = new WebViewPrivate();
+
+ WebCore::InitializeLoggingChannelsIfNecessary();
+ WebCore::HTMLFrameOwnerElement* parentFrame = 0;
+
+ WebCore::EditorClientWx* editorClient = new WebCore::EditorClientWx();
+ m_impl->page = new WebCore::Page(new WebCore::ChromeClientWx(this),
+ new WebCore::ContextMenuClientWx(),
+ editorClient,
+ new WebCore::DragClientWx(),
+ new WebCore::InspectorClientWx(), 0, 0, 0, 0);
+ editorClient->setPage(m_impl->page);
+
+ m_mainFrame = new wxWebFrame(this);
+
+ // Default settings - we should have wxWebViewSettings class for this
+ // eventually
+ WebCore::Settings* settings = m_impl->page->settings();
+ settings->setLoadsImagesAutomatically(true);
+ settings->setDefaultFixedFontSize(13);
+ settings->setDefaultFontSize(16);
+ settings->setSerifFontFamily("Times New Roman");
+ settings->setFixedFontFamily("Courier New");
+ settings->setSansSerifFontFamily("Arial");
+ settings->setStandardFontFamily("Times New Roman");
+ settings->setJavaScriptEnabled(true);
+
+#if ENABLE(DATABASE)
+ SetDatabasesEnabled(true);
+#endif
+
+ // we need to do this so that objects like the focusController are properly
+ // initialized so that the activate handler is run properly.
+ LoadURL(wxT("about:blank"));
+
+ wxWindow* tlw = wxGetTopLevelParent(this);
+ tlw->Connect(-1, wxEVT_ACTIVATE, wxActivateEventHandler(wxWebView::OnTLWActivated));
+
+ m_isInitialized = true;
+
+ return true;
+}
+
+wxWebView::~wxWebView()
+{
+ m_beingDestroyed = true;
+
+ while (HasCapture())
+ ReleaseMouse();
+
+ if (m_mainFrame && m_mainFrame->GetFrame())
+ m_mainFrame->GetFrame()->loader()->detachFromParent();
+
+ delete m_impl->page;
+ m_impl->page = 0;
+}
+
+void wxWebView::OnTLWActivated(wxActivateEvent& event)
+{
+ if (m_impl && m_impl->page && m_impl->page->focusController())
+ m_impl->page->focusController()->setActive(event.GetActive());
+
+ event.Skip();
+
+}
+
+void wxWebView::Stop()
+{
+ if (m_mainFrame)
+ m_mainFrame->Stop();
+}
+
+void wxWebView::Reload()
+{
+ if (m_mainFrame)
+ m_mainFrame->Reload();
+}
+
+wxString wxWebView::GetPageSource()
+{
+ if (m_mainFrame)
+ return m_mainFrame->GetPageSource();
+
+ return wxEmptyString;
+}
+
+void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl)
+{
+ if (m_mainFrame)
+ m_mainFrame->SetPageSource(source, baseUrl);
+}
+
+wxString wxWebView::GetInnerText()
+{
+ if (m_mainFrame)
+ return m_mainFrame->GetInnerText();
+
+ return wxEmptyString;
+}
+
+wxString wxWebView::GetAsMarkup()
+{
+ if (m_mainFrame)
+ return m_mainFrame->GetAsMarkup();
+
+ return wxEmptyString;
+}
+
+wxString wxWebView::GetExternalRepresentation()
+{
+ if (m_mainFrame)
+ return m_mainFrame->GetExternalRepresentation();
+
+ return wxEmptyString;
+}
+
+void wxWebView::SetTransparent(bool transparent)
+{
+ WebCore::Frame* frame = 0;
+ if (m_mainFrame)
+ frame = m_mainFrame->GetFrame();
+
+ if (!frame || !frame->view())
+ return;
+
+ frame->view()->setTransparent(transparent);
+}
+
+bool wxWebView::IsTransparent() const
+{
+ WebCore::Frame* frame = 0;
+ if (m_mainFrame)
+ frame = m_mainFrame->GetFrame();
+
+ if (!frame || !frame->view())
+ return false;
+
+ return frame->view()->isTransparent();
+}
+
+wxString wxWebView::RunScript(const wxString& javascript)
+{
+ if (m_mainFrame)
+ return m_mainFrame->RunScript(javascript);
+
+ return wxEmptyString;
+}
+
+void wxWebView::LoadURL(const wxString& url)
+{
+ if (m_mainFrame)
+ m_mainFrame->LoadURL(url);
+}
+
+bool wxWebView::GoBack()
+{
+ if (m_mainFrame)
+ return m_mainFrame->GoBack();
+
+ return false;
+}
+
+bool wxWebView::GoForward()
+{
+ if (m_mainFrame)
+ return m_mainFrame->GoForward();
+
+ return false;
+}
+
+bool wxWebView::CanGoBack()
+{
+ if (m_mainFrame)
+ return m_mainFrame->CanGoBack();
+
+ return false;
+}
+
+bool wxWebView::CanGoForward()
+{
+ if (m_mainFrame)
+ return m_mainFrame->CanGoForward();
+
+ return false;
+}
+
+bool wxWebView::CanIncreaseTextSize() const
+{
+ if (m_mainFrame)
+ return m_mainFrame->CanIncreaseTextSize();
+
+ return false;
+}
+
+void wxWebView::IncreaseTextSize()
+{
+ if (m_mainFrame)
+ m_mainFrame->IncreaseTextSize();
+}
+
+bool wxWebView::CanDecreaseTextSize() const
+{
+ if (m_mainFrame)
+ m_mainFrame->CanDecreaseTextSize();
+
+ return false;
+}
+
+void wxWebView::DecreaseTextSize()
+{
+ if (m_mainFrame)
+ m_mainFrame->DecreaseTextSize();
+}
+
+void wxWebView::ResetTextSize()
+{
+ if (m_mainFrame)
+ m_mainFrame->ResetTextSize();
+}
+
+void wxWebView::MakeEditable(bool enable)
+{
+ m_isEditable = enable;
+}
+
+
+/*
+ * Event forwarding functions to send events down to WebCore.
+ */
+
+void wxWebView::OnPaint(wxPaintEvent& event)
+{
+ if (m_beingDestroyed || !m_mainFrame)
+ return;
+
+ WebCore::Frame* frame = m_mainFrame->GetFrame();
+ if (!frame || !frame->view())
+ return;
+
+ wxAutoBufferedPaintDC dc(this);
+
+ if (IsShown() && frame->document()) {
+#if USE(WXGC)
+ wxGCDC gcdc(dc);
+#endif
+
+ if (dc.IsOk()) {
+ wxRect paintRect = GetUpdateRegion().GetBox();
+
+#if USE(WXGC)
+ WebCore::GraphicsContext gc(&gcdc);
+#else
+ WebCore::GraphicsContext gc(&dc);
+#endif
+ if (frame->contentRenderer()) {
+ frame->view()->layoutIfNeededRecursive();
+ frame->view()->paint(&gc, paintRect);
+ }
+ }
+ }
+}
+
+bool wxWebView::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
+{
+ if (m_mainFrame)
+ return m_mainFrame->FindString(string, forward, caseSensitive, wrapSelection, startInSelection);
+
+ return false;
+}
+
+void wxWebView::OnSize(wxSizeEvent& event)
+{
+ if (m_isInitialized && m_mainFrame) {
+ WebCore::Frame* frame = m_mainFrame->GetFrame();
+ frame->view()->setFrameRect(wxRect(wxPoint(0,0), event.GetSize()));
+ frame->view()->forceLayout();
+ frame->view()->adjustViewSize();
+ }
+
+ event.Skip();
+}
+
+static int getDoubleClickTime()
+{
+#if __WXMSW__
+ return ::GetDoubleClickTime();
+#else
+ return 500;
+#endif
+}
+
+void wxWebView::OnMouseEvents(wxMouseEvent& event)
+{
+ event.Skip();
+
+ if (!m_impl->page)
+ return;
+
+ WebCore::Frame* frame = m_mainFrame->GetFrame();
+ if (!frame || !frame->view())
+ return;
+
+ wxPoint globalPoint = ClientToScreen(event.GetPosition());
+
+ wxEventType type = event.GetEventType();
+
+ if (type == wxEVT_MOUSEWHEEL) {
+ if (m_mouseWheelZooms && event.ControlDown() && !event.AltDown() && !event.ShiftDown()) {
+ if (event.GetWheelRotation() < 0)
+ DecreaseTextSize();
+ else if (event.GetWheelRotation() > 0)
+ IncreaseTextSize();
+ } else {
+ WebCore::PlatformWheelEvent wkEvent(event, globalPoint);
+ frame->eventHandler()->handleWheelEvent(wkEvent);
+ }
+
+ return;
+ }
+
+ // If an event, such as a right-click event, leads to a focus change (e.g. it
+ // raises a dialog), WebKit never gets the mouse up event and never relinquishes
+ // mouse capture. This leads to WebKit handling mouse events, such as modifying
+ // the selection, while other controls or top level windows have the focus.
+ // I'm not sure if this is the right place to handle this, but I can't seem to
+ // find a precedent on how to handle this in other ports.
+ if (wxWindow::FindFocus() != this) {
+ while (HasCapture())
+ ReleaseMouse();
+
+ frame->eventHandler()->setMousePressed(false);
+
+ return;
+ }
+
+ int clickCount = event.ButtonDClick() ? 2 : 1;
+
+ if (clickCount == 1 && m_impl->tripleClickTimer.IsRunning()) {
+ wxPoint diff(event.GetPosition() - m_impl->tripleClickPos);
+ if (abs(diff.x) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_X) &&
+ abs(diff.y) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_Y)) {
+ clickCount = 3;
+ }
+ } else if (clickCount == 2) {
+ m_impl->tripleClickTimer.Start(getDoubleClickTime(), false);
+ m_impl->tripleClickPos = event.GetPosition();
+ }
+
+ WebCore::PlatformMouseEvent wkEvent(event, globalPoint, clickCount);
+
+ if (type == wxEVT_LEFT_DOWN || type == wxEVT_MIDDLE_DOWN || type == wxEVT_RIGHT_DOWN ||
+ type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK) {
+ frame->eventHandler()->handleMousePressEvent(wkEvent);
+ if (!HasCapture())
+ CaptureMouse();
+ } else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP) {
+ frame->eventHandler()->handleMouseReleaseEvent(wkEvent);
+ while (HasCapture())
+ ReleaseMouse();
+ } else if (type == wxEVT_MOTION || type == wxEVT_ENTER_WINDOW || type == wxEVT_LEAVE_WINDOW)
+ frame->eventHandler()->mouseMoved(wkEvent);
+}
+
+void wxWebView::OnContextMenuEvents(wxContextMenuEvent& event)
+{
+ Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxWebView::OnMenuSelectEvents), NULL, this);
+ m_impl->page->contextMenuController()->clearContextMenu();
+ wxPoint localEventPoint = ScreenToClient(event.GetPosition());
+
+ if (!m_impl->page)
+ return;
+
+ WebCore::Frame* focusedFrame = m_impl->page->focusController()->focusedOrMainFrame();
+ if (!focusedFrame->view())
+ return;
+
+ //Create WebCore mouse event from the wxContextMenuEvent
+ wxMouseEvent mouseEvent(wxEVT_RIGHT_DOWN);
+ mouseEvent.m_x = localEventPoint.x;
+ mouseEvent.m_y = localEventPoint.y;
+ WebCore::PlatformMouseEvent wkEvent(mouseEvent, event.GetPosition(), 1);
+
+ bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(wkEvent);
+ if (!handledEvent)
+ return;
+
+ WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
+ if (!coreMenu)
+ return;
+
+ WebCore::PlatformMenuDescription menuWx = coreMenu->platformDescription();
+ if (!menuWx)
+ return;
+
+ PopupMenu(menuWx, localEventPoint);
+
+ Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxWebView::OnMenuSelectEvents), NULL, this);
+}
+
+void wxWebView::OnMenuSelectEvents(wxCommandEvent& event)
+{
+ // we shouldn't hit this unless there's a context menu showing
+ WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
+ ASSERT(coreMenu);
+ if (!coreMenu)
+ return;
+
+ WebCore::ContextMenuItem* item = WebCore::ContextMenu::itemWithId (event.GetId());
+ if (!item)
+ return;
+
+ m_impl->page->contextMenuController()->contextMenuItemSelected(item);
+ delete item;
+}
+
+bool wxWebView::CanCopy()
+{
+ if (m_mainFrame)
+ return m_mainFrame->CanCopy();
+
+ return false;
+}
+
+void wxWebView::Copy()
+{
+ if (m_mainFrame)
+ m_mainFrame->Copy();
+}
+
+bool wxWebView::CanCut()
+{
+ if (m_mainFrame)
+ return m_mainFrame->CanCut();
+
+ return false;
+}
+
+void wxWebView::Cut()
+{
+ if (m_mainFrame)
+ m_mainFrame->Cut();
+}
+
+bool wxWebView::CanPaste()
+{
+ if (m_mainFrame)
+ return m_mainFrame->CanPaste();
+
+ return false;
+}
+
+void wxWebView::Paste()
+{
+ if (m_mainFrame)
+ m_mainFrame->Paste();
+}
+
+void wxWebView::OnKeyEvents(wxKeyEvent& event)
+{
+ WebCore::Frame* frame = 0;
+ if (m_impl->page)
+ frame = m_impl->page->focusController()->focusedOrMainFrame();
+
+ if (!(frame && frame->view()))
+ return;
+
+ if (event.GetKeyCode() == WXK_CAPITAL)
+ frame->eventHandler()->capsLockStateMayHaveChanged();
+
+ WebCore::PlatformKeyboardEvent wkEvent(event);
+
+ if (frame->eventHandler()->keyEvent(wkEvent))
+ return;
+
+ //Some things WebKit won't do for us... Copy/Cut/Paste and KB scrolling
+ if (event.GetEventType() == wxEVT_KEY_DOWN) {
+ switch (event.GetKeyCode()) {
+ case 67: //"C"
+ if (CanCopy() && event.GetModifiers() == wxMOD_CMD) {
+ Copy();
+ return;
+ }
+ break;
+ case 86: //"V"
+ if (CanPaste() && event.GetModifiers() == wxMOD_CMD) {
+ Paste();
+ return;
+ }
+ break;
+ case 88: //"X"
+ if (CanCut() && event.GetModifiers() == wxMOD_CMD) {
+ Cut();
+ return;
+ }
+ break;
+ case WXK_INSERT:
+ if (CanCopy() && event.GetModifiers() == wxMOD_CMD) {
+ Copy();
+ return;
+ }
+ if (CanPaste() && event.GetModifiers() == wxMOD_SHIFT) {
+ Paste();
+ return;
+ }
+ return; //Insert shall not become a char
+ case WXK_DELETE:
+ if (CanCut() && event.GetModifiers() == wxMOD_SHIFT) {
+ Cut();
+ return;
+ }
+ break;
+ case WXK_LEFT:
+ case WXK_NUMPAD_LEFT:
+ frame->view()->scrollBy(WebCore::IntSize(-WebCore::Scrollbar::pixelsPerLineStep(), 0));
+ return;
+ case WXK_UP:
+ case WXK_NUMPAD_UP:
+ frame->view()->scrollBy(WebCore::IntSize(0, -WebCore::Scrollbar::pixelsPerLineStep()));
+ return;
+ case WXK_RIGHT:
+ case WXK_NUMPAD_RIGHT:
+ frame->view()->scrollBy(WebCore::IntSize(WebCore::Scrollbar::pixelsPerLineStep(), 0));
+ return;
+ case WXK_DOWN:
+ case WXK_NUMPAD_DOWN:
+ frame->view()->scrollBy(WebCore::IntSize(0, WebCore::Scrollbar::pixelsPerLineStep()));
+ return;
+ case WXK_END:
+ case WXK_NUMPAD_END:
+ frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), frame->view()->maximumScrollPosition().y()));
+ return;
+ case WXK_HOME:
+ case WXK_NUMPAD_HOME:
+ frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), 0));
+ return;
+ case WXK_PAGEUP:
+ case WXK_NUMPAD_PAGEUP:
+ frame->view()->scrollBy(WebCore::IntSize(0, -frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
+ return;
+ case WXK_PAGEDOWN:
+ case WXK_NUMPAD_PAGEDOWN:
+ frame->view()->scrollBy(WebCore::IntSize(0, frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
+ return;
+ //These we don't want turning into char events, stuff 'em
+ case WXK_ESCAPE:
+ case WXK_LBUTTON:
+ case WXK_RBUTTON:
+ case WXK_CANCEL:
+ case WXK_MENU:
+ case WXK_MBUTTON:
+ case WXK_CLEAR:
+ case WXK_PAUSE:
+ case WXK_SELECT:
+ case WXK_PRINT:
+ case WXK_EXECUTE:
+ case WXK_SNAPSHOT:
+ case WXK_HELP:
+ case WXK_F1:
+ case WXK_F2:
+ case WXK_F3:
+ case WXK_F4:
+ case WXK_F5:
+ case WXK_F6:
+ case WXK_F7:
+ case WXK_F8:
+ case WXK_F9:
+ case WXK_F10:
+ case WXK_F11:
+ case WXK_F12:
+ case WXK_F13:
+ case WXK_F14:
+ case WXK_F15:
+ case WXK_F16:
+ case WXK_F17:
+ case WXK_F18:
+ case WXK_F19:
+ case WXK_F20:
+ case WXK_F21:
+ case WXK_F22:
+ case WXK_F23:
+ case WXK_F24:
+ case WXK_NUMPAD_F1:
+ case WXK_NUMPAD_F2:
+ case WXK_NUMPAD_F3:
+ case WXK_NUMPAD_F4:
+ //When numlock is off Numpad 5 becomes BEGIN, or HOME on Char
+ case WXK_NUMPAD_BEGIN:
+ case WXK_NUMPAD_INSERT:
+ return;
+ }
+ }
+
+ event.Skip();
+}
+
+void wxWebView::OnSetFocus(wxFocusEvent& event)
+{
+ if (m_impl && m_impl->page && m_impl->page->focusController()) {
+ m_impl->page->focusController()->setFocused(true);
+ m_impl->page->focusController()->setActive(true);
+
+ if (!m_impl->page->focusController()->focusedFrame() && m_mainFrame)
+ m_impl->page->focusController()->setFocusedFrame(m_mainFrame->GetFrame());
+ }
+
+ event.Skip();
+}
+
+void wxWebView::OnKillFocus(wxFocusEvent& event)
+{
+ if (m_impl && m_impl->page && m_impl->page->focusController()) {
+ m_impl->page->focusController()->setFocused(false);
+
+ // We also handle active state in OnTLWActivated, but if a user does not
+ // call event.Skip() in their own EVT_ACTIVATE handler, we won't get those
+ // callbacks. So we handle active state here as well as a fallback.
+ wxTopLevelWindow* tlw = dynamic_cast<wxTopLevelWindow*>(wxGetTopLevelParent(this));
+ if (tlw && tlw->IsActive())
+ m_impl->page->focusController()->setActive(true);
+ else
+ m_impl->page->focusController()->setActive(false);
+ }
+
+ while (HasCapture())
+ ReleaseMouse();
+
+ event.Skip();
+}
+
+wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const
+{
+ if (m_mainFrame)
+ return m_mainFrame->HitTest(pos);
+
+ return wxWebViewDOMElementInfo();
+}
+
+bool wxWebView::ShouldClose() const
+{
+ if (m_mainFrame)
+ return m_mainFrame->ShouldClose();
+
+ return true;
+}
+
+/* static */
+void wxWebView::SetDatabaseDirectory(const wxString& databaseDirectory)
+{
+#if ENABLE(DATABASE)
+ WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(databaseDirectory);
+#endif
+}
+
+/* static */
+wxString wxWebView::GetDatabaseDirectory()
+{
+#if ENABLE(DATABASE)
+ return WebCore::DatabaseTracker::tracker().databaseDirectoryPath();
+#else
+ return wxEmptyString;
+#endif
+}
+
+/* static */
+void wxWebView::SetDatabasesEnabled(bool enabled)
+{
+#if ENABLE(DATABASE)
+ WebCore::AbstractDatabase::setIsAvailable(enabled);
+#endif
+}
+
+/* static */
+bool wxWebView::AreDatabasesEnabled()
+{
+#if ENABLE(DATABASE)
+ return WebCore::AbstractDatabase::isAvailable();
+#endif
+ return false;
+}
+
+static WebCore::ResourceHandleManager::ProxyType curlProxyType(wxProxyType type)
+{
+ switch (type) {
+ case HTTP: return WebCore::ResourceHandleManager::HTTP;
+ case Socks4: return WebCore::ResourceHandleManager::Socks4;
+ case Socks4A: return WebCore::ResourceHandleManager::Socks4A;
+ case Socks5: return WebCore::ResourceHandleManager::Socks5;
+ case Socks5Hostname: return WebCore::ResourceHandleManager::Socks5Hostname;
+ default:
+ ASSERT_NOT_REACHED();
+ return WebCore::ResourceHandleManager::HTTP;
+ }
+}
+
+/* static */
+void wxWebView::SetProxyInfo(const wxString& host,
+ unsigned long port,
+ wxProxyType type,
+ const wxString& username,
+ const wxString& password)
+{
+ using WebCore::ResourceHandleManager;
+ if (ResourceHandleManager* mgr = ResourceHandleManager::sharedInstance())
+ mgr->setProxyInfo(host, port, curlProxyType(type), username, password);
+}
+
+wxWebSettings wxWebView::GetWebSettings()
+{
+ ASSERT(m_impl->page);
+ if (m_impl->page)
+ return wxWebSettings(m_impl->page->settings());
+
+ return wxWebSettings();
+}
+
+wxWebKitParseMode wxWebView::GetParseMode() const
+{
+ if (m_mainFrame)
+ return m_mainFrame->GetParseMode();
+
+ return NoDocument;
+}
+
+void wxWebView::GrantUniversalAccess()
+{
+ if (m_mainFrame)
+ m_mainFrame->GrantUniversalAccess();
+}