diff -r 000000000000 -r 4f2f89ce4247 WebKit/wx/WebView.cpp --- /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 +#include +#include + +#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 +#include +#include + +#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(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(); +}