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 "PlatformKeyboardEvent.h"
41 #include "PlatformMouseEvent.h"
42 #include "PlatformString.h"
43 #include "PlatformWheelEvent.h"
44 #include "RenderObject.h"
45 #include "RenderView.h"
46 #include "SelectionController.h"
48 #include "SubstituteData.h"
50 #include "ChromeClientWx.h"
51 #include "ContextMenuClientWx.h"
52 #include "DragClientWx.h"
53 #include "EditorClientWx.h"
54 #include "FrameLoaderClientWx.h"
55 #include "InspectorClientWx.h"
57 #include "ScriptController.h"
58 #include "JSDOMBinding.h"
59 #include <kjs/JSValue.h>
60 #include <kjs/ustring.h>
62 #include "wx/wxprec.h"
69 #include "WebViewPrivate.h"
72 #include <wx/dcbuffer.h>
77 return (int)(val < 0 ? val - 0.5 : val + 0.5);
81 // ----------------------------------------------------------------------------
83 // ----------------------------------------------------------------------------
85 IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent)
87 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD)
89 wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win)
91 SetEventType( wxEVT_WEBVIEW_LOAD);
92 SetEventObject( win );
97 IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent)
99 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD)
101 wxWebViewBeforeLoadEvent::wxWebViewBeforeLoadEvent(wxWindow* win)
104 SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD);
110 IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent)
112 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW)
114 wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win)
116 SetEventType(wxEVT_WEBVIEW_NEW_WINDOW);
122 IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent)
124 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK)
126 wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win)
128 SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK);
134 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent)
136 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE)
138 wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win)
140 SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE);
146 IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent)
148 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE)
150 wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win)
152 SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE);
158 //---------------------------------------------------------
159 // DOM Element info data type
160 //---------------------------------------------------------
162 wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() :
165 m_text(wxEmptyString),
166 m_imageSrc(wxEmptyString),
167 m_link(wxEmptyString)
171 BEGIN_EVENT_TABLE(wxWebView, wxWindow)
172 EVT_PAINT(wxWebView::OnPaint)
173 EVT_SIZE(wxWebView::OnSize)
174 EVT_MOUSE_EVENTS(wxWebView::OnMouseEvents)
175 EVT_KEY_DOWN(wxWebView::OnKeyEvents)
176 EVT_KEY_UP(wxWebView::OnKeyEvents)
177 EVT_CHAR(wxWebView::OnKeyEvents)
178 EVT_SET_FOCUS(wxWebView::OnSetFocus)
179 EVT_KILL_FOCUS(wxWebView::OnKillFocus)
180 EVT_ACTIVATE(wxWebView::OnActivate)
183 IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow)
185 const wxChar* wxWebViewNameStr = wxT("webView");
187 wxWebView::wxWebView() :
188 m_textMagnifier(1.0),
190 m_isInitialized(false),
191 m_beingDestroyed(false),
192 m_title(wxEmptyString)
196 wxWebView::wxWebView(wxWindow* parent, int id, const wxPoint& position,
197 const wxSize& size, long style, const wxString& name) :
198 m_textMagnifier(1.0),
200 m_isInitialized(false),
201 m_beingDestroyed(false),
202 m_title(wxEmptyString)
204 Create(parent, id, position, size, style, name);
207 bool wxWebView::Create(wxWindow* parent, int id, const wxPoint& position,
208 const wxSize& size, long style, const wxString& name)
210 if ( (style & wxBORDER_MASK) == 0)
211 style |= wxBORDER_NONE;
212 style |= wxHSCROLL | wxVSCROLL;
214 if (!wxWindow::Create(parent, id, position, size, style, name))
217 // This is necessary because we are using SharedTimerWin.cpp on Windows,
218 // due to a problem with exceptions getting eaten when using the callback
219 // approach to timers (which wx itself uses).
221 WebCore::Page::setInstanceHandle(wxGetInstance());
224 // this helps reduce flicker on platforms like MSW
225 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
227 m_impl = new WebViewPrivate();
229 WebCore::InitializeLoggingChannelsIfNecessary();
230 WebCore::HTMLFrameOwnerElement* parentFrame = 0;
232 WebCore::EditorClientWx* editorClient = new WebCore::EditorClientWx();
233 m_impl->page = new WebCore::Page(new WebCore::ChromeClientWx(this), new WebCore::ContextMenuClientWx(), editorClient, new WebCore::DragClientWx(), new WebCore::InspectorClientWx());
234 editorClient->setPage(m_impl->page);
236 m_mainFrame = new wxWebFrame(this);
238 // Default settings - we should have wxWebViewSettings class for this
240 WebCore::Settings* settings = m_impl->page->settings();
241 settings->setLoadsImagesAutomatically(true);
242 settings->setDefaultFixedFontSize(13);
243 settings->setDefaultFontSize(16);
244 settings->setSerifFontFamily("Times New Roman");
245 settings->setFixedFontFamily("Courier New");
246 settings->setSansSerifFontFamily("Arial");
247 settings->setStandardFontFamily("Times New Roman");
248 settings->setJavaScriptEnabled(true);
250 m_isInitialized = true;
255 wxWebView::~wxWebView()
257 m_beingDestroyed = true;
265 void wxWebView::Stop()
271 void wxWebView::Reload()
274 m_mainFrame->Reload();
277 wxString wxWebView::GetPageSource()
280 return m_mainFrame->GetPageSource();
282 return wxEmptyString;
285 void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl)
288 m_mainFrame->SetPageSource(source, baseUrl);
291 wxString wxWebView::GetInnerText()
294 return m_mainFrame->GetInnerText();
296 return wxEmptyString;
299 wxString wxWebView::GetAsMarkup()
302 return m_mainFrame->GetAsMarkup();
304 return wxEmptyString;
307 wxString wxWebView::GetExternalRepresentation()
310 return m_mainFrame->GetExternalRepresentation();
312 return wxEmptyString;
315 wxString wxWebView::RunScript(const wxString& javascript)
318 return m_mainFrame->RunScript(javascript);
320 return wxEmptyString;
323 void wxWebView::LoadURL(const wxString& url)
326 m_mainFrame->LoadURL(url);
329 bool wxWebView::GoBack()
332 return m_mainFrame->GoBack();
337 bool wxWebView::GoForward()
340 return m_mainFrame->GoForward();
345 bool wxWebView::CanGoBack()
348 return m_mainFrame->CanGoBack();
353 bool wxWebView::CanGoForward()
356 return m_mainFrame->CanGoForward();
361 bool wxWebView::CanIncreaseTextSize() const
364 return m_mainFrame->CanIncreaseTextSize();
369 void wxWebView::IncreaseTextSize()
372 m_mainFrame->IncreaseTextSize();
375 bool wxWebView::CanDecreaseTextSize() const
378 m_mainFrame->CanDecreaseTextSize();
383 void wxWebView::DecreaseTextSize()
386 m_mainFrame->DecreaseTextSize();
389 void wxWebView::MakeEditable(bool enable)
391 m_isEditable = enable;
396 * Event forwarding functions to send events down to WebCore.
399 void wxWebView::OnPaint(wxPaintEvent& event)
402 if (m_beingDestroyed || !m_mainFrame)
405 WebCore::Frame* frame = m_mainFrame->GetFrame();
406 if (!frame || !frame->view())
409 wxAutoBufferedPaintDC dc(this);
411 if (IsShown() && frame->document()) {
417 wxRect paintRect = GetUpdateRegion().GetBox();
419 WebCore::IntSize offset = frame->view()->scrollOffset();
421 gcdc.SetDeviceOrigin(-offset.width(), -offset.height());
423 dc.SetDeviceOrigin(-offset.width(), -offset.height());
424 paintRect.Offset(offset.width(), offset.height());
427 WebCore::GraphicsContext* gc = new WebCore::GraphicsContext(&gcdc);
429 WebCore::GraphicsContext* gc = new WebCore::GraphicsContext((wxWindowDC*)&dc);
431 if (gc && frame->contentRenderer()) {
432 if (frame->view()->needsLayout())
433 frame->view()->layout();
435 frame->paint(gc, paintRect);
441 void wxWebView::OnSize(wxSizeEvent& event)
443 if (m_isInitialized && m_mainFrame) {
444 WebCore::Frame* frame = m_mainFrame->GetFrame();
445 frame->sendResizeEvent();
446 frame->view()->layout();
452 void wxWebView::OnMouseEvents(wxMouseEvent& event)
459 WebCore::Frame* frame = m_mainFrame->GetFrame();
460 if (!frame || !frame->view())
463 wxPoint globalPoint = ClientToScreen(event.GetPosition());
465 wxEventType type = event.GetEventType();
467 if (type == wxEVT_MOUSEWHEEL) {
468 WebCore::PlatformWheelEvent wkEvent(event, globalPoint);
469 frame->eventHandler()->handleWheelEvent(wkEvent);
473 WebCore::PlatformMouseEvent wkEvent(event, globalPoint);
475 if (type == wxEVT_LEFT_DOWN || type == wxEVT_MIDDLE_DOWN || type == wxEVT_RIGHT_DOWN)
476 frame->eventHandler()->handleMousePressEvent(wkEvent);
478 else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP ||
479 type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK)
480 frame->eventHandler()->handleMouseReleaseEvent(wkEvent);
482 else if (type == wxEVT_MOTION)
483 frame->eventHandler()->mouseMoved(wkEvent);
486 bool wxWebView::CanCopy()
489 return m_mainFrame->CanCopy();
494 void wxWebView::Copy()
500 bool wxWebView::CanCut()
503 m_mainFrame->CanCut();
508 void wxWebView::Cut()
514 bool wxWebView::CanPaste()
517 m_mainFrame->CanPaste();
522 void wxWebView::Paste()
525 m_mainFrame->Paste();
529 void wxWebView::OnKeyEvents(wxKeyEvent& event)
531 WebCore::Frame* frame = 0;
533 frame = m_mainFrame->GetFrame();
535 if (frame && frame->view()) {
536 // WebCore doesn't handle these events itself, so we need to do
537 // it and not send the event down or else CTRL+C will erase the text
538 // and replace it with c.
539 if (event.CmdDown() && event.GetKeyCode() == static_cast<int>('C'))
541 else if (event.CmdDown() && event.GetKeyCode() == static_cast<int>('X'))
543 else if (event.CmdDown() && event.GetKeyCode() == static_cast<int>('V'))
546 WebCore::PlatformKeyboardEvent wkEvent(event);
547 if (wkEvent.type() == WebCore::PlatformKeyboardEvent::Char && wkEvent.altKey())
548 frame->eventHandler()->handleAccessKey(wkEvent);
550 frame->eventHandler()->keyEvent(wkEvent);
554 // make sure we get the character event.
555 if (event.GetEventType() != wxEVT_CHAR)
559 void wxWebView::OnSetFocus(wxFocusEvent& event)
561 WebCore::Frame* frame = 0;
563 frame = m_mainFrame->GetFrame();
566 frame->selection()->setFocused(true);
571 void wxWebView::OnKillFocus(wxFocusEvent& event)
573 WebCore::Frame* frame = 0;
575 frame = m_mainFrame->GetFrame();
578 frame->selection()->setFocused(false);
583 void wxWebView::OnActivate(wxActivateEvent& event)
586 m_impl->page->focusController()->setActive(event.GetActive());