Reviewed by Kevin Ollivier.
[WebKit.git] / WebKit / wx / WebView.cpp
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 "CString.h"
28 #include "Document.h"
29 #include "Element.h"
30 #include "Editor.h"
31 #include "EventHandler.h"
32 #include "FocusController.h"
33 #include "Frame.h"
34 #include "FrameLoader.h"
35 #include "FrameView.h"
36 #include "GraphicsContext.h"
37 #include "Logging.h"
38 #include "markup.h"
39 #include "Page.h"
40 #include "ContextMenu.h"
41 #include "ContextMenuItem.h"
42 #include "ContextMenuController.h"
43 #include "PlatformKeyboardEvent.h"
44 #include "PlatformMouseEvent.h"
45 #include "PlatformString.h"
46 #include "PlatformWheelEvent.h"
47 #include "RenderObject.h"
48 #include "RenderView.h"
49 #include "SelectionController.h"
50 #include "Settings.h"
51 #include "SubstituteData.h"
52
53 #include "ChromeClientWx.h"
54 #include "ContextMenuClientWx.h"
55 #include "DragClientWx.h"
56 #include "EditorClientWx.h"
57 #include "FrameLoaderClientWx.h"
58 #include "InspectorClientWx.h"
59
60 #include "ScriptController.h"
61 #include "JSDOMBinding.h"
62 #include <runtime/JSValue.h>
63 #include <runtime/UString.h>
64
65 #include "wx/wxprec.h"
66 #ifndef WX_PRECOMP
67     #include "wx/wx.h"
68 #endif
69
70 #include "WebFrame.h"
71 #include "WebView.h"
72 #include "WebViewPrivate.h"
73
74 #include <wx/defs.h>
75 #include <wx/dcbuffer.h>
76 #include <wx/dcgraph.h>
77
78 #if defined(_MSC_VER)
79 int rint(double val)
80 {
81     return (int)(val < 0 ? val - 0.5 : val + 0.5);
82 }
83 #endif
84
85 // ----------------------------------------------------------------------------
86 // wxWebView Events
87 // ----------------------------------------------------------------------------
88
89 IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent)
90
91 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD)
92
93 wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win)
94 {
95     SetEventType( wxEVT_WEBVIEW_LOAD);
96     SetEventObject( win );
97     if (win)
98         SetId(win->GetId());
99 }
100
101 IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent)
102
103 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD)
104
105 wxWebViewBeforeLoadEvent::wxWebViewBeforeLoadEvent(wxWindow* win)
106 {
107     m_cancelled = false;
108     SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD);
109     SetEventObject(win);
110     if (win)
111         SetId(win->GetId());
112 }
113
114 IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent)
115
116 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW)
117
118 wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win)
119 {
120     SetEventType(wxEVT_WEBVIEW_NEW_WINDOW);
121     SetEventObject(win);
122     if (win)
123         SetId(win->GetId());
124 }
125
126 IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent)
127
128 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK)
129
130 wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win)
131 {
132     SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK);
133     SetEventObject(win);
134     if (win)
135         SetId(win->GetId());
136 }
137
138 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent)
139
140 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE)
141
142 wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win)
143 {
144     SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE);
145     SetEventObject(win);
146     if (win)
147         SetId(win->GetId());
148 }
149
150 IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent, wxCommandEvent)
151
152 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT)
153
154 wxWebViewAlertEvent::wxWebViewAlertEvent(wxWindow* win)
155 {
156     SetEventType(wxEVT_WEBVIEW_JS_ALERT);
157     SetEventObject(win);
158     if (win)
159         SetId(win->GetId());
160 }
161
162 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent, wxCommandEvent)
163
164 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM)
165
166 wxWebViewConfirmEvent::wxWebViewConfirmEvent(wxWindow* win)
167 {
168     SetEventType(wxEVT_WEBVIEW_JS_CONFIRM);
169     SetEventObject(win);
170     if (win)
171         SetId(win->GetId());
172 }
173
174 IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent, wxCommandEvent)
175
176 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT)
177
178 wxWebViewPromptEvent::wxWebViewPromptEvent(wxWindow* win)
179 {
180     SetEventType(wxEVT_WEBVIEW_JS_PROMPT);
181     SetEventObject(win);
182     if (win)
183         SetId(win->GetId());
184 }
185
186 IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent)
187
188 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE)
189
190 wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win)
191 {
192     SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE);
193     SetEventObject(win);
194     if (win)
195         SetId(win->GetId());
196 }
197
198 IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent, wxCommandEvent)
199
200 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED)
201
202 wxWebViewWindowObjectClearedEvent::wxWebViewWindowObjectClearedEvent(wxWindow* win)
203 {
204     SetEventType(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED);
205     SetEventObject(win);
206     if (win)
207         SetId(win->GetId());
208 }
209
210
211 //---------------------------------------------------------
212 // DOM Element info data type
213 //---------------------------------------------------------
214
215 wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() :
216     m_domElement(NULL),
217     m_isSelected(false),
218     m_text(wxEmptyString),
219     m_imageSrc(wxEmptyString),
220     m_link(wxEmptyString)
221 {
222 }
223
224 BEGIN_EVENT_TABLE(wxWebView, wxWindow)
225     EVT_PAINT(wxWebView::OnPaint)
226     EVT_SIZE(wxWebView::OnSize)
227     EVT_MOUSE_EVENTS(wxWebView::OnMouseEvents)
228     EVT_CONTEXT_MENU(wxWebView::OnContextMenuEvents)
229     EVT_MENU(wxID_ANY, wxWebView::OnMenuSelectEvents)
230     EVT_KEY_DOWN(wxWebView::OnKeyEvents)
231     EVT_KEY_UP(wxWebView::OnKeyEvents)
232     EVT_CHAR(wxWebView::OnKeyEvents)
233     EVT_SET_FOCUS(wxWebView::OnSetFocus)
234     EVT_KILL_FOCUS(wxWebView::OnKillFocus)
235     EVT_ACTIVATE(wxWebView::OnActivate)
236 END_EVENT_TABLE()
237
238 IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow)
239
240 const wxChar* wxWebViewNameStr = wxT("webView");
241
242 wxWebView::wxWebView() :
243     m_textMagnifier(1.0),
244     m_isEditable(false),
245     m_isInitialized(false),
246     m_beingDestroyed(false),
247     m_title(wxEmptyString)
248 {
249 }
250
251 wxWebView::wxWebView(wxWindow* parent, int id, const wxPoint& position, 
252                      const wxSize& size, long style, const wxString& name) :
253     m_textMagnifier(1.0),
254     m_isEditable(false),
255     m_isInitialized(false),
256     m_beingDestroyed(false),
257     m_title(wxEmptyString)
258 {
259     Create(parent, id, position, size, style, name);
260 }
261
262 bool wxWebView::Create(wxWindow* parent, int id, const wxPoint& position, 
263                        const wxSize& size, long style, const wxString& name)
264 {
265     if ( (style & wxBORDER_MASK) == 0)
266         style |= wxBORDER_NONE;
267     style |= wxHSCROLL | wxVSCROLL;
268     
269     if (!wxWindow::Create(parent, id, position, size, style, name))
270         return false;
271
272 // This is necessary because we are using SharedTimerWin.cpp on Windows,
273 // due to a problem with exceptions getting eaten when using the callback
274 // approach to timers (which wx itself uses).
275 #if __WXMSW__
276     WebCore::Page::setInstanceHandle(wxGetInstance());
277 #endif
278
279     // this helps reduce flicker on platforms like MSW
280     SetBackgroundStyle(wxBG_STYLE_CUSTOM);
281
282     m_impl = new WebViewPrivate();
283
284     WebCore::InitializeLoggingChannelsIfNecessary();    
285     WebCore::HTMLFrameOwnerElement* parentFrame = 0;
286
287     WebCore::EditorClientWx* editorClient = new WebCore::EditorClientWx();
288     m_impl->page = new WebCore::Page(new WebCore::ChromeClientWx(this), new WebCore::ContextMenuClientWx(), editorClient, new WebCore::DragClientWx(), new WebCore::InspectorClientWx());
289     editorClient->setPage(m_impl->page);
290     
291     m_mainFrame = new wxWebFrame(this);
292
293     // Default settings - we should have wxWebViewSettings class for this
294     // eventually
295     WebCore::Settings* settings = m_impl->page->settings();
296     settings->setLoadsImagesAutomatically(true);
297     settings->setDefaultFixedFontSize(13);
298     settings->setDefaultFontSize(16);
299     settings->setSerifFontFamily("Times New Roman");
300     settings->setFixedFontFamily("Courier New");
301     settings->setSansSerifFontFamily("Arial");
302     settings->setStandardFontFamily("Times New Roman");
303     settings->setJavaScriptEnabled(true);
304
305     m_isInitialized = true;
306
307     return true;
308 }
309
310 wxWebView::~wxWebView()
311 {
312     m_beingDestroyed = true;
313     
314     delete m_mainFrame;
315     
316     delete m_impl->page;
317     m_impl->page = 0;   
318 }
319
320 void wxWebView::Stop()
321 {
322     if (m_mainFrame)
323         m_mainFrame->Stop();
324 }
325
326 void wxWebView::Reload()
327 {
328     if (m_mainFrame)
329         m_mainFrame->Reload();
330 }
331
332 wxString wxWebView::GetPageSource()
333 {
334     if (m_mainFrame)
335         return m_mainFrame->GetPageSource();
336
337     return wxEmptyString;
338 }
339
340 void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl)
341 {
342     if (m_mainFrame)
343         m_mainFrame->SetPageSource(source, baseUrl);
344 }
345
346 wxString wxWebView::GetInnerText()
347 {
348     if (m_mainFrame)
349         return m_mainFrame->GetInnerText();
350         
351     return wxEmptyString;
352 }
353
354 wxString wxWebView::GetAsMarkup()
355 {
356     if (m_mainFrame)
357         return m_mainFrame->GetAsMarkup();
358         
359     return wxEmptyString;
360 }
361
362 wxString wxWebView::GetExternalRepresentation()
363 {
364     if (m_mainFrame)
365         return m_mainFrame->GetExternalRepresentation();
366         
367     return wxEmptyString;
368 }
369
370 void wxWebView::SetTransparent(bool transparent)
371 {
372     WebCore::Frame* frame = 0;
373     if (m_mainFrame)
374         frame = m_mainFrame->GetFrame();
375     
376     if (!frame || !frame->view())
377         return;
378
379     frame->view()->setTransparent(transparent);
380 }
381
382 bool wxWebView::IsTransparent() const
383 {
384     WebCore::Frame* frame = 0;
385     if (m_mainFrame)
386         frame = m_mainFrame->GetFrame();
387
388    if (!frame || !frame->view())
389         return false;
390
391     return frame->view()->isTransparent();
392 }
393
394 wxString wxWebView::RunScript(const wxString& javascript)
395 {
396     if (m_mainFrame)
397         return m_mainFrame->RunScript(javascript);
398     
399     return wxEmptyString;
400 }
401
402 void wxWebView::LoadURL(const wxString& url)
403 {
404     if (m_mainFrame)
405         m_mainFrame->LoadURL(url);
406 }
407
408 bool wxWebView::GoBack()
409 {
410     if (m_mainFrame)
411         return m_mainFrame->GoBack();
412
413     return false;
414 }
415
416 bool wxWebView::GoForward()
417 {
418     if (m_mainFrame)
419         return m_mainFrame->GoForward();
420
421     return false;
422 }
423
424 bool wxWebView::CanGoBack()
425 {
426     if (m_mainFrame)
427         return m_mainFrame->CanGoBack();
428
429     return false;
430 }
431
432 bool wxWebView::CanGoForward()
433 {
434     if (m_mainFrame)
435         return m_mainFrame->CanGoForward();
436
437     return false;
438 }
439
440 bool wxWebView::CanIncreaseTextSize() const
441 {
442     if (m_mainFrame)
443         return m_mainFrame->CanIncreaseTextSize();
444
445     return false;
446 }
447
448 void wxWebView::IncreaseTextSize()
449 {
450     if (m_mainFrame)
451         m_mainFrame->IncreaseTextSize();
452 }
453
454 bool wxWebView::CanDecreaseTextSize() const
455 {
456     if (m_mainFrame)
457         m_mainFrame->CanDecreaseTextSize();
458
459     return false;
460 }
461
462 void wxWebView::DecreaseTextSize()
463 {        
464     if (m_mainFrame)
465         m_mainFrame->DecreaseTextSize();
466 }
467
468 void wxWebView::MakeEditable(bool enable)
469 {
470     m_isEditable = enable;
471 }
472
473
474 /* 
475  * Event forwarding functions to send events down to WebCore.
476  */
477
478 void wxWebView::OnPaint(wxPaintEvent& event)
479 {
480     
481     if (m_beingDestroyed || !m_mainFrame)
482         return;
483     
484     WebCore::Frame* frame = m_mainFrame->GetFrame();
485     if (!frame || !frame->view())
486         return;
487     
488     wxAutoBufferedPaintDC dc(this);
489
490     if (IsShown() && frame->document()) {
491 #if USE(WXGC)
492         wxGCDC gcdc(dc);
493 #endif
494
495         if (dc.IsOk()) {
496             wxRect paintRect = GetUpdateRegion().GetBox();
497
498             WebCore::IntSize offset = frame->view()->scrollOffset();
499 #if USE(WXGC)
500             gcdc.SetDeviceOrigin(-offset.width(), -offset.height());
501 #endif
502             dc.SetDeviceOrigin(-offset.width(), -offset.height());
503             paintRect.Offset(offset.width(), offset.height());
504
505 #if USE(WXGC)
506             WebCore::GraphicsContext* gc = new WebCore::GraphicsContext(&gcdc);
507 #else
508             WebCore::GraphicsContext* gc = new WebCore::GraphicsContext((wxWindowDC*)&dc);
509 #endif
510             if (gc && frame->contentRenderer()) {
511                 if (frame->view()->needsLayout())
512                     frame->view()->layout();
513
514                 frame->view()->paintContents(gc, paintRect);
515             }
516             delete gc;
517         }
518     }
519 }
520
521 bool wxWebView::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
522 {
523     if (m_mainFrame)
524         return m_mainFrame->FindString(string, forward, caseSensitive, wrapSelection, startInSelection);
525
526     return false;
527 }
528
529 void wxWebView::OnSize(wxSizeEvent& event)
530
531     if (m_isInitialized && m_mainFrame) {
532         WebCore::Frame* frame = m_mainFrame->GetFrame();
533         frame->eventHandler()->sendResizeEvent();
534         frame->view()->layout();
535         frame->view()->adjustScrollbars();
536     }
537       
538     event.Skip();
539 }
540
541 void wxWebView::OnMouseEvents(wxMouseEvent& event)
542 {
543     event.Skip();
544     
545     if (!m_mainFrame)
546         return; 
547         
548     WebCore::Frame* frame = m_mainFrame->GetFrame();  
549     if (!frame || !frame->view())
550         return;
551     
552     wxPoint globalPoint = ClientToScreen(event.GetPosition());
553
554     wxEventType type = event.GetEventType();
555     
556     if (type == wxEVT_MOUSEWHEEL) {
557         WebCore::PlatformWheelEvent wkEvent(event, globalPoint);
558         frame->eventHandler()->handleWheelEvent(wkEvent);
559         return;
560     }
561     
562     WebCore::PlatformMouseEvent wkEvent(event, globalPoint);
563
564     if (type == wxEVT_LEFT_DOWN || type == wxEVT_MIDDLE_DOWN || type == wxEVT_RIGHT_DOWN || 
565                 type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK)
566         frame->eventHandler()->handleMousePressEvent(wkEvent);
567     
568     else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP)
569         frame->eventHandler()->handleMouseReleaseEvent(wkEvent);
570
571     else if (type == wxEVT_MOTION)
572         frame->eventHandler()->mouseMoved(wkEvent);
573 }
574
575 void wxWebView::OnContextMenuEvents(wxContextMenuEvent& event)
576 {
577     m_impl->page->contextMenuController()->clearContextMenu();
578     wxPoint localEventPoint = ScreenToClient(event.GetPosition());
579
580     if (!m_mainFrame)
581         return;
582         
583     WebCore::Frame* focusedFrame = m_mainFrame->GetFrame();
584     if (!focusedFrame->view())
585         return;
586
587     //Create WebCore mouse event from the wxContextMenuEvent
588     wxMouseEvent mouseEvent(wxEVT_RIGHT_DOWN);
589     mouseEvent.m_x = localEventPoint.x;
590     mouseEvent.m_y = localEventPoint.y;
591     WebCore::PlatformMouseEvent wkEvent(mouseEvent, event.GetPosition());
592
593     bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(wkEvent);
594     if (!handledEvent)
595         return;
596
597     WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
598     if (!coreMenu)
599         return;
600
601     WebCore::PlatformMenuDescription menuWx = coreMenu->platformDescription();
602     if (!menuWx)
603         return;
604
605     PopupMenu(menuWx, localEventPoint);
606 }
607
608 void wxWebView::OnMenuSelectEvents(wxCommandEvent& event)
609 {
610     WebCore::ContextMenuItem* item = WebCore::ContextMenu::itemWithId (event.GetId());
611     if (!item)
612         return;
613
614     m_impl->page->contextMenuController()->contextMenuItemSelected(item);
615     delete item;
616 }
617
618 bool wxWebView::CanCopy()
619 {
620     if (m_mainFrame)
621         return m_mainFrame->CanCopy();
622
623     return false;
624 }
625
626 void wxWebView::Copy()
627 {
628     if (m_mainFrame)
629         m_mainFrame->Copy();
630 }
631
632 bool wxWebView::CanCut()
633 {
634     if (m_mainFrame)
635         m_mainFrame->CanCut();
636
637     return false;
638 }
639
640 void wxWebView::Cut()
641 {
642     if (m_mainFrame)
643         m_mainFrame->Cut();
644 }
645
646 bool wxWebView::CanPaste()
647 {
648     if (m_mainFrame)
649         m_mainFrame->CanPaste();
650
651     return false;
652 }
653
654 void wxWebView::Paste()
655 {
656     if (m_mainFrame)
657         m_mainFrame->Paste();
658
659 }
660
661 void wxWebView::OnKeyEvents(wxKeyEvent& event)
662 {
663     WebCore::Frame* frame = 0;
664     if (m_mainFrame)
665         frame = m_mainFrame->GetFrame();
666         
667     if (frame && frame->view()) {
668         // WebCore doesn't handle these events itself, so we need to do
669         // it and not send the event down or else CTRL+C will erase the text
670         // and replace it with c.
671         if (event.CmdDown() && event.GetEventType() == wxEVT_KEY_UP) {
672             if (event.GetKeyCode() == static_cast<int>('C'))
673                 Copy();
674             else if (event.GetKeyCode() == static_cast<int>('X'))
675                 Cut();
676             else if (event.GetKeyCode() == static_cast<int>('V'))
677                 Paste();
678             else if (event.GetKeyCode() == static_cast<int>('Z')) {
679                 if (event.ShiftDown()) {
680                     if (m_mainFrame->CanRedo())
681                         m_mainFrame->Redo();
682                 }
683                 else {
684                     if (m_mainFrame->CanUndo())
685                         m_mainFrame->Undo();
686                 }
687             }
688         } else {    
689             WebCore::PlatformKeyboardEvent wkEvent(event);
690             if (wkEvent.type() == WebCore::PlatformKeyboardEvent::Char && wkEvent.altKey())
691                 frame->eventHandler()->handleAccessKey(wkEvent);
692             else
693                 frame->eventHandler()->keyEvent(wkEvent);
694         }
695     }
696     
697     // make sure we get the character event.
698     if (event.GetEventType() != wxEVT_CHAR)
699         event.Skip();
700 }
701
702 void wxWebView::OnSetFocus(wxFocusEvent& event)
703 {
704     WebCore::Frame* frame = 0;
705     if (m_mainFrame)
706         frame = m_mainFrame->GetFrame();
707         
708     if (frame) {
709         m_impl->page->focusController()->setActive(true);
710         frame->selection()->setFocused(true);
711     }
712
713     event.Skip();
714 }
715
716 void wxWebView::OnKillFocus(wxFocusEvent& event)
717 {
718     WebCore::Frame* frame = 0;
719     if (m_mainFrame)
720         frame = m_mainFrame->GetFrame();
721         
722     if (frame) {
723         m_impl->page->focusController()->setActive(false);
724         frame->selection()->setFocused(false);
725     }
726     event.Skip();
727 }
728
729 void wxWebView::OnActivate(wxActivateEvent& event)
730 {
731     if (m_impl->page)
732         m_impl->page->focusController()->setActive(event.GetActive());
733
734     event.Skip();
735 }
736
737 wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const
738 {
739     if (m_mainFrame)
740         return m_mainFrame->HitTest(pos);
741
742     return wxWebViewDOMElementInfo();
743 }
744