2 * Copyright (C) 2007 Kevin Ollivier All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
31 #include "EventHandler.h"
32 #include "FocusController.h"
34 #include "FrameLoader.h"
35 #include "FrameView.h"
36 #include "GraphicsContext.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"
51 #include "SubstituteData.h"
53 #include "ChromeClientWx.h"
54 #include "ContextMenuClientWx.h"
55 #include "DragClientWx.h"
56 #include "EditorClientWx.h"
57 #include "FrameLoaderClientWx.h"
58 #include "InspectorClientWx.h"
60 #include "ScriptController.h"
61 #include "JSDOMBinding.h"
62 #include <runtime/JSValue.h>
63 #include <runtime/UString.h>
65 #include "wx/wxprec.h"
72 #include "WebViewPrivate.h"
75 #include <wx/dcbuffer.h>
76 #include <wx/dcgraph.h>
81 return (int)(val < 0 ? val - 0.5 : val + 0.5);
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent)
91 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD)
93 wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win)
95 SetEventType( wxEVT_WEBVIEW_LOAD);
96 SetEventObject( win );
101 IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent)
103 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD)
105 wxWebViewBeforeLoadEvent::wxWebViewBeforeLoadEvent(wxWindow* win)
108 SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD);
114 IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent)
116 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW)
118 wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win)
120 SetEventType(wxEVT_WEBVIEW_NEW_WINDOW);
126 IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent)
128 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK)
130 wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win)
132 SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK);
138 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent)
140 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE)
142 wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win)
144 SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE);
150 IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent, wxCommandEvent)
152 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT)
154 wxWebViewAlertEvent::wxWebViewAlertEvent(wxWindow* win)
156 SetEventType(wxEVT_WEBVIEW_JS_ALERT);
162 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent, wxCommandEvent)
164 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM)
166 wxWebViewConfirmEvent::wxWebViewConfirmEvent(wxWindow* win)
168 SetEventType(wxEVT_WEBVIEW_JS_CONFIRM);
174 IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent, wxCommandEvent)
176 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT)
178 wxWebViewPromptEvent::wxWebViewPromptEvent(wxWindow* win)
180 SetEventType(wxEVT_WEBVIEW_JS_PROMPT);
186 IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent)
188 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE)
190 wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win)
192 SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE);
198 IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent, wxCommandEvent)
200 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED)
202 wxWebViewWindowObjectClearedEvent::wxWebViewWindowObjectClearedEvent(wxWindow* win)
204 SetEventType(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED);
211 //---------------------------------------------------------
212 // DOM Element info data type
213 //---------------------------------------------------------
215 wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() :
218 m_text(wxEmptyString),
219 m_imageSrc(wxEmptyString),
220 m_link(wxEmptyString)
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)
238 IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow)
240 const wxChar* wxWebViewNameStr = wxT("webView");
242 wxWebView::wxWebView() :
243 m_textMagnifier(1.0),
245 m_isInitialized(false),
246 m_beingDestroyed(false),
247 m_title(wxEmptyString)
251 wxWebView::wxWebView(wxWindow* parent, int id, const wxPoint& position,
252 const wxSize& size, long style, const wxString& name) :
253 m_textMagnifier(1.0),
255 m_isInitialized(false),
256 m_beingDestroyed(false),
257 m_title(wxEmptyString)
259 Create(parent, id, position, size, style, name);
262 bool wxWebView::Create(wxWindow* parent, int id, const wxPoint& position,
263 const wxSize& size, long style, const wxString& name)
265 if ( (style & wxBORDER_MASK) == 0)
266 style |= wxBORDER_NONE;
267 style |= wxHSCROLL | wxVSCROLL;
269 if (!wxWindow::Create(parent, id, position, size, style, name))
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).
276 WebCore::Page::setInstanceHandle(wxGetInstance());
279 // this helps reduce flicker on platforms like MSW
280 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
282 m_impl = new WebViewPrivate();
284 WebCore::InitializeLoggingChannelsIfNecessary();
285 WebCore::HTMLFrameOwnerElement* parentFrame = 0;
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);
291 m_mainFrame = new wxWebFrame(this);
293 // Default settings - we should have wxWebViewSettings class for this
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);
305 m_isInitialized = true;
310 wxWebView::~wxWebView()
312 m_beingDestroyed = true;
320 void wxWebView::Stop()
326 void wxWebView::Reload()
329 m_mainFrame->Reload();
332 wxString wxWebView::GetPageSource()
335 return m_mainFrame->GetPageSource();
337 return wxEmptyString;
340 void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl)
343 m_mainFrame->SetPageSource(source, baseUrl);
346 wxString wxWebView::GetInnerText()
349 return m_mainFrame->GetInnerText();
351 return wxEmptyString;
354 wxString wxWebView::GetAsMarkup()
357 return m_mainFrame->GetAsMarkup();
359 return wxEmptyString;
362 wxString wxWebView::GetExternalRepresentation()
365 return m_mainFrame->GetExternalRepresentation();
367 return wxEmptyString;
370 void wxWebView::SetTransparent(bool transparent)
372 WebCore::Frame* frame = 0;
374 frame = m_mainFrame->GetFrame();
376 if (!frame || !frame->view())
379 frame->view()->setTransparent(transparent);
382 bool wxWebView::IsTransparent() const
384 WebCore::Frame* frame = 0;
386 frame = m_mainFrame->GetFrame();
388 if (!frame || !frame->view())
391 return frame->view()->isTransparent();
394 wxString wxWebView::RunScript(const wxString& javascript)
397 return m_mainFrame->RunScript(javascript);
399 return wxEmptyString;
402 void wxWebView::LoadURL(const wxString& url)
405 m_mainFrame->LoadURL(url);
408 bool wxWebView::GoBack()
411 return m_mainFrame->GoBack();
416 bool wxWebView::GoForward()
419 return m_mainFrame->GoForward();
424 bool wxWebView::CanGoBack()
427 return m_mainFrame->CanGoBack();
432 bool wxWebView::CanGoForward()
435 return m_mainFrame->CanGoForward();
440 bool wxWebView::CanIncreaseTextSize() const
443 return m_mainFrame->CanIncreaseTextSize();
448 void wxWebView::IncreaseTextSize()
451 m_mainFrame->IncreaseTextSize();
454 bool wxWebView::CanDecreaseTextSize() const
457 m_mainFrame->CanDecreaseTextSize();
462 void wxWebView::DecreaseTextSize()
465 m_mainFrame->DecreaseTextSize();
468 void wxWebView::MakeEditable(bool enable)
470 m_isEditable = enable;
475 * Event forwarding functions to send events down to WebCore.
478 void wxWebView::OnPaint(wxPaintEvent& event)
481 if (m_beingDestroyed || !m_mainFrame)
484 WebCore::Frame* frame = m_mainFrame->GetFrame();
485 if (!frame || !frame->view())
488 wxAutoBufferedPaintDC dc(this);
490 if (IsShown() && frame->document()) {
496 wxRect paintRect = GetUpdateRegion().GetBox();
498 WebCore::IntSize offset = frame->view()->scrollOffset();
500 gcdc.SetDeviceOrigin(-offset.width(), -offset.height());
502 dc.SetDeviceOrigin(-offset.width(), -offset.height());
503 paintRect.Offset(offset.width(), offset.height());
506 WebCore::GraphicsContext* gc = new WebCore::GraphicsContext(&gcdc);
508 WebCore::GraphicsContext* gc = new WebCore::GraphicsContext((wxWindowDC*)&dc);
510 if (gc && frame->contentRenderer()) {
511 if (frame->view()->needsLayout())
512 frame->view()->layout();
514 frame->view()->paintContents(gc, paintRect);
521 bool wxWebView::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
524 return m_mainFrame->FindString(string, forward, caseSensitive, wrapSelection, startInSelection);
529 void wxWebView::OnSize(wxSizeEvent& event)
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();
541 void wxWebView::OnMouseEvents(wxMouseEvent& event)
548 WebCore::Frame* frame = m_mainFrame->GetFrame();
549 if (!frame || !frame->view())
552 wxPoint globalPoint = ClientToScreen(event.GetPosition());
554 wxEventType type = event.GetEventType();
556 if (type == wxEVT_MOUSEWHEEL) {
557 WebCore::PlatformWheelEvent wkEvent(event, globalPoint);
558 frame->eventHandler()->handleWheelEvent(wkEvent);
562 WebCore::PlatformMouseEvent wkEvent(event, globalPoint);
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);
568 else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP)
569 frame->eventHandler()->handleMouseReleaseEvent(wkEvent);
571 else if (type == wxEVT_MOTION)
572 frame->eventHandler()->mouseMoved(wkEvent);
575 void wxWebView::OnContextMenuEvents(wxContextMenuEvent& event)
577 m_impl->page->contextMenuController()->clearContextMenu();
578 wxPoint localEventPoint = ScreenToClient(event.GetPosition());
583 WebCore::Frame* focusedFrame = m_mainFrame->GetFrame();
584 if (!focusedFrame->view())
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());
593 bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(wkEvent);
597 WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu();
601 WebCore::PlatformMenuDescription menuWx = coreMenu->platformDescription();
605 PopupMenu(menuWx, localEventPoint);
608 void wxWebView::OnMenuSelectEvents(wxCommandEvent& event)
610 WebCore::ContextMenuItem* item = WebCore::ContextMenu::itemWithId (event.GetId());
614 m_impl->page->contextMenuController()->contextMenuItemSelected(item);
618 bool wxWebView::CanCopy()
621 return m_mainFrame->CanCopy();
626 void wxWebView::Copy()
632 bool wxWebView::CanCut()
635 m_mainFrame->CanCut();
640 void wxWebView::Cut()
646 bool wxWebView::CanPaste()
649 m_mainFrame->CanPaste();
654 void wxWebView::Paste()
657 m_mainFrame->Paste();
661 void wxWebView::OnKeyEvents(wxKeyEvent& event)
663 WebCore::Frame* frame = 0;
665 frame = m_mainFrame->GetFrame();
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'))
674 else if (event.GetKeyCode() == static_cast<int>('X'))
676 else if (event.GetKeyCode() == static_cast<int>('V'))
678 else if (event.GetKeyCode() == static_cast<int>('Z')) {
679 if (event.ShiftDown()) {
680 if (m_mainFrame->CanRedo())
684 if (m_mainFrame->CanUndo())
689 WebCore::PlatformKeyboardEvent wkEvent(event);
690 if (wkEvent.type() == WebCore::PlatformKeyboardEvent::Char && wkEvent.altKey())
691 frame->eventHandler()->handleAccessKey(wkEvent);
693 frame->eventHandler()->keyEvent(wkEvent);
697 // make sure we get the character event.
698 if (event.GetEventType() != wxEVT_CHAR)
702 void wxWebView::OnSetFocus(wxFocusEvent& event)
704 WebCore::Frame* frame = 0;
706 frame = m_mainFrame->GetFrame();
709 m_impl->page->focusController()->setActive(true);
710 frame->selection()->setFocused(true);
716 void wxWebView::OnKillFocus(wxFocusEvent& event)
718 WebCore::Frame* frame = 0;
720 frame = m_mainFrame->GetFrame();
723 m_impl->page->focusController()->setActive(false);
724 frame->selection()->setFocused(false);
729 void wxWebView::OnActivate(wxActivateEvent& event)
732 m_impl->page->focusController()->setActive(event.GetActive());
737 wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const
740 return m_mainFrame->HitTest(pos);
742 return wxWebViewDOMElementInfo();