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)
rint(double val)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent,wxCommandEvent)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
IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent,wxCommandEvent)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
wxWebViewDOMElementInfo()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 */
SetCachePolicy(const wxWebViewCachePolicy & cachePolicy)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 */
GetCachePolicy()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
wxWebView()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
wxWebView(wxWindow * parent,int id,const wxPoint & position,const wxSize & size,long style,const wxString & name)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
Create(wxWindow * parent,int id,const wxPoint & position,const wxSize & size,long style,const wxString & name)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
~wxWebView()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
Stop()361 void wxWebView::Stop()
362 {
363 if (m_mainFrame)
364 m_mainFrame->Stop();
365 }
366
Reload()367 void wxWebView::Reload()
368 {
369 if (m_mainFrame)
370 m_mainFrame->Reload();
371 }
372
GetPageSource()373 wxString wxWebView::GetPageSource()
374 {
375 if (m_mainFrame)
376 return m_mainFrame->GetPageSource();
377
378 return wxEmptyString;
379 }
380
SetPageSource(const wxString & source,const wxString & baseUrl)381 void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl)
382 {
383 if (m_mainFrame)
384 m_mainFrame->SetPageSource(source, baseUrl);
385 }
386
GetInnerText()387 wxString wxWebView::GetInnerText()
388 {
389 if (m_mainFrame)
390 return m_mainFrame->GetInnerText();
391
392 return wxEmptyString;
393 }
394
GetAsMarkup()395 wxString wxWebView::GetAsMarkup()
396 {
397 if (m_mainFrame)
398 return m_mainFrame->GetAsMarkup();
399
400 return wxEmptyString;
401 }
402
GetExternalRepresentation()403 wxString wxWebView::GetExternalRepresentation()
404 {
405 if (m_mainFrame)
406 return m_mainFrame->GetExternalRepresentation();
407
408 return wxEmptyString;
409 }
410
SetTransparent(bool transparent)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
IsTransparent() const423 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
RunScript(const wxString & javascript)435 wxString wxWebView::RunScript(const wxString& javascript)
436 {
437 if (m_mainFrame)
438 return m_mainFrame->RunScript(javascript);
439
440 return wxEmptyString;
441 }
442
LoadURL(const wxString & url)443 void wxWebView::LoadURL(const wxString& url)
444 {
445 if (m_mainFrame)
446 m_mainFrame->LoadURL(url);
447 }
448
GoBack()449 bool wxWebView::GoBack()
450 {
451 if (m_mainFrame)
452 return m_mainFrame->GoBack();
453
454 return false;
455 }
456
GoForward()457 bool wxWebView::GoForward()
458 {
459 if (m_mainFrame)
460 return m_mainFrame->GoForward();
461
462 return false;
463 }
464
CanGoBack()465 bool wxWebView::CanGoBack()
466 {
467 if (m_mainFrame)
468 return m_mainFrame->CanGoBack();
469
470 return false;
471 }
472
CanGoForward()473 bool wxWebView::CanGoForward()
474 {
475 if (m_mainFrame)
476 return m_mainFrame->CanGoForward();
477
478 return false;
479 }
480
CanIncreaseTextSize() const481 bool wxWebView::CanIncreaseTextSize() const
482 {
483 if (m_mainFrame)
484 return m_mainFrame->CanIncreaseTextSize();
485
486 return false;
487 }
488
IncreaseTextSize()489 void wxWebView::IncreaseTextSize()
490 {
491 if (m_mainFrame)
492 m_mainFrame->IncreaseTextSize();
493 }
494
CanDecreaseTextSize() const495 bool wxWebView::CanDecreaseTextSize() const
496 {
497 if (m_mainFrame)
498 m_mainFrame->CanDecreaseTextSize();
499
500 return false;
501 }
502
DecreaseTextSize()503 void wxWebView::DecreaseTextSize()
504 {
505 if (m_mainFrame)
506 m_mainFrame->DecreaseTextSize();
507 }
508
ResetTextSize()509 void wxWebView::ResetTextSize()
510 {
511 if (m_mainFrame)
512 m_mainFrame->ResetTextSize();
513 }
514
MakeEditable(bool enable)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
OnPaint(wxPaintEvent & event)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
FindString(const wxString & string,bool forward,bool caseSensitive,bool wrapSelection,bool startInSelection)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
OnSize(wxSizeEvent & event)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
getDoubleClickTime()584 static int getDoubleClickTime()
585 {
586 #if __WXMSW__
587 return ::GetDoubleClickTime();
588 #else
589 return 500;
590 #endif
591 }
592
OnMouseEvents(wxMouseEvent & event)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
OnContextMenuEvents(wxContextMenuEvent & event)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
OnMenuSelectEvents(wxCommandEvent & event)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
CanCopy()702 bool wxWebView::CanCopy()
703 {
704 if (m_mainFrame)
705 return m_mainFrame->CanCopy();
706
707 return false;
708 }
709
Copy()710 void wxWebView::Copy()
711 {
712 if (m_mainFrame)
713 m_mainFrame->Copy();
714 }
715
CanCut()716 bool wxWebView::CanCut()
717 {
718 if (m_mainFrame)
719 return m_mainFrame->CanCut();
720
721 return false;
722 }
723
Cut()724 void wxWebView::Cut()
725 {
726 if (m_mainFrame)
727 m_mainFrame->Cut();
728 }
729
CanPaste()730 bool wxWebView::CanPaste()
731 {
732 if (m_mainFrame)
733 return m_mainFrame->CanPaste();
734
735 return false;
736 }
737
Paste()738 void wxWebView::Paste()
739 {
740 if (m_mainFrame)
741 m_mainFrame->Paste();
742 }
743
OnKeyEvents(wxKeyEvent & event)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
OnSetFocus(wxFocusEvent & event)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
OnKillFocus(wxFocusEvent & event)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
HitTest(const wxPoint & pos) const907 wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const
908 {
909 if (m_mainFrame)
910 return m_mainFrame->HitTest(pos);
911
912 return wxWebViewDOMElementInfo();
913 }
914
ShouldClose() const915 bool wxWebView::ShouldClose() const
916 {
917 if (m_mainFrame)
918 return m_mainFrame->ShouldClose();
919
920 return true;
921 }
922
923 /* static */
SetDatabaseDirectory(const wxString & databaseDirectory)924 void wxWebView::SetDatabaseDirectory(const wxString& databaseDirectory)
925 {
926 #if ENABLE(DATABASE)
927 WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(databaseDirectory);
928 #endif
929 }
930
931 /* static */
GetDatabaseDirectory()932 wxString wxWebView::GetDatabaseDirectory()
933 {
934 #if ENABLE(DATABASE)
935 return WebCore::DatabaseTracker::tracker().databaseDirectoryPath();
936 #else
937 return wxEmptyString;
938 #endif
939 }
940
curlProxyType(wxProxyType type)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 */
SetProxyInfo(const wxString & host,unsigned long port,wxProxyType type,const wxString & username,const wxString & password)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
GetWebSettings()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
GetParseMode() const976 wxWebKitParseMode wxWebView::GetParseMode() const
977 {
978 if (m_mainFrame)
979 return m_mainFrame->GetParseMode();
980
981 return NoDocument;
982 }