Home | History | Annotate | Download | only in wx
      1 /*
      2  * Copyright (C) 2007 Kevin Ollivier  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "Cache.h"
     28 #include "ContextMenu.h"
     29 #include "ContextMenuItem.h"
     30 #include "ContextMenuController.h"
     31 #include "CString.h"
     32 #include "Document.h"
     33 #include "Element.h"
     34 #include "Editor.h"
     35 #include "EmptyClients.h"
     36 #include "EventHandler.h"
     37 #include "FileChooser.h"
     38 #include "FocusController.h"
     39 #include "Frame.h"
     40 #include "FrameLoader.h"
     41 #include "FrameView.h"
     42 #include "GraphicsContext.h"
     43 #include "HTMLFormElement.h"
     44 #include "Logging.h"
     45 #include "markup.h"
     46 #include "Page.h"
     47 #include "PlatformKeyboardEvent.h"
     48 #include "PlatformMouseEvent.h"
     49 #include "PlatformString.h"
     50 #include "PlatformWheelEvent.h"
     51 #include "PluginHalterClient.h"
     52 #include "RenderObject.h"
     53 #include "RenderView.h"
     54 #include "ResourceHandleManager.h"
     55 #include "Scrollbar.h"
     56 #include "SelectionController.h"
     57 #include "Settings.h"
     58 #include "SubstituteData.h"
     59 #include "Threading.h"
     60 
     61 #include "ChromeClientWx.h"
     62 #include "ContextMenuClientWx.h"
     63 #include "DragClientWx.h"
     64 #include "EditorClientWx.h"
     65 #include "FrameLoaderClientWx.h"
     66 #include "InspectorClientWx.h"
     67 
     68 #include "ScriptController.h"
     69 #include "JSDOMBinding.h"
     70 #include <runtime/JSValue.h>
     71 #include <runtime/UString.h>
     72 
     73 #if ENABLE(DATABASE)
     74 #include "DatabaseTracker.h"
     75 #endif
     76 
     77 #include "wx/wxprec.h"
     78 #ifndef WX_PRECOMP
     79     #include "wx/wx.h"
     80 #endif
     81 
     82 #include "WebFrame.h"
     83 #include "WebView.h"
     84 #include "WebViewPrivate.h"
     85 
     86 #include <wx/defs.h>
     87 #include <wx/dcbuffer.h>
     88 #include <wx/dcgraph.h>
     89 
     90 #if defined(_MSC_VER)
     91 int rint(double val)
     92 {
     93     return (int)(val < 0 ? val - 0.5 : val + 0.5);
     94 }
     95 #endif
     96 
     97 // ----------------------------------------------------------------------------
     98 // wxWebView Events
     99 // ----------------------------------------------------------------------------
    100 
    101 IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent)
    102 
    103 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD)
    104 
    105 wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win)
    106 {
    107     SetEventType( wxEVT_WEBVIEW_LOAD);
    108     SetEventObject( win );
    109     if (win)
    110         SetId(win->GetId());
    111 }
    112 
    113 IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent)
    114 
    115 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD)
    116 
    117 wxWebViewBeforeLoadEvent::wxWebViewBeforeLoadEvent(wxWindow* win)
    118 {
    119     m_cancelled = false;
    120     SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD);
    121     SetEventObject(win);
    122     if (win)
    123         SetId(win->GetId());
    124 }
    125 
    126 IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent)
    127 
    128 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW)
    129 
    130 wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win)
    131 {
    132     SetEventType(wxEVT_WEBVIEW_NEW_WINDOW);
    133     SetEventObject(win);
    134     if (win)
    135         SetId(win->GetId());
    136 }
    137 
    138 IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent)
    139 
    140 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK)
    141 
    142 wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win)
    143 {
    144     SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK);
    145     SetEventObject(win);
    146     if (win)
    147         SetId(win->GetId());
    148 }
    149 
    150 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent)
    151 
    152 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE)
    153 
    154 wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win)
    155 {
    156     SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE);
    157     SetEventObject(win);
    158     if (win)
    159         SetId(win->GetId());
    160 }
    161 
    162 IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent, wxCommandEvent)
    163 
    164 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT)
    165 
    166 wxWebViewAlertEvent::wxWebViewAlertEvent(wxWindow* win)
    167 {
    168     SetEventType(wxEVT_WEBVIEW_JS_ALERT);
    169     SetEventObject(win);
    170     if (win)
    171         SetId(win->GetId());
    172 }
    173 
    174 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent, wxCommandEvent)
    175 
    176 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM)
    177 
    178 wxWebViewConfirmEvent::wxWebViewConfirmEvent(wxWindow* win)
    179 {
    180     SetEventType(wxEVT_WEBVIEW_JS_CONFIRM);
    181     SetEventObject(win);
    182     if (win)
    183         SetId(win->GetId());
    184 }
    185 
    186 IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent, wxCommandEvent)
    187 
    188 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT)
    189 
    190 wxWebViewPromptEvent::wxWebViewPromptEvent(wxWindow* win)
    191 {
    192     SetEventType(wxEVT_WEBVIEW_JS_PROMPT);
    193     SetEventObject(win);
    194     if (win)
    195         SetId(win->GetId());
    196 }
    197 
    198 IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent)
    199 
    200 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE)
    201 
    202 wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win)
    203 {
    204     SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE);
    205     SetEventObject(win);
    206     if (win)
    207         SetId(win->GetId());
    208 }
    209 
    210 IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent, wxCommandEvent)
    211 
    212 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED)
    213 
    214 wxWebViewWindowObjectClearedEvent::wxWebViewWindowObjectClearedEvent(wxWindow* win)
    215 {
    216     SetEventType(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED);
    217     SetEventObject(win);
    218     if (win)
    219         SetId(win->GetId());
    220 }
    221 
    222 
    223 //---------------------------------------------------------
    224 // DOM Element info data type
    225 //---------------------------------------------------------
    226 
    227 wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() :
    228     m_domElement(NULL),
    229     m_isSelected(false),
    230     m_text(wxEmptyString),
    231     m_imageSrc(wxEmptyString),
    232     m_link(wxEmptyString)
    233 {
    234 }
    235 
    236 static wxWebViewCachePolicy gs_cachePolicy;
    237 
    238 /* static */
    239 void wxWebView::SetCachePolicy(const wxWebViewCachePolicy& cachePolicy)
    240 {
    241     WebCore::Cache* globalCache = WebCore::cache();
    242     globalCache->setCapacities(cachePolicy.GetMinDeadCapacity(),
    243                                cachePolicy.GetMaxDeadCapacity(),
    244                                cachePolicy.GetCapacity());
    245 
    246     // store a copy since there is no getter for Cache values
    247     gs_cachePolicy = cachePolicy;
    248 }
    249 
    250 /* static */
    251 wxWebViewCachePolicy wxWebView::GetCachePolicy()
    252 {
    253     return gs_cachePolicy;
    254 }
    255 
    256 BEGIN_EVENT_TABLE(wxWebView, wxWindow)
    257     EVT_PAINT(wxWebView::OnPaint)
    258     EVT_SIZE(wxWebView::OnSize)
    259     EVT_MOUSE_EVENTS(wxWebView::OnMouseEvents)
    260     EVT_CONTEXT_MENU(wxWebView::OnContextMenuEvents)
    261     EVT_KEY_DOWN(wxWebView::OnKeyEvents)
    262     EVT_KEY_UP(wxWebView::OnKeyEvents)
    263     EVT_CHAR(wxWebView::OnKeyEvents)
    264     EVT_SET_FOCUS(wxWebView::OnSetFocus)
    265     EVT_KILL_FOCUS(wxWebView::OnKillFocus)
    266 END_EVENT_TABLE()
    267 
    268 IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow)
    269 
    270 const wxChar* wxWebViewNameStr = wxT("webView");
    271 
    272 wxWebView::wxWebView() :
    273     m_textMagnifier(1.0),
    274     m_isEditable(false),
    275     m_isInitialized(false),
    276     m_beingDestroyed(false),
    277     m_mouseWheelZooms(false),
    278     m_title(wxEmptyString)
    279 {
    280 }
    281 
    282 wxWebView::wxWebView(wxWindow* parent, int id, const wxPoint& position,
    283                      const wxSize& size, long style, const wxString& name) :
    284     m_textMagnifier(1.0),
    285     m_isEditable(false),
    286     m_isInitialized(false),
    287     m_beingDestroyed(false),
    288     m_mouseWheelZooms(false),
    289     m_title(wxEmptyString)
    290 {
    291     Create(parent, id, position, size, style, name);
    292 }
    293 
    294 bool wxWebView::Create(wxWindow* parent, int id, const wxPoint& position,
    295                        const wxSize& size, long style, const wxString& name)
    296 {
    297     if ( (style & wxBORDER_MASK) == 0)
    298         style |= wxBORDER_NONE;
    299 
    300     if (!wxWindow::Create(parent, id, position, size, style, name))
    301         return false;
    302 
    303     WTF::initializeThreading();
    304 
    305 // This is necessary because we are using SharedTimerWin.cpp on Windows,
    306 // due to a problem with exceptions getting eaten when using the callback
    307 // approach to timers (which wx itself uses).
    308 #if __WXMSW__
    309     WebCore::Page::setInstanceHandle(wxGetInstance());
    310 #endif
    311 
    312     // this helps reduce flicker on platforms like MSW
    313     SetBackgroundStyle(wxBG_STYLE_CUSTOM);
    314 
    315     m_impl = new WebViewPrivate();
    316 
    317     WebCore::InitializeLoggingChannelsIfNecessary();
    318     WebCore::HTMLFrameOwnerElement* parentFrame = 0;
    319 
    320     WebCore::EditorClientWx* editorClient = new WebCore::EditorClientWx();
    321     m_impl->page = new WebCore::Page(new WebCore::ChromeClientWx(this), new WebCore::ContextMenuClientWx(), editorClient, new WebCore::DragClientWx(), new WebCore::InspectorClientWx(), 0, 0);
    322     editorClient->setPage(m_impl->page);
    323 
    324     m_mainFrame = new wxWebFrame(this);
    325 
    326     // Default settings - we should have wxWebViewSettings class for this
    327     // eventually
    328     WebCore::Settings* settings = m_impl->page->settings();
    329     settings->setLoadsImagesAutomatically(true);
    330     settings->setDefaultFixedFontSize(13);
    331     settings->setDefaultFontSize(16);
    332     settings->setSerifFontFamily("Times New Roman");
    333     settings->setFixedFontFamily("Courier New");
    334     settings->setSansSerifFontFamily("Arial");
    335     settings->setStandardFontFamily("Times New Roman");
    336     settings->setJavaScriptEnabled(true);
    337 
    338 #if ENABLE(DATABASE)
    339     settings->setDatabasesEnabled(true);
    340 #endif
    341 
    342     m_isInitialized = true;
    343 
    344     return true;
    345 }
    346 
    347 wxWebView::~wxWebView()
    348 {
    349     m_beingDestroyed = true;
    350 
    351     while (HasCapture())
    352         ReleaseMouse();
    353 
    354     if (m_mainFrame && m_mainFrame->GetFrame())
    355         m_mainFrame->GetFrame()->loader()->detachFromParent();
    356 
    357     delete m_impl->page;
    358     m_impl->page = 0;
    359 }
    360 
    361 void wxWebView::Stop()
    362 {
    363     if (m_mainFrame)
    364         m_mainFrame->Stop();
    365 }
    366 
    367 void wxWebView::Reload()
    368 {
    369     if (m_mainFrame)
    370         m_mainFrame->Reload();
    371 }
    372 
    373 wxString wxWebView::GetPageSource()
    374 {
    375     if (m_mainFrame)
    376         return m_mainFrame->GetPageSource();
    377 
    378     return wxEmptyString;
    379 }
    380 
    381 void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl)
    382 {
    383     if (m_mainFrame)
    384         m_mainFrame->SetPageSource(source, baseUrl);
    385 }
    386 
    387 wxString wxWebView::GetInnerText()
    388 {
    389     if (m_mainFrame)
    390         return m_mainFrame->GetInnerText();
    391 
    392     return wxEmptyString;
    393 }
    394 
    395 wxString wxWebView::GetAsMarkup()
    396 {
    397     if (m_mainFrame)
    398         return m_mainFrame->GetAsMarkup();
    399 
    400     return wxEmptyString;
    401 }
    402 
    403 wxString wxWebView::GetExternalRepresentation()
    404 {
    405     if (m_mainFrame)
    406         return m_mainFrame->GetExternalRepresentation();
    407 
    408     return wxEmptyString;
    409 }
    410 
    411 void wxWebView::SetTransparent(bool transparent)
    412 {
    413     WebCore::Frame* frame = 0;
    414     if (m_mainFrame)
    415         frame = m_mainFrame->GetFrame();
    416 
    417     if (!frame || !frame->view())
    418         return;
    419 
    420     frame->view()->setTransparent(transparent);
    421 }
    422 
    423 bool wxWebView::IsTransparent() const
    424 {
    425     WebCore::Frame* frame = 0;
    426     if (m_mainFrame)
    427         frame = m_mainFrame->GetFrame();
    428 
    429    if (!frame || !frame->view())
    430         return false;
    431 
    432     return frame->view()->isTransparent();
    433 }
    434 
    435 wxString wxWebView::RunScript(const wxString& javascript)
    436 {
    437     if (m_mainFrame)
    438         return m_mainFrame->RunScript(javascript);
    439 
    440     return wxEmptyString;
    441 }
    442 
    443 void wxWebView::LoadURL(const wxString& url)
    444 {
    445     if (m_mainFrame)
    446         m_mainFrame->LoadURL(url);
    447 }
    448 
    449 bool wxWebView::GoBack()
    450 {
    451     if (m_mainFrame)
    452         return m_mainFrame->GoBack();
    453 
    454     return false;
    455 }
    456 
    457 bool wxWebView::GoForward()
    458 {
    459     if (m_mainFrame)
    460         return m_mainFrame->GoForward();
    461 
    462     return false;
    463 }
    464 
    465 bool wxWebView::CanGoBack()
    466 {
    467     if (m_mainFrame)
    468         return m_mainFrame->CanGoBack();
    469 
    470     return false;
    471 }
    472 
    473 bool wxWebView::CanGoForward()
    474 {
    475     if (m_mainFrame)
    476         return m_mainFrame->CanGoForward();
    477 
    478     return false;
    479 }
    480 
    481 bool wxWebView::CanIncreaseTextSize() const
    482 {
    483     if (m_mainFrame)
    484         return m_mainFrame->CanIncreaseTextSize();
    485 
    486     return false;
    487 }
    488 
    489 void wxWebView::IncreaseTextSize()
    490 {
    491     if (m_mainFrame)
    492         m_mainFrame->IncreaseTextSize();
    493 }
    494 
    495 bool wxWebView::CanDecreaseTextSize() const
    496 {
    497     if (m_mainFrame)
    498         m_mainFrame->CanDecreaseTextSize();
    499 
    500     return false;
    501 }
    502 
    503 void wxWebView::DecreaseTextSize()
    504 {
    505     if (m_mainFrame)
    506         m_mainFrame->DecreaseTextSize();
    507 }
    508 
    509 void wxWebView::ResetTextSize()
    510 {
    511     if (m_mainFrame)
    512         m_mainFrame->ResetTextSize();
    513 }
    514 
    515 void wxWebView::MakeEditable(bool enable)
    516 {
    517     m_isEditable = enable;
    518 }
    519 
    520 
    521 /*
    522  * Event forwarding functions to send events down to WebCore.
    523  */
    524 
    525 void wxWebView::OnPaint(wxPaintEvent& event)
    526 {
    527     if (m_beingDestroyed || !m_mainFrame)
    528         return;
    529 
    530     // WebView active state is based on TLW active state.
    531     wxTopLevelWindow* tlw = dynamic_cast<wxTopLevelWindow*>(wxGetTopLevelParent(this));
    532     if (tlw && tlw->IsActive())
    533         m_impl->page->focusController()->setActive(true);
    534     else {
    535         m_impl->page->focusController()->setActive(false);
    536     }
    537     WebCore::Frame* frame = m_mainFrame->GetFrame();
    538     if (!frame || !frame->view())
    539         return;
    540 
    541     wxAutoBufferedPaintDC dc(this);
    542 
    543     if (IsShown() && frame->document()) {
    544 #if USE(WXGC)
    545         wxGCDC gcdc(dc);
    546 #endif
    547 
    548         if (dc.IsOk()) {
    549             wxRect paintRect = GetUpdateRegion().GetBox();
    550 
    551 #if USE(WXGC)
    552             WebCore::GraphicsContext gc(&gcdc);
    553 #else
    554             WebCore::GraphicsContext gc(&dc);
    555 #endif
    556             if (frame->contentRenderer()) {
    557                 frame->view()->layoutIfNeededRecursive();
    558                 frame->view()->paint(&gc, paintRect);
    559             }
    560         }
    561     }
    562 }
    563 
    564 bool wxWebView::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
    565 {
    566     if (m_mainFrame)
    567         return m_mainFrame->FindString(string, forward, caseSensitive, wrapSelection, startInSelection);
    568 
    569     return false;
    570 }
    571 
    572 void wxWebView::OnSize(wxSizeEvent& event)
    573 {
    574     if (m_isInitialized && m_mainFrame) {
    575         WebCore::Frame* frame = m_mainFrame->GetFrame();
    576         frame->view()->setFrameRect(wxRect(wxPoint(0,0), event.GetSize()));
    577         frame->view()->forceLayout();
    578         frame->view()->adjustViewSize();
    579     }
    580 
    581     event.Skip();
    582 }
    583 
    584 static int getDoubleClickTime()
    585 {
    586 #if __WXMSW__
    587     return ::GetDoubleClickTime();
    588 #else
    589     return 500;
    590 #endif
    591 }
    592 
    593 void wxWebView::OnMouseEvents(wxMouseEvent& event)
    594 {
    595     event.Skip();
    596 
    597     if (!m_impl->page)
    598         return;
    599 
    600     WebCore::Frame* frame = m_mainFrame->GetFrame();
    601     if (!frame || !frame->view())
    602         return;
    603 
    604     wxPoint globalPoint = ClientToScreen(event.GetPosition());
    605 
    606     wxEventType type = event.GetEventType();
    607 
    608     if (type == wxEVT_MOUSEWHEEL) {
    609         if (m_mouseWheelZooms && event.ControlDown() && !event.AltDown() && !event.ShiftDown()) {
    610             if (event.GetWheelRotation() < 0)
    611                 DecreaseTextSize();
    612             else if (event.GetWheelRotation() > 0)
    613                 IncreaseTextSize();
    614         } else {
    615             WebCore::PlatformWheelEvent wkEvent(event, globalPoint);
    616             frame->eventHandler()->handleWheelEvent(wkEvent);
    617         }
    618 
    619         return;
    620     }
    621 
    622     int clickCount = event.ButtonDClick() ? 2 : 1;
    623 
    624     if (clickCount == 1 && m_impl->tripleClickTimer.IsRunning()) {
    625         wxPoint diff(event.GetPosition() - m_impl->tripleClickPos);
    626         if (abs(diff.x) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_X) &&
    627             abs(diff.y) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_Y)) {
    628             clickCount = 3;
    629         }
    630     } else if (clickCount == 2) {
    631         m_impl->tripleClickTimer.Start(getDoubleClickTime(), false);
    632         m_impl->tripleClickPos = event.GetPosition();
    633     }
    634 
    635     WebCore::PlatformMouseEvent wkEvent(event, globalPoint, clickCount);
    636 
    637     if (type == wxEVT_LEFT_DOWN || type == wxEVT_MIDDLE_DOWN || type == wxEVT_RIGHT_DOWN ||
    638                 type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK) {
    639         frame->eventHandler()->handleMousePressEvent(wkEvent);
    640         if (!HasCapture())
    641             CaptureMouse();
    642     } else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP) {
    643         frame->eventHandler()->handleMouseReleaseEvent(wkEvent);
    644         while (HasCapture())
    645             ReleaseMouse();
    646     } else if (type == wxEVT_MOTION || type == wxEVT_ENTER_WINDOW || type == wxEVT_LEAVE_WINDOW)
    647         frame->eventHandler()->mouseMoved(wkEvent);
    648 }
    649 
    650 void wxWebView::OnContextMenuEvents(wxContextMenuEvent& event)
    651 {
    652     Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxWebView::OnMenuSelectEvents), NULL, this);
    653     m_impl->page->contextMenuController()->clearContextMenu();
    654     wxPoint localEventPoint = ScreenToClient(event.GetPosition());
    655 
    656     if (!m_impl->page)
    657         return;
    658 
    659     WebCore::Frame* focusedFrame = m_impl->page->focusController()->focusedOrMainFrame();
    660     if (!focusedFrame->view())
    661         return;
    662 
    663     //Create WebCore mouse event from the wxContextMenuEvent
    664     wxMouseEvent mouseEvent(wxEVT_RIGHT_DOWN);
    665     mouseEvent.m_x = localEventPoint.x;
    666     mouseEvent.m_y = localEventPoint.y;
    667     WebCore::PlatformMouseEvent wkEvent(mouseEvent, event.GetPosition(), 1);
    668 
    669     bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(wkEvent);
    670     if (!handledEvent)
    671         return;
    672 
    673     WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
    674     if (!coreMenu)
    675         return;
    676 
    677     WebCore::PlatformMenuDescription menuWx = coreMenu->platformDescription();
    678     if (!menuWx)
    679         return;
    680 
    681     PopupMenu(menuWx, localEventPoint);
    682 
    683     Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxWebView::OnMenuSelectEvents), NULL, this);
    684 }
    685 
    686 void wxWebView::OnMenuSelectEvents(wxCommandEvent& event)
    687 {
    688     // we shouldn't hit this unless there's a context menu showing
    689     WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
    690     ASSERT(coreMenu);
    691     if (!coreMenu)
    692         return;
    693 
    694     WebCore::ContextMenuItem* item = WebCore::ContextMenu::itemWithId (event.GetId());
    695     if (!item)
    696         return;
    697 
    698     m_impl->page->contextMenuController()->contextMenuItemSelected(item);
    699     delete item;
    700 }
    701 
    702 bool wxWebView::CanCopy()
    703 {
    704     if (m_mainFrame)
    705         return m_mainFrame->CanCopy();
    706 
    707     return false;
    708 }
    709 
    710 void wxWebView::Copy()
    711 {
    712     if (m_mainFrame)
    713         m_mainFrame->Copy();
    714 }
    715 
    716 bool wxWebView::CanCut()
    717 {
    718     if (m_mainFrame)
    719         return m_mainFrame->CanCut();
    720 
    721     return false;
    722 }
    723 
    724 void wxWebView::Cut()
    725 {
    726     if (m_mainFrame)
    727         m_mainFrame->Cut();
    728 }
    729 
    730 bool wxWebView::CanPaste()
    731 {
    732     if (m_mainFrame)
    733         return m_mainFrame->CanPaste();
    734 
    735     return false;
    736 }
    737 
    738 void wxWebView::Paste()
    739 {
    740     if (m_mainFrame)
    741         m_mainFrame->Paste();
    742 }
    743 
    744 void wxWebView::OnKeyEvents(wxKeyEvent& event)
    745 {
    746     WebCore::Frame* frame = 0;
    747     if (m_impl->page)
    748         frame = m_impl->page->focusController()->focusedOrMainFrame();
    749 
    750     if (!(frame && frame->view()))
    751         return;
    752 
    753     if (event.GetKeyCode() == WXK_CAPITAL)
    754         frame->eventHandler()->capsLockStateMayHaveChanged();
    755 
    756     WebCore::PlatformKeyboardEvent wkEvent(event);
    757 
    758     if (frame->eventHandler()->keyEvent(wkEvent))
    759         return;
    760 
    761     //Some things WebKit won't do for us... Copy/Cut/Paste and KB scrolling
    762     if (event.GetEventType() == wxEVT_KEY_DOWN) {
    763         switch (event.GetKeyCode()) {
    764         case 67: //"C"
    765             if (CanCopy() && event.GetModifiers() == wxMOD_CMD) {
    766                 Copy();
    767                 return;
    768             }
    769             break;
    770         case 86: //"V"
    771             if (CanPaste() && event.GetModifiers() == wxMOD_CMD) {
    772                 Paste();
    773                 return;
    774             }
    775             break;
    776         case 88: //"X"
    777             if (CanCut() && event.GetModifiers() == wxMOD_CMD) {
    778                 Cut();
    779                 return;
    780             }
    781             break;
    782         case WXK_INSERT:
    783             if (CanCopy() && event.GetModifiers() == wxMOD_CMD) {
    784                 Copy();
    785                 return;
    786             }
    787             if (CanPaste() && event.GetModifiers() == wxMOD_SHIFT) {
    788                 Paste();
    789                 return;
    790             }
    791             return; //Insert shall not become a char
    792         case WXK_DELETE:
    793             if (CanCut() && event.GetModifiers() == wxMOD_SHIFT) {
    794                 Cut();
    795                 return;
    796             }
    797             break;
    798         case WXK_LEFT:
    799         case WXK_NUMPAD_LEFT:
    800             frame->view()->scrollBy(WebCore::IntSize(-WebCore::Scrollbar::pixelsPerLineStep(), 0));
    801             return;
    802         case WXK_UP:
    803         case WXK_NUMPAD_UP:
    804             frame->view()->scrollBy(WebCore::IntSize(0, -WebCore::Scrollbar::pixelsPerLineStep()));
    805             return;
    806         case WXK_RIGHT:
    807         case WXK_NUMPAD_RIGHT:
    808             frame->view()->scrollBy(WebCore::IntSize(WebCore::Scrollbar::pixelsPerLineStep(), 0));
    809             return;
    810         case WXK_DOWN:
    811         case WXK_NUMPAD_DOWN:
    812             frame->view()->scrollBy(WebCore::IntSize(0, WebCore::Scrollbar::pixelsPerLineStep()));
    813             return;
    814         case WXK_END:
    815         case WXK_NUMPAD_END:
    816             frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), frame->view()->maximumScrollPosition().y()));
    817             return;
    818         case WXK_HOME:
    819         case WXK_NUMPAD_HOME:
    820             frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), 0));
    821             return;
    822         case WXK_PAGEUP:
    823         case WXK_NUMPAD_PAGEUP:
    824             frame->view()->scrollBy(WebCore::IntSize(0, -frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
    825             return;
    826         case WXK_PAGEDOWN:
    827         case WXK_NUMPAD_PAGEDOWN:
    828             frame->view()->scrollBy(WebCore::IntSize(0, frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging()));
    829             return;
    830         //These we don't want turning into char events, stuff 'em
    831         case WXK_ESCAPE:
    832         case WXK_LBUTTON:
    833         case WXK_RBUTTON:
    834         case WXK_CANCEL:
    835         case WXK_MENU:
    836         case WXK_MBUTTON:
    837         case WXK_CLEAR:
    838         case WXK_PAUSE:
    839         case WXK_SELECT:
    840         case WXK_PRINT:
    841         case WXK_EXECUTE:
    842         case WXK_SNAPSHOT:
    843         case WXK_HELP:
    844         case WXK_F1:
    845         case WXK_F2:
    846         case WXK_F3:
    847         case WXK_F4:
    848         case WXK_F5:
    849         case WXK_F6:
    850         case WXK_F7:
    851         case WXK_F8:
    852         case WXK_F9:
    853         case WXK_F10:
    854         case WXK_F11:
    855         case WXK_F12:
    856         case WXK_F13:
    857         case WXK_F14:
    858         case WXK_F15:
    859         case WXK_F16:
    860         case WXK_F17:
    861         case WXK_F18:
    862         case WXK_F19:
    863         case WXK_F20:
    864         case WXK_F21:
    865         case WXK_F22:
    866         case WXK_F23:
    867         case WXK_F24:
    868         case WXK_NUMPAD_F1:
    869         case WXK_NUMPAD_F2:
    870         case WXK_NUMPAD_F3:
    871         case WXK_NUMPAD_F4:
    872         //When numlock is off Numpad 5 becomes BEGIN, or HOME on Char
    873         case WXK_NUMPAD_BEGIN:
    874         case WXK_NUMPAD_INSERT:
    875             return;
    876         }
    877     }
    878 
    879     event.Skip();
    880 }
    881 
    882 void wxWebView::OnSetFocus(wxFocusEvent& event)
    883 {
    884     WebCore::Frame* frame = 0;
    885     if (m_mainFrame)
    886         frame = m_mainFrame->GetFrame();
    887 
    888     if (frame) {
    889         frame->selection()->setFocused(true);
    890     }
    891 
    892     event.Skip();
    893 }
    894 
    895 void wxWebView::OnKillFocus(wxFocusEvent& event)
    896 {
    897     WebCore::Frame* frame = 0;
    898     if (m_mainFrame)
    899         frame = m_mainFrame->GetFrame();
    900 
    901     if (frame) {
    902         frame->selection()->setFocused(false);
    903     }
    904     event.Skip();
    905 }
    906 
    907 wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const
    908 {
    909     if (m_mainFrame)
    910         return m_mainFrame->HitTest(pos);
    911 
    912     return wxWebViewDOMElementInfo();
    913 }
    914 
    915 bool wxWebView::ShouldClose() const
    916 {
    917     if (m_mainFrame)
    918         return m_mainFrame->ShouldClose();
    919 
    920     return true;
    921 }
    922 
    923 /* static */
    924 void wxWebView::SetDatabaseDirectory(const wxString& databaseDirectory)
    925 {
    926 #if ENABLE(DATABASE)
    927     WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(databaseDirectory);
    928 #endif
    929 }
    930 
    931 /* static */
    932 wxString wxWebView::GetDatabaseDirectory()
    933 {
    934 #if ENABLE(DATABASE)
    935     return WebCore::DatabaseTracker::tracker().databaseDirectoryPath();
    936 #else
    937     return wxEmptyString;
    938 #endif
    939 }
    940 
    941 static WebCore::ResourceHandleManager::ProxyType curlProxyType(wxProxyType type)
    942 {
    943     switch (type) {
    944         case HTTP: return WebCore::ResourceHandleManager::HTTP;
    945         case Socks4: return WebCore::ResourceHandleManager::Socks4;
    946         case Socks4A: return WebCore::ResourceHandleManager::Socks4A;
    947         case Socks5: return WebCore::ResourceHandleManager::Socks5;
    948         case Socks5Hostname: return WebCore::ResourceHandleManager::Socks5Hostname;
    949         default:
    950             ASSERT_NOT_REACHED();
    951             return WebCore::ResourceHandleManager::HTTP;
    952     }
    953 }
    954 
    955 /* static */
    956 void wxWebView::SetProxyInfo(const wxString& host,
    957                              unsigned long port,
    958                              wxProxyType type,
    959                              const wxString& username,
    960                              const wxString& password)
    961 {
    962     using WebCore::ResourceHandleManager;
    963     if (ResourceHandleManager* mgr = ResourceHandleManager::sharedInstance())
    964         mgr->setProxyInfo(host, port, curlProxyType(type), username, password);
    965 }
    966 
    967 wxWebSettings wxWebView::GetWebSettings()
    968 {
    969     ASSERT(m_impl->page);
    970     if (m_impl->page)
    971         return wxWebSettings(m_impl->page->settings());
    972 
    973     return wxWebSettings();
    974 }
    975 
    976 wxWebKitParseMode wxWebView::GetParseMode() const
    977 {
    978     if (m_mainFrame)
    979         return m_mainFrame->GetParseMode();
    980 
    981     return NoDocument;
    982 }