diff options
Diffstat (limited to 'WebKit/wx/WebView.cpp')
| -rw-r--r-- | WebKit/wx/WebView.cpp | 594 |
1 files changed, 594 insertions, 0 deletions
diff --git a/WebKit/wx/WebView.cpp b/WebKit/wx/WebView.cpp new file mode 100644 index 0000000..fb2164f --- /dev/null +++ b/WebKit/wx/WebView.cpp @@ -0,0 +1,594 @@ +/* + * Copyright (C) 2007 Kevin Ollivier All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "CString.h" +#include "Document.h" +#include "Element.h" +#include "Editor.h" +#include "EventHandler.h" +#include "FocusController.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameView.h" +#include "GraphicsContext.h" +#include "Logging.h" +#include "markup.h" +#include "Page.h" +#include "PlatformKeyboardEvent.h" +#include "PlatformMouseEvent.h" +#include "PlatformString.h" +#include "PlatformWheelEvent.h" +#include "RenderObject.h" +#include "RenderView.h" +#include "SelectionController.h" +#include "Settings.h" +#include "SubstituteData.h" + +#include "ChromeClientWx.h" +#include "ContextMenuClientWx.h" +#include "DragClientWx.h" +#include "EditorClientWx.h" +#include "FrameLoaderClientWx.h" +#include "InspectorClientWx.h" + +#include "ScriptController.h" +#include "JSDOMBinding.h" +#include <runtime/JSValue.h> +#include <kjs/ustring.h> + +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif + +#include "WebFrame.h" +#include "WebView.h" +#include "WebViewPrivate.h" + +#include <wx/defs.h> +#include <wx/dcbuffer.h> + +#if defined(_MSC_VER) +int rint(double val) +{ + return (int)(val < 0 ? val - 0.5 : val + 0.5); +} +#endif + +// ---------------------------------------------------------------------------- +// wxWebView Events +// ---------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent) + +DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD) + +wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win) +{ + SetEventType( wxEVT_WEBVIEW_LOAD); + SetEventObject( win ); + if (win) + SetId(win->GetId()); +} + +IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent) + +DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD) + +wxWebViewBeforeLoadEvent::wxWebViewBeforeLoadEvent(wxWindow* win) +{ + m_cancelled = false; + SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD); + SetEventObject(win); + if (win) + SetId(win->GetId()); +} + +IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent) + +DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW) + +wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win) +{ + SetEventType(wxEVT_WEBVIEW_NEW_WINDOW); + SetEventObject(win); + if (win) + SetId(win->GetId()); +} + +IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent) + +DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK) + +wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win) +{ + SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK); + SetEventObject(win); + if (win) + SetId(win->GetId()); +} + +IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent) + +DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE) + +wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win) +{ + SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE); + SetEventObject(win); + if (win) + SetId(win->GetId()); +} + +IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent) + +DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE) + +wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win) +{ + SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE); + SetEventObject(win); + if (win) + SetId(win->GetId()); +} + +//--------------------------------------------------------- +// DOM Element info data type +//--------------------------------------------------------- + +wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() : + m_domElement(NULL), + m_isSelected(false), + m_text(wxEmptyString), + m_imageSrc(wxEmptyString), + m_link(wxEmptyString) +{ +} + +BEGIN_EVENT_TABLE(wxWebView, wxWindow) + EVT_PAINT(wxWebView::OnPaint) + EVT_SIZE(wxWebView::OnSize) + EVT_MOUSE_EVENTS(wxWebView::OnMouseEvents) + EVT_KEY_DOWN(wxWebView::OnKeyEvents) + EVT_KEY_UP(wxWebView::OnKeyEvents) + EVT_CHAR(wxWebView::OnKeyEvents) + EVT_SET_FOCUS(wxWebView::OnSetFocus) + EVT_KILL_FOCUS(wxWebView::OnKillFocus) + EVT_ACTIVATE(wxWebView::OnActivate) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow) + +const wxChar* wxWebViewNameStr = wxT("webView"); + +wxWebView::wxWebView() : + m_textMagnifier(1.0), + m_isEditable(false), + m_isInitialized(false), + m_beingDestroyed(false), + m_title(wxEmptyString) +{ +} + +wxWebView::wxWebView(wxWindow* parent, int id, const wxPoint& position, + const wxSize& size, long style, const wxString& name) : + m_textMagnifier(1.0), + m_isEditable(false), + m_isInitialized(false), + m_beingDestroyed(false), + m_title(wxEmptyString) +{ + Create(parent, id, position, size, style, name); +} + +bool wxWebView::Create(wxWindow* parent, int id, const wxPoint& position, + const wxSize& size, long style, const wxString& name) +{ + if ( (style & wxBORDER_MASK) == 0) + style |= wxBORDER_NONE; + style |= wxHSCROLL | wxVSCROLL; + + if (!wxWindow::Create(parent, id, position, size, style, name)) + return false; + +// This is necessary because we are using SharedTimerWin.cpp on Windows, +// due to a problem with exceptions getting eaten when using the callback +// approach to timers (which wx itself uses). +#if __WXMSW__ + WebCore::Page::setInstanceHandle(wxGetInstance()); +#endif + + // this helps reduce flicker on platforms like MSW + SetBackgroundStyle(wxBG_STYLE_CUSTOM); + + m_impl = new WebViewPrivate(); + + WebCore::InitializeLoggingChannelsIfNecessary(); + WebCore::HTMLFrameOwnerElement* parentFrame = 0; + + WebCore::EditorClientWx* editorClient = new WebCore::EditorClientWx(); + m_impl->page = new WebCore::Page(new WebCore::ChromeClientWx(this), new WebCore::ContextMenuClientWx(), editorClient, new WebCore::DragClientWx(), new WebCore::InspectorClientWx()); + editorClient->setPage(m_impl->page); + + m_mainFrame = new wxWebFrame(this); + + // Default settings - we should have wxWebViewSettings class for this + // eventually + WebCore::Settings* settings = m_impl->page->settings(); + settings->setLoadsImagesAutomatically(true); + settings->setDefaultFixedFontSize(13); + settings->setDefaultFontSize(16); + settings->setSerifFontFamily("Times New Roman"); + settings->setFixedFontFamily("Courier New"); + settings->setSansSerifFontFamily("Arial"); + settings->setStandardFontFamily("Times New Roman"); + settings->setJavaScriptEnabled(true); + + m_isInitialized = true; + + return true; +} + +wxWebView::~wxWebView() +{ + m_beingDestroyed = true; + + delete m_mainFrame; + + delete m_impl->page; + m_impl->page = 0; +} + +void wxWebView::Stop() +{ + if (m_mainFrame) + m_mainFrame->Stop(); +} + +void wxWebView::Reload() +{ + if (m_mainFrame) + m_mainFrame->Reload(); +} + +wxString wxWebView::GetPageSource() +{ + if (m_mainFrame) + return m_mainFrame->GetPageSource(); + + return wxEmptyString; +} + +void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl) +{ + if (m_mainFrame) + m_mainFrame->SetPageSource(source, baseUrl); +} + +wxString wxWebView::GetInnerText() +{ + if (m_mainFrame) + return m_mainFrame->GetInnerText(); + + return wxEmptyString; +} + +wxString wxWebView::GetAsMarkup() +{ + if (m_mainFrame) + return m_mainFrame->GetAsMarkup(); + + return wxEmptyString; +} + +wxString wxWebView::GetExternalRepresentation() +{ + if (m_mainFrame) + return m_mainFrame->GetExternalRepresentation(); + + return wxEmptyString; +} + +wxString wxWebView::RunScript(const wxString& javascript) +{ + if (m_mainFrame) + return m_mainFrame->RunScript(javascript); + + return wxEmptyString; +} + +void wxWebView::LoadURL(const wxString& url) +{ + if (m_mainFrame) + m_mainFrame->LoadURL(url); +} + +bool wxWebView::GoBack() +{ + if (m_mainFrame) + return m_mainFrame->GoBack(); + + return false; +} + +bool wxWebView::GoForward() +{ + if (m_mainFrame) + return m_mainFrame->GoForward(); + + return false; +} + +bool wxWebView::CanGoBack() +{ + if (m_mainFrame) + return m_mainFrame->CanGoBack(); + + return false; +} + +bool wxWebView::CanGoForward() +{ + if (m_mainFrame) + return m_mainFrame->CanGoForward(); + + return false; +} + +bool wxWebView::CanIncreaseTextSize() const +{ + if (m_mainFrame) + return m_mainFrame->CanIncreaseTextSize(); + + return false; +} + +void wxWebView::IncreaseTextSize() +{ + if (m_mainFrame) + m_mainFrame->IncreaseTextSize(); +} + +bool wxWebView::CanDecreaseTextSize() const +{ + if (m_mainFrame) + m_mainFrame->CanDecreaseTextSize(); + + return false; +} + +void wxWebView::DecreaseTextSize() +{ + if (m_mainFrame) + m_mainFrame->DecreaseTextSize(); +} + +void wxWebView::MakeEditable(bool enable) +{ + m_isEditable = enable; +} + + +/* + * Event forwarding functions to send events down to WebCore. + */ + +void wxWebView::OnPaint(wxPaintEvent& event) +{ + + if (m_beingDestroyed || !m_mainFrame) + return; + + WebCore::Frame* frame = m_mainFrame->GetFrame(); + if (!frame || !frame->view()) + return; + + wxAutoBufferedPaintDC dc(this); + + if (IsShown() && frame->document()) { +#if USE(WXGC) + wxGCDC gcdc(dc); +#endif + + if (dc.IsOk()) { + wxRect paintRect = GetUpdateRegion().GetBox(); + + WebCore::IntSize offset = frame->view()->scrollOffset(); +#if USE(WXGC) + gcdc.SetDeviceOrigin(-offset.width(), -offset.height()); +#endif + dc.SetDeviceOrigin(-offset.width(), -offset.height()); + paintRect.Offset(offset.width(), offset.height()); + +#if USE(WXGC) + WebCore::GraphicsContext* gc = new WebCore::GraphicsContext(&gcdc); +#else + WebCore::GraphicsContext* gc = new WebCore::GraphicsContext((wxWindowDC*)&dc); +#endif + if (gc && frame->contentRenderer()) { + if (frame->view()->needsLayout()) + frame->view()->layout(); + + frame->view()->paintContents(gc, paintRect); + } + delete gc; + } + } +} + +void wxWebView::OnSize(wxSizeEvent& event) +{ + if (m_isInitialized && m_mainFrame) { + WebCore::Frame* frame = m_mainFrame->GetFrame(); + frame->sendResizeEvent(); + frame->view()->layout(); + frame->view()->adjustScrollbars(); + } + + event.Skip(); +} + +void wxWebView::OnMouseEvents(wxMouseEvent& event) +{ + event.Skip(); + + if (!m_mainFrame) + return; + + WebCore::Frame* frame = m_mainFrame->GetFrame(); + if (!frame || !frame->view()) + return; + + wxPoint globalPoint = ClientToScreen(event.GetPosition()); + + wxEventType type = event.GetEventType(); + + if (type == wxEVT_MOUSEWHEEL) { + WebCore::PlatformWheelEvent wkEvent(event, globalPoint); + frame->eventHandler()->handleWheelEvent(wkEvent); + return; + } + + WebCore::PlatformMouseEvent wkEvent(event, globalPoint); + + if (type == wxEVT_LEFT_DOWN || type == wxEVT_MIDDLE_DOWN || type == wxEVT_RIGHT_DOWN) + frame->eventHandler()->handleMousePressEvent(wkEvent); + + else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP || + type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK) + frame->eventHandler()->handleMouseReleaseEvent(wkEvent); + + else if (type == wxEVT_MOTION) + frame->eventHandler()->mouseMoved(wkEvent); +} + +bool wxWebView::CanCopy() +{ + if (m_mainFrame) + return m_mainFrame->CanCopy(); + + return false; +} + +void wxWebView::Copy() +{ + if (m_mainFrame) + m_mainFrame->Copy(); +} + +bool wxWebView::CanCut() +{ + if (m_mainFrame) + m_mainFrame->CanCut(); + + return false; +} + +void wxWebView::Cut() +{ + if (m_mainFrame) + m_mainFrame->Cut(); +} + +bool wxWebView::CanPaste() +{ + if (m_mainFrame) + m_mainFrame->CanPaste(); + + return false; +} + +void wxWebView::Paste() +{ + if (m_mainFrame) + m_mainFrame->Paste(); + +} + +void wxWebView::OnKeyEvents(wxKeyEvent& event) +{ + WebCore::Frame* frame = 0; + if (m_mainFrame) + frame = m_mainFrame->GetFrame(); + + if (frame && frame->view()) { + // WebCore doesn't handle these events itself, so we need to do + // it and not send the event down or else CTRL+C will erase the text + // and replace it with c. + if (event.CmdDown() && event.GetKeyCode() == static_cast<int>('C')) + Copy(); + else if (event.CmdDown() && event.GetKeyCode() == static_cast<int>('X')) + Cut(); + else if (event.CmdDown() && event.GetKeyCode() == static_cast<int>('V')) + Paste(); + else { + WebCore::PlatformKeyboardEvent wkEvent(event); + if (wkEvent.type() == WebCore::PlatformKeyboardEvent::Char && wkEvent.altKey()) + frame->eventHandler()->handleAccessKey(wkEvent); + else + frame->eventHandler()->keyEvent(wkEvent); + } + } + + // make sure we get the character event. + if (event.GetEventType() != wxEVT_CHAR) + event.Skip(); +} + +void wxWebView::OnSetFocus(wxFocusEvent& event) +{ + WebCore::Frame* frame = 0; + if (m_mainFrame) + frame = m_mainFrame->GetFrame(); + + if (frame) { + m_impl->page->focusController()->setActive(true); + frame->selection()->setFocused(true); + } + + event.Skip(); +} + +void wxWebView::OnKillFocus(wxFocusEvent& event) +{ + WebCore::Frame* frame = 0; + if (m_mainFrame) + frame = m_mainFrame->GetFrame(); + + if (frame) { + m_impl->page->focusController()->setActive(false); + frame->selection()->setFocused(false); + } + event.Skip(); +} + +void wxWebView::OnActivate(wxActivateEvent& event) +{ + if (m_impl->page) + m_impl->page->focusController()->setActive(event.GetActive()); + + event.Skip(); +} |
