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 "WebView.h" 28 29#include "ContextMenu.h" 30#include "ContextMenuController.h" 31#include "ContextMenuItem.h" 32#include "Document.h" 33#include "Editor.h" 34#include "Element.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 "MemoryCache.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#include "markup.h" 61#if __WXMSW__ 62#include "WebCoreInstanceHandle.h" 63#endif 64 65#include "ChromeClientWx.h" 66#include "ContextMenuClientWx.h" 67#include "DragClientWx.h" 68#include "EditorClientWx.h" 69#include "FrameLoaderClientWx.h" 70#include "InspectorClientWx.h" 71 72#include "ScriptController.h" 73#include "JSDOMBinding.h" 74#include <runtime/initializeThreading.h> 75#include <runtime/JSValue.h> 76#include <runtime/UString.h> 77#include <wtf/text/CString.h> 78 79#if ENABLE(DATABASE) 80#include "AbstractDatabase.h" 81#include "DatabaseTracker.h" 82#endif 83 84#include "wx/wxprec.h" 85#ifndef WX_PRECOMP 86 #include "wx/wx.h" 87#endif 88 89#include "WebDOMElement.h" 90#include "WebDOMNode.h" 91 92#include "WebFrame.h" 93#include "WebViewPrivate.h" 94 95#include <wx/defs.h> 96#include <wx/dcbuffer.h> 97#include <wx/dcgraph.h> 98 99#if defined(_MSC_VER) 100int rint(double val) 101{ 102 return (int)(val < 0 ? val - 0.5 : val + 0.5); 103} 104#endif 105 106// ---------------------------------------------------------------------------- 107// wxWebView Events 108// ---------------------------------------------------------------------------- 109 110IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent) 111 112DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD) 113 114wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win) 115{ 116 SetEventType( wxEVT_WEBVIEW_LOAD); 117 SetEventObject( win ); 118 if (win) 119 SetId(win->GetId()); 120} 121 122IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent) 123 124DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD) 125 126wxWebViewBeforeLoadEvent::wxWebViewBeforeLoadEvent(wxWindow* win) 127{ 128 m_cancelled = false; 129 SetEventType(wxEVT_WEBVIEW_BEFORE_LOAD); 130 SetEventObject(win); 131 if (win) 132 SetId(win->GetId()); 133} 134 135IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent) 136 137DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW) 138 139wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win) 140{ 141 SetEventType(wxEVT_WEBVIEW_NEW_WINDOW); 142 SetEventObject(win); 143 if (win) 144 SetId(win->GetId()); 145} 146 147IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent) 148 149DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK) 150 151wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win) 152{ 153 SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK); 154 SetEventObject(win); 155 if (win) 156 SetId(win->GetId()); 157} 158 159IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent) 160 161DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE) 162 163wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win) 164{ 165 SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE); 166 SetEventObject(win); 167 if (win) 168 SetId(win->GetId()); 169} 170 171IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent, wxCommandEvent) 172 173DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT) 174 175wxWebViewAlertEvent::wxWebViewAlertEvent(wxWindow* win) 176{ 177 SetEventType(wxEVT_WEBVIEW_JS_ALERT); 178 SetEventObject(win); 179 if (win) 180 SetId(win->GetId()); 181} 182 183IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent, wxCommandEvent) 184 185DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM) 186 187wxWebViewConfirmEvent::wxWebViewConfirmEvent(wxWindow* win) 188{ 189 SetEventType(wxEVT_WEBVIEW_JS_CONFIRM); 190 SetEventObject(win); 191 if (win) 192 SetId(win->GetId()); 193} 194 195IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent, wxCommandEvent) 196 197DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT) 198 199wxWebViewPromptEvent::wxWebViewPromptEvent(wxWindow* win) 200{ 201 SetEventType(wxEVT_WEBVIEW_JS_PROMPT); 202 SetEventObject(win); 203 if (win) 204 SetId(win->GetId()); 205} 206 207IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent) 208 209DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE) 210 211wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win) 212{ 213 SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE); 214 SetEventObject(win); 215 if (win) 216 SetId(win->GetId()); 217} 218 219IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent, wxCommandEvent) 220 221DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED) 222 223wxWebViewWindowObjectClearedEvent::wxWebViewWindowObjectClearedEvent(wxWindow* win) 224{ 225 SetEventType(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED); 226 SetEventObject(win); 227 if (win) 228 SetId(win->GetId()); 229} 230 231IMPLEMENT_DYNAMIC_CLASS(wxWebViewContentsChangedEvent, wxCommandEvent) 232 233DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONTENTS_CHANGED) 234 235wxWebViewContentsChangedEvent::wxWebViewContentsChangedEvent(wxWindow* win) 236{ 237 SetEventType(wxEVT_WEBVIEW_CONTENTS_CHANGED); 238 SetEventObject(win); 239 if (win) 240 SetId(win->GetId()); 241} 242 243IMPLEMENT_DYNAMIC_CLASS(wxWebViewSelectionChangedEvent, wxCommandEvent) 244 245DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_SELECTION_CHANGED) 246 247wxWebViewSelectionChangedEvent::wxWebViewSelectionChangedEvent(wxWindow* win) 248{ 249 SetEventType(wxEVT_WEBVIEW_SELECTION_CHANGED); 250 SetEventObject(win); 251 if (win) 252 SetId(win->GetId()); 253} 254 255//--------------------------------------------------------- 256// DOM Element info data type 257//--------------------------------------------------------- 258 259wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() : 260 m_isSelected(false), 261 m_text(wxEmptyString), 262 m_imageSrc(wxEmptyString), 263 m_link(wxEmptyString), 264 m_urlElement(NULL), 265 m_innerNode(NULL) 266{ 267} 268 269static wxWebViewCachePolicy gs_cachePolicy; 270 271/* static */ 272void wxWebView::SetCachePolicy(const wxWebViewCachePolicy& cachePolicy) 273{ 274 WebCore::MemoryCache* globalCache = WebCore::memoryCache(); 275 globalCache->setCapacities(cachePolicy.GetMinDeadCapacity(), 276 cachePolicy.GetMaxDeadCapacity(), 277 cachePolicy.GetCapacity()); 278 279 // store a copy since there is no getter for MemoryCache values 280 gs_cachePolicy = cachePolicy; 281} 282 283/* static */ 284wxWebViewCachePolicy wxWebView::GetCachePolicy() 285{ 286 return gs_cachePolicy; 287} 288 289wxWebViewDOMElementInfo::wxWebViewDOMElementInfo(const wxWebViewDOMElementInfo& other) 290{ 291 m_isSelected = other.m_isSelected; 292 m_text = other.m_text; 293 m_imageSrc = other.m_imageSrc; 294 m_link = other.m_link; 295 m_innerNode = other.m_innerNode; 296 m_urlElement = other.m_urlElement; 297} 298 299wxWebViewDOMElementInfo::~wxWebViewDOMElementInfo() 300{ 301 if (m_innerNode) 302 delete m_innerNode; 303 304 if (m_urlElement) 305 delete m_urlElement; 306} 307 308#if OS(DARWIN) 309// prototype - function is in WebSystemInterface.mm 310void InitWebCoreSystemInterface(void); 311#endif 312 313BEGIN_EVENT_TABLE(wxWebView, wxWindow) 314 EVT_PAINT(wxWebView::OnPaint) 315 EVT_SIZE(wxWebView::OnSize) 316 EVT_MOUSE_EVENTS(wxWebView::OnMouseEvents) 317 EVT_CONTEXT_MENU(wxWebView::OnContextMenuEvents) 318 EVT_KEY_DOWN(wxWebView::OnKeyEvents) 319 EVT_KEY_UP(wxWebView::OnKeyEvents) 320 EVT_CHAR(wxWebView::OnKeyEvents) 321 EVT_SET_FOCUS(wxWebView::OnSetFocus) 322 EVT_KILL_FOCUS(wxWebView::OnKillFocus) 323END_EVENT_TABLE() 324 325IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow) 326 327const wxChar* wxWebViewNameStr = wxT("webView"); 328 329wxWebView::wxWebView() : 330 m_textMagnifier(1.0), 331 m_isInitialized(false), 332 m_beingDestroyed(false), 333 m_mouseWheelZooms(false), 334 m_title(wxEmptyString) 335{ 336} 337 338wxWebView::wxWebView(wxWindow* parent, int id, const wxPoint& position, 339 const wxSize& size, long style, const wxString& name) : 340 m_textMagnifier(1.0), 341 m_isInitialized(false), 342 m_beingDestroyed(false), 343 m_mouseWheelZooms(false), 344 m_title(wxEmptyString) 345{ 346 Create(parent, id, position, size, style, name); 347} 348 349bool wxWebView::Create(wxWindow* parent, int id, const wxPoint& position, 350 const wxSize& size, long style, const wxString& name) 351{ 352#if OS(DARWIN) 353 InitWebCoreSystemInterface(); 354#endif 355 356 if ( (style & wxBORDER_MASK) == 0) 357 style |= wxBORDER_NONE; 358 359 if (!wxWindow::Create(parent, id, position, size, style, name)) 360 return false; 361 362 JSC::initializeThreading(); 363 WTF::initializeMainThread(); 364 365// This is necessary because we are using SharedTimerWin.cpp on Windows, 366// due to a problem with exceptions getting eaten when using the callback 367// approach to timers (which wx itself uses). 368#if __WXMSW__ 369 WebCore::setInstanceHandle(wxGetInstance()); 370#endif 371 372 // this helps reduce flicker on platforms like MSW 373 SetBackgroundStyle(wxBG_STYLE_CUSTOM); 374 375 m_impl = new WebViewPrivate(); 376 377 WebCore::InitializeLoggingChannelsIfNecessary(); 378 WebCore::HTMLFrameOwnerElement* parentFrame = 0; 379 380 WebCore::EditorClientWx* editorClient = new WebCore::EditorClientWx(); 381 382 WebCore::Page::PageClients pageClients; 383 pageClients.chromeClient = new WebCore::ChromeClientWx(this); 384 pageClients.contextMenuClient = new WebCore::ContextMenuClientWx(); 385 pageClients.editorClient = editorClient; 386 pageClients.dragClient = new WebCore::DragClientWx(); 387 pageClients.inspectorClient = new WebCore::InspectorClientWx(); 388 m_impl->page = new WebCore::Page(pageClients); 389 editorClient->setPage(m_impl->page); 390 391 m_mainFrame = new wxWebFrame(this); 392 393 // Default settings - we should have wxWebViewSettings class for this 394 // eventually 395 WebCore::Settings* settings = m_impl->page->settings(); 396 settings->setLoadsImagesAutomatically(true); 397 settings->setDefaultFixedFontSize(13); 398 settings->setDefaultFontSize(16); 399 settings->setSerifFontFamily("Times New Roman"); 400 settings->setFixedFontFamily("Courier New"); 401 settings->setSansSerifFontFamily("Arial"); 402 settings->setStandardFontFamily("Times New Roman"); 403 settings->setJavaScriptEnabled(true); 404 405#if ENABLE(DATABASE) 406 SetDatabasesEnabled(true); 407#endif 408 409 // we need to do this so that objects like the focusController are properly 410 // initialized so that the activate handler is run properly. 411 LoadURL(wxT("about:blank")); 412 413 m_isInitialized = true; 414 415 return true; 416} 417 418wxWebView::~wxWebView() 419{ 420 m_beingDestroyed = true; 421 422 while (HasCapture()) 423 ReleaseMouse(); 424 425 if (m_mainFrame && m_mainFrame->GetFrame()) 426 m_mainFrame->GetFrame()->loader()->detachFromParent(); 427 428 delete m_impl->page; 429 m_impl->page = 0; 430} 431 432// NOTE: binding to this event in the wxWebView constructor is too early in 433// some cases, but leave the event handler here so that users can bind to it 434// at a later time if they have activation state problems. 435void wxWebView::OnTLWActivated(wxActivateEvent& event) 436{ 437 if (m_impl && m_impl->page && m_impl->page->focusController()) 438 m_impl->page->focusController()->setActive(event.GetActive()); 439 440 event.Skip(); 441 442} 443 444void wxWebView::Stop() 445{ 446 if (m_mainFrame) 447 m_mainFrame->Stop(); 448} 449 450void wxWebView::Reload() 451{ 452 if (m_mainFrame) 453 m_mainFrame->Reload(); 454} 455 456wxString wxWebView::GetPageSource() 457{ 458 if (m_mainFrame) 459 return m_mainFrame->GetPageSource(); 460 461 return wxEmptyString; 462} 463 464void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl, const wxString& mimetype) 465{ 466 if (m_mainFrame) 467 m_mainFrame->SetPageSource(source, baseUrl, mimetype); 468} 469 470wxString wxWebView::GetInnerText() 471{ 472 if (m_mainFrame) 473 return m_mainFrame->GetInnerText(); 474 475 return wxEmptyString; 476} 477 478wxString wxWebView::GetAsMarkup() 479{ 480 if (m_mainFrame) 481 return m_mainFrame->GetAsMarkup(); 482 483 return wxEmptyString; 484} 485 486wxString wxWebView::GetExternalRepresentation() 487{ 488 if (m_mainFrame) 489 return m_mainFrame->GetExternalRepresentation(); 490 491 return wxEmptyString; 492} 493 494wxWebKitSelection wxWebView::GetSelection() 495{ 496 if (m_mainFrame) 497 return m_mainFrame->GetSelection(); 498 499 return 0; 500} 501 502wxString wxWebView::GetSelectionAsHTML() 503{ 504 if (m_mainFrame) 505 return m_mainFrame->GetSelectionAsHTML(); 506 507 return wxEmptyString; 508} 509 510wxString wxWebView::GetSelectionAsText() 511{ 512 if (m_mainFrame) 513 return m_mainFrame->GetSelectionAsText(); 514 515 return wxEmptyString; 516} 517 518void wxWebView::SetTransparent(bool transparent) 519{ 520 WebCore::Frame* frame = 0; 521 if (m_mainFrame) 522 frame = m_mainFrame->GetFrame(); 523 524 if (!frame || !frame->view()) 525 return; 526 527 frame->view()->setTransparent(transparent); 528} 529 530bool wxWebView::IsTransparent() const 531{ 532 WebCore::Frame* frame = 0; 533 if (m_mainFrame) 534 frame = m_mainFrame->GetFrame(); 535 536 if (!frame || !frame->view()) 537 return false; 538 539 return frame->view()->isTransparent(); 540} 541 542wxString wxWebView::RunScript(const wxString& javascript) 543{ 544 if (m_mainFrame) 545 return m_mainFrame->RunScript(javascript); 546 547 return wxEmptyString; 548} 549 550bool wxWebView::ExecuteEditCommand(const wxString& command, const wxString& parameter) 551{ 552 if (m_mainFrame) 553 return m_mainFrame->ExecuteEditCommand(command, parameter); 554} 555 556EditState wxWebView::GetEditCommandState(const wxString& command) const 557{ 558 if (m_mainFrame) 559 return m_mainFrame->GetEditCommandState(command); 560} 561 562wxString wxWebView::GetEditCommandValue(const wxString& command) const 563{ 564 if (m_mainFrame) 565 return m_mainFrame->GetEditCommandValue(command); 566 567 return wxEmptyString; 568} 569 570void wxWebView::LoadURL(const wxString& url) 571{ 572 if (m_mainFrame) 573 m_mainFrame->LoadURL(url); 574} 575 576bool wxWebView::GoBack() 577{ 578 if (m_mainFrame) 579 return m_mainFrame->GoBack(); 580 581 return false; 582} 583 584bool wxWebView::GoForward() 585{ 586 if (m_mainFrame) 587 return m_mainFrame->GoForward(); 588 589 return false; 590} 591 592bool wxWebView::CanGoBack() 593{ 594 if (m_mainFrame) 595 return m_mainFrame->CanGoBack(); 596 597 return false; 598} 599 600bool wxWebView::CanGoForward() 601{ 602 if (m_mainFrame) 603 return m_mainFrame->CanGoForward(); 604 605 return false; 606} 607 608bool wxWebView::CanIncreaseTextSize() const 609{ 610 if (m_mainFrame) 611 return m_mainFrame->CanIncreaseTextSize(); 612 613 return false; 614} 615 616void wxWebView::IncreaseTextSize() 617{ 618 if (m_mainFrame) 619 m_mainFrame->IncreaseTextSize(); 620} 621 622bool wxWebView::CanDecreaseTextSize() const 623{ 624 if (m_mainFrame) 625 m_mainFrame->CanDecreaseTextSize(); 626 627 return false; 628} 629 630void wxWebView::DecreaseTextSize() 631{ 632 if (m_mainFrame) 633 m_mainFrame->DecreaseTextSize(); 634} 635 636void wxWebView::ResetTextSize() 637{ 638 if (m_mainFrame) 639 m_mainFrame->ResetTextSize(); 640} 641 642void wxWebView::MakeEditable(bool enable) 643{ 644 if (m_mainFrame) 645 m_mainFrame->MakeEditable(enable); 646} 647 648bool wxWebView::IsEditable() const 649{ 650 if (m_mainFrame) 651 return m_mainFrame->IsEditable(); 652 653 return false; 654} 655 656 657 658/* 659 * Event forwarding functions to send events down to WebCore. 660 */ 661 662void wxWebView::OnPaint(wxPaintEvent& event) 663{ 664 if (m_beingDestroyed || !m_mainFrame) 665 return; 666 667 WebCore::Frame* frame = m_mainFrame->GetFrame(); 668 if (!frame || !frame->view()) 669 return; 670 671 wxAutoBufferedPaintDC dc(this); 672 673 if (IsShown() && frame->document()) { 674#if USE(WXGC) 675 wxGCDC gcdc(dc); 676#endif 677 678 if (dc.IsOk()) { 679 wxRect paintRect = GetUpdateRegion().GetBox(); 680 681#if USE(WXGC) 682 WebCore::GraphicsContext gc(&gcdc); 683#else 684 WebCore::GraphicsContext gc(&dc); 685#endif 686 if (frame->contentRenderer()) { 687 frame->view()->updateLayoutAndStyleIfNeededRecursive(); 688 frame->view()->paint(&gc, paintRect); 689 } 690 } 691 } 692} 693 694bool wxWebView::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection) 695{ 696 if (m_mainFrame) 697 return m_mainFrame->FindString(string, forward, caseSensitive, wrapSelection, startInSelection); 698 699 return false; 700} 701 702void wxWebView::OnSize(wxSizeEvent& event) 703{ 704 if (m_isInitialized && m_mainFrame) { 705 WebCore::Frame* frame = m_mainFrame->GetFrame(); 706 frame->view()->resize(event.GetSize()); 707 frame->view()->adjustViewSize(); 708 } 709 710 event.Skip(); 711} 712 713static int getDoubleClickTime() 714{ 715#if __WXMSW__ 716 return ::GetDoubleClickTime(); 717#else 718 return 500; 719#endif 720} 721 722void wxWebView::OnMouseEvents(wxMouseEvent& event) 723{ 724 event.Skip(); 725 726 if (!m_impl->page) 727 return; 728 729 WebCore::Frame* frame = m_mainFrame->GetFrame(); 730 if (!frame || !frame->view()) 731 return; 732 733 wxPoint globalPoint = ClientToScreen(event.GetPosition()); 734 735 wxEventType type = event.GetEventType(); 736 737 if (type == wxEVT_MOUSEWHEEL) { 738 if (m_mouseWheelZooms && event.ControlDown() && !event.AltDown() && !event.ShiftDown()) { 739 if (event.GetWheelRotation() < 0) 740 DecreaseTextSize(); 741 else if (event.GetWheelRotation() > 0) 742 IncreaseTextSize(); 743 } else { 744 WebCore::PlatformWheelEvent wkEvent(event, globalPoint); 745 frame->eventHandler()->handleWheelEvent(wkEvent); 746 } 747 748 return; 749 } 750 751 // If an event, such as a right-click event, leads to a focus change (e.g. it 752 // raises a dialog), WebKit never gets the mouse up event and never relinquishes 753 // mouse capture. This leads to WebKit handling mouse events, such as modifying 754 // the selection, while other controls or top level windows have the focus. 755 // I'm not sure if this is the right place to handle this, but I can't seem to 756 // find a precedent on how to handle this in other ports. 757 if (wxWindow::FindFocus() != this) { 758 while (HasCapture()) 759 ReleaseMouse(); 760 761 frame->eventHandler()->setMousePressed(false); 762 763 return; 764 } 765 766 int clickCount = event.ButtonDClick() ? 2 : 1; 767 768 if (clickCount == 1 && m_impl->tripleClickTimer.IsRunning()) { 769 wxPoint diff(event.GetPosition() - m_impl->tripleClickPos); 770 if (abs(diff.x) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_X) && 771 abs(diff.y) <= wxSystemSettings::GetMetric(wxSYS_DCLICK_Y)) { 772 clickCount = 3; 773 } 774 } else if (clickCount == 2) { 775 m_impl->tripleClickTimer.Start(getDoubleClickTime(), false); 776 m_impl->tripleClickPos = event.GetPosition(); 777 } 778 779 WebCore::PlatformMouseEvent wkEvent(event, globalPoint, clickCount); 780 781 if (type == wxEVT_LEFT_DOWN || type == wxEVT_MIDDLE_DOWN || type == wxEVT_RIGHT_DOWN || 782 type == wxEVT_LEFT_DCLICK || type == wxEVT_MIDDLE_DCLICK || type == wxEVT_RIGHT_DCLICK) { 783 frame->eventHandler()->handleMousePressEvent(wkEvent); 784 if (!HasCapture()) 785 CaptureMouse(); 786 } else if (type == wxEVT_LEFT_UP || type == wxEVT_MIDDLE_UP || type == wxEVT_RIGHT_UP) { 787 frame->eventHandler()->handleMouseReleaseEvent(wkEvent); 788 while (HasCapture()) 789 ReleaseMouse(); 790 } else if (type == wxEVT_MOTION || type == wxEVT_ENTER_WINDOW || type == wxEVT_LEAVE_WINDOW) 791 frame->eventHandler()->mouseMoved(wkEvent); 792} 793 794void wxWebView::OnContextMenuEvents(wxContextMenuEvent& event) 795{ 796 Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxWebView::OnMenuSelectEvents), NULL, this); 797 m_impl->page->contextMenuController()->clearContextMenu(); 798 wxPoint localEventPoint = ScreenToClient(event.GetPosition()); 799 800 if (!m_impl->page) 801 return; 802 803 WebCore::Frame* focusedFrame = m_impl->page->focusController()->focusedOrMainFrame(); 804 if (!focusedFrame->view()) 805 return; 806 807 //Create WebCore mouse event from the wxContextMenuEvent 808 wxMouseEvent mouseEvent(wxEVT_RIGHT_DOWN); 809 mouseEvent.m_x = localEventPoint.x; 810 mouseEvent.m_y = localEventPoint.y; 811 WebCore::PlatformMouseEvent wkEvent(mouseEvent, event.GetPosition(), 1); 812 813 bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(wkEvent); 814 if (!handledEvent) 815 return; 816 817 WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu(); 818 if (!coreMenu) 819 return; 820 821 WebCore::PlatformMenuDescription menuWx = coreMenu->platformDescription(); 822 if (!menuWx) 823 return; 824 825 PopupMenu(menuWx, localEventPoint); 826 827 Disconnect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxWebView::OnMenuSelectEvents), NULL, this); 828} 829 830void wxWebView::OnMenuSelectEvents(wxCommandEvent& event) 831{ 832 // we shouldn't hit this unless there's a context menu showing 833 WebCore::ContextMenu* coreMenu = m_impl->page->contextMenuController()->contextMenu(); 834 ASSERT(coreMenu); 835 if (!coreMenu) 836 return; 837 838 WebCore::ContextMenuItem* item = WebCore::ContextMenu::itemWithId (event.GetId()); 839 if (!item) 840 return; 841 842 m_impl->page->contextMenuController()->contextMenuItemSelected(item); 843 delete item; 844} 845 846bool wxWebView::CanCopy() 847{ 848 if (m_mainFrame) 849 return m_mainFrame->CanCopy(); 850 851 return false; 852} 853 854void wxWebView::Copy() 855{ 856 if (m_mainFrame) 857 m_mainFrame->Copy(); 858} 859 860bool wxWebView::CanCut() 861{ 862 if (m_mainFrame) 863 return m_mainFrame->CanCut(); 864 865 return false; 866} 867 868void wxWebView::Cut() 869{ 870 if (m_mainFrame) 871 m_mainFrame->Cut(); 872} 873 874bool wxWebView::CanPaste() 875{ 876 if (m_mainFrame) 877 return m_mainFrame->CanPaste(); 878 879 return false; 880} 881 882void wxWebView::Paste() 883{ 884 if (m_mainFrame) 885 m_mainFrame->Paste(); 886} 887 888void wxWebView::OnKeyEvents(wxKeyEvent& event) 889{ 890 WebCore::Frame* frame = 0; 891 if (m_impl->page) 892 frame = m_impl->page->focusController()->focusedOrMainFrame(); 893 894 if (!(frame && frame->view())) 895 return; 896 897 WebCore::PlatformKeyboardEvent wkEvent(event); 898 899 if (frame->eventHandler()->keyEvent(wkEvent)) 900 return; 901 902 //Some things WebKit won't do for us... Copy/Cut/Paste and KB scrolling 903 if (event.GetEventType() == wxEVT_KEY_DOWN) { 904 switch (event.GetKeyCode()) { 905 case 67: //"C" 906 if (CanCopy() && event.GetModifiers() == wxMOD_CMD) { 907 Copy(); 908 return; 909 } 910 break; 911 case 86: //"V" 912 if (CanPaste() && event.GetModifiers() == wxMOD_CMD) { 913 Paste(); 914 return; 915 } 916 break; 917 case 88: //"X" 918 if (CanCut() && event.GetModifiers() == wxMOD_CMD) { 919 Cut(); 920 return; 921 } 922 break; 923 case WXK_INSERT: 924 if (CanCopy() && event.GetModifiers() == wxMOD_CMD) { 925 Copy(); 926 return; 927 } 928 if (CanPaste() && event.GetModifiers() == wxMOD_SHIFT) { 929 Paste(); 930 return; 931 } 932 return; //Insert shall not become a char 933 case WXK_DELETE: 934 if (CanCut() && event.GetModifiers() == wxMOD_SHIFT) { 935 Cut(); 936 return; 937 } 938 break; 939 case WXK_LEFT: 940 case WXK_NUMPAD_LEFT: 941 frame->view()->scrollBy(WebCore::IntSize(-WebCore::Scrollbar::pixelsPerLineStep(), 0)); 942 return; 943 case WXK_UP: 944 case WXK_NUMPAD_UP: 945 frame->view()->scrollBy(WebCore::IntSize(0, -WebCore::Scrollbar::pixelsPerLineStep())); 946 return; 947 case WXK_RIGHT: 948 case WXK_NUMPAD_RIGHT: 949 frame->view()->scrollBy(WebCore::IntSize(WebCore::Scrollbar::pixelsPerLineStep(), 0)); 950 return; 951 case WXK_DOWN: 952 case WXK_NUMPAD_DOWN: 953 frame->view()->scrollBy(WebCore::IntSize(0, WebCore::Scrollbar::pixelsPerLineStep())); 954 return; 955 case WXK_END: 956 case WXK_NUMPAD_END: 957 frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), frame->view()->maximumScrollPosition().y())); 958 return; 959 case WXK_HOME: 960 case WXK_NUMPAD_HOME: 961 frame->view()->setScrollPosition(WebCore::IntPoint(frame->view()->scrollX(), 0)); 962 return; 963 case WXK_PAGEUP: 964 case WXK_NUMPAD_PAGEUP: 965 frame->view()->scrollBy(WebCore::IntSize(0, -frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging())); 966 return; 967 case WXK_PAGEDOWN: 968 case WXK_NUMPAD_PAGEDOWN: 969 frame->view()->scrollBy(WebCore::IntSize(0, frame->view()->visibleHeight() * WebCore::Scrollbar::minFractionToStepWhenPaging())); 970 return; 971 //These we don't want turning into char events, stuff 'em 972 case WXK_ESCAPE: 973 case WXK_LBUTTON: 974 case WXK_RBUTTON: 975 case WXK_CANCEL: 976 case WXK_MENU: 977 case WXK_MBUTTON: 978 case WXK_CLEAR: 979 case WXK_PAUSE: 980 case WXK_SELECT: 981 case WXK_PRINT: 982 case WXK_EXECUTE: 983 case WXK_SNAPSHOT: 984 case WXK_HELP: 985 case WXK_F1: 986 case WXK_F2: 987 case WXK_F3: 988 case WXK_F4: 989 case WXK_F5: 990 case WXK_F6: 991 case WXK_F7: 992 case WXK_F8: 993 case WXK_F9: 994 case WXK_F10: 995 case WXK_F11: 996 case WXK_F12: 997 case WXK_F13: 998 case WXK_F14: 999 case WXK_F15: 1000 case WXK_F16: 1001 case WXK_F17: 1002 case WXK_F18: 1003 case WXK_F19: 1004 case WXK_F20: 1005 case WXK_F21: 1006 case WXK_F22: 1007 case WXK_F23: 1008 case WXK_F24: 1009 case WXK_NUMPAD_F1: 1010 case WXK_NUMPAD_F2: 1011 case WXK_NUMPAD_F3: 1012 case WXK_NUMPAD_F4: 1013 //When numlock is off Numpad 5 becomes BEGIN, or HOME on Char 1014 case WXK_NUMPAD_BEGIN: 1015 case WXK_NUMPAD_INSERT: 1016 return; 1017 } 1018 } 1019 1020 event.Skip(); 1021} 1022 1023void wxWebView::OnSetFocus(wxFocusEvent& event) 1024{ 1025 if (m_impl && m_impl->page && m_impl->page->focusController()) { 1026 m_impl->page->focusController()->setFocused(true); 1027 m_impl->page->focusController()->setActive(true); 1028 1029 if (!m_impl->page->focusController()->focusedFrame() && m_mainFrame) 1030 m_impl->page->focusController()->setFocusedFrame(m_mainFrame->GetFrame()); 1031 } 1032 1033 event.Skip(); 1034} 1035 1036void wxWebView::OnKillFocus(wxFocusEvent& event) 1037{ 1038 if (m_impl && m_impl->page && m_impl->page->focusController()) { 1039 m_impl->page->focusController()->setFocused(false); 1040 1041 // We also handle active state in OnTLWActivated, but if a user does not 1042 // call event.Skip() in their own EVT_ACTIVATE handler, we won't get those 1043 // callbacks. So we handle active state here as well as a fallback. 1044 wxTopLevelWindow* tlw = dynamic_cast<wxTopLevelWindow*>(wxGetTopLevelParent(this)); 1045 if (tlw && tlw->IsActive()) 1046 m_impl->page->focusController()->setActive(true); 1047 else 1048 m_impl->page->focusController()->setActive(false); 1049 } 1050 1051 while (HasCapture()) 1052 ReleaseMouse(); 1053 1054 event.Skip(); 1055} 1056 1057wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const 1058{ 1059 if (m_mainFrame) 1060 return m_mainFrame->HitTest(pos); 1061 1062 return wxWebViewDOMElementInfo(); 1063} 1064 1065bool wxWebView::ShouldClose() const 1066{ 1067 if (m_mainFrame) 1068 return m_mainFrame->ShouldClose(); 1069 1070 return true; 1071} 1072 1073/* static */ 1074void wxWebView::SetDatabaseDirectory(const wxString& databaseDirectory) 1075{ 1076#if ENABLE(DATABASE) 1077 WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(databaseDirectory); 1078#endif 1079} 1080 1081/* static */ 1082wxString wxWebView::GetDatabaseDirectory() 1083{ 1084#if ENABLE(DATABASE) 1085 return WebCore::DatabaseTracker::tracker().databaseDirectoryPath(); 1086#else 1087 return wxEmptyString; 1088#endif 1089} 1090 1091/* static */ 1092void wxWebView::SetDatabasesEnabled(bool enabled) 1093{ 1094#if ENABLE(DATABASE) 1095 WebCore::AbstractDatabase::setIsAvailable(enabled); 1096#endif 1097} 1098 1099/* static */ 1100bool wxWebView::AreDatabasesEnabled() 1101{ 1102#if ENABLE(DATABASE) 1103 return WebCore::AbstractDatabase::isAvailable(); 1104#endif 1105 return false; 1106} 1107 1108static WebCore::ResourceHandleManager::ProxyType curlProxyType(wxProxyType type) 1109{ 1110 switch (type) { 1111 case HTTP: return WebCore::ResourceHandleManager::HTTP; 1112 case Socks4: return WebCore::ResourceHandleManager::Socks4; 1113 case Socks4A: return WebCore::ResourceHandleManager::Socks4A; 1114 case Socks5: return WebCore::ResourceHandleManager::Socks5; 1115 case Socks5Hostname: return WebCore::ResourceHandleManager::Socks5Hostname; 1116 default: 1117 ASSERT_NOT_REACHED(); 1118 return WebCore::ResourceHandleManager::HTTP; 1119 } 1120} 1121 1122/* static */ 1123void wxWebView::SetProxyInfo(const wxString& host, 1124 unsigned long port, 1125 wxProxyType type, 1126 const wxString& username, 1127 const wxString& password) 1128{ 1129 using WebCore::ResourceHandleManager; 1130 if (ResourceHandleManager* mgr = ResourceHandleManager::sharedInstance()) 1131 mgr->setProxyInfo(host, port, curlProxyType(type), username, password); 1132} 1133 1134wxWebSettings wxWebView::GetWebSettings() 1135{ 1136 ASSERT(m_impl->page); 1137 if (m_impl->page) 1138 return wxWebSettings(m_impl->page->settings()); 1139 1140 return wxWebSettings(); 1141} 1142 1143wxWebKitCompatibilityMode wxWebView::GetCompatibilityMode() const 1144{ 1145 if (m_mainFrame) 1146 return m_mainFrame->GetCompatibilityMode(); 1147 1148 return QuirksMode; 1149} 1150 1151void wxWebView::GrantUniversalAccess() 1152{ 1153 if (m_mainFrame) 1154 m_mainFrame->GrantUniversalAccess(); 1155} 1156