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) 91int 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 101IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent) 102 103DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD) 104 105wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win) 106{ 107 SetEventType( wxEVT_WEBVIEW_LOAD); 108 SetEventObject( win ); 109 if (win) 110 SetId(win->GetId()); 111} 112 113IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent) 114 115DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD) 116 117wxWebViewBeforeLoadEvent::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 126IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent) 127 128DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW) 129 130wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win) 131{ 132 SetEventType(wxEVT_WEBVIEW_NEW_WINDOW); 133 SetEventObject(win); 134 if (win) 135 SetId(win->GetId()); 136} 137 138IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent) 139 140DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK) 141 142wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win) 143{ 144 SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK); 145 SetEventObject(win); 146 if (win) 147 SetId(win->GetId()); 148} 149 150IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent) 151 152DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE) 153 154wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win) 155{ 156 SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE); 157 SetEventObject(win); 158 if (win) 159 SetId(win->GetId()); 160} 161 162IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent, wxCommandEvent) 163 164DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT) 165 166wxWebViewAlertEvent::wxWebViewAlertEvent(wxWindow* win) 167{ 168 SetEventType(wxEVT_WEBVIEW_JS_ALERT); 169 SetEventObject(win); 170 if (win) 171 SetId(win->GetId()); 172} 173 174IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent, wxCommandEvent) 175 176DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM) 177 178wxWebViewConfirmEvent::wxWebViewConfirmEvent(wxWindow* win) 179{ 180 SetEventType(wxEVT_WEBVIEW_JS_CONFIRM); 181 SetEventObject(win); 182 if (win) 183 SetId(win->GetId()); 184} 185 186IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent, wxCommandEvent) 187 188DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT) 189 190wxWebViewPromptEvent::wxWebViewPromptEvent(wxWindow* win) 191{ 192 SetEventType(wxEVT_WEBVIEW_JS_PROMPT); 193 SetEventObject(win); 194 if (win) 195 SetId(win->GetId()); 196} 197 198IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent) 199 200DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE) 201 202wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win) 203{ 204 SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE); 205 SetEventObject(win); 206 if (win) 207 SetId(win->GetId()); 208} 209 210IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent, wxCommandEvent) 211 212DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED) 213 214wxWebViewWindowObjectClearedEvent::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 227wxWebViewDOMElementInfo::wxWebViewDOMElementInfo() : 228 m_domElement(NULL), 229 m_isSelected(false), 230 m_text(wxEmptyString), 231 m_imageSrc(wxEmptyString), 232 m_link(wxEmptyString) 233{ 234} 235 236static wxWebViewCachePolicy gs_cachePolicy; 237 238/* static */ 239void 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 */ 251wxWebViewCachePolicy wxWebView::GetCachePolicy() 252{ 253 return gs_cachePolicy; 254} 255 256BEGIN_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) 266END_EVENT_TABLE() 267 268IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow) 269 270const wxChar* wxWebViewNameStr = wxT("webView"); 271 272wxWebView::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 282wxWebView::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 294bool 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 347wxWebView::~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 361void wxWebView::Stop() 362{ 363 if (m_mainFrame) 364 m_mainFrame->Stop(); 365} 366 367void wxWebView::Reload() 368{ 369 if (m_mainFrame) 370 m_mainFrame->Reload(); 371} 372 373wxString wxWebView::GetPageSource() 374{ 375 if (m_mainFrame) 376 return m_mainFrame->GetPageSource(); 377 378 return wxEmptyString; 379} 380 381void wxWebView::SetPageSource(const wxString& source, const wxString& baseUrl) 382{ 383 if (m_mainFrame) 384 m_mainFrame->SetPageSource(source, baseUrl); 385} 386 387wxString wxWebView::GetInnerText() 388{ 389 if (m_mainFrame) 390 return m_mainFrame->GetInnerText(); 391 392 return wxEmptyString; 393} 394 395wxString wxWebView::GetAsMarkup() 396{ 397 if (m_mainFrame) 398 return m_mainFrame->GetAsMarkup(); 399 400 return wxEmptyString; 401} 402 403wxString wxWebView::GetExternalRepresentation() 404{ 405 if (m_mainFrame) 406 return m_mainFrame->GetExternalRepresentation(); 407 408 return wxEmptyString; 409} 410 411void 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 423bool 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 435wxString wxWebView::RunScript(const wxString& javascript) 436{ 437 if (m_mainFrame) 438 return m_mainFrame->RunScript(javascript); 439 440 return wxEmptyString; 441} 442 443void wxWebView::LoadURL(const wxString& url) 444{ 445 if (m_mainFrame) 446 m_mainFrame->LoadURL(url); 447} 448 449bool wxWebView::GoBack() 450{ 451 if (m_mainFrame) 452 return m_mainFrame->GoBack(); 453 454 return false; 455} 456 457bool wxWebView::GoForward() 458{ 459 if (m_mainFrame) 460 return m_mainFrame->GoForward(); 461 462 return false; 463} 464 465bool wxWebView::CanGoBack() 466{ 467 if (m_mainFrame) 468 return m_mainFrame->CanGoBack(); 469 470 return false; 471} 472 473bool wxWebView::CanGoForward() 474{ 475 if (m_mainFrame) 476 return m_mainFrame->CanGoForward(); 477 478 return false; 479} 480 481bool wxWebView::CanIncreaseTextSize() const 482{ 483 if (m_mainFrame) 484 return m_mainFrame->CanIncreaseTextSize(); 485 486 return false; 487} 488 489void wxWebView::IncreaseTextSize() 490{ 491 if (m_mainFrame) 492 m_mainFrame->IncreaseTextSize(); 493} 494 495bool wxWebView::CanDecreaseTextSize() const 496{ 497 if (m_mainFrame) 498 m_mainFrame->CanDecreaseTextSize(); 499 500 return false; 501} 502 503void wxWebView::DecreaseTextSize() 504{ 505 if (m_mainFrame) 506 m_mainFrame->DecreaseTextSize(); 507} 508 509void wxWebView::ResetTextSize() 510{ 511 if (m_mainFrame) 512 m_mainFrame->ResetTextSize(); 513} 514 515void 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 525void 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 564bool 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 572void 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 584static int getDoubleClickTime() 585{ 586#if __WXMSW__ 587 return ::GetDoubleClickTime(); 588#else 589 return 500; 590#endif 591} 592 593void 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 650void 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 686void 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 702bool wxWebView::CanCopy() 703{ 704 if (m_mainFrame) 705 return m_mainFrame->CanCopy(); 706 707 return false; 708} 709 710void wxWebView::Copy() 711{ 712 if (m_mainFrame) 713 m_mainFrame->Copy(); 714} 715 716bool wxWebView::CanCut() 717{ 718 if (m_mainFrame) 719 return m_mainFrame->CanCut(); 720 721 return false; 722} 723 724void wxWebView::Cut() 725{ 726 if (m_mainFrame) 727 m_mainFrame->Cut(); 728} 729 730bool wxWebView::CanPaste() 731{ 732 if (m_mainFrame) 733 return m_mainFrame->CanPaste(); 734 735 return false; 736} 737 738void wxWebView::Paste() 739{ 740 if (m_mainFrame) 741 m_mainFrame->Paste(); 742} 743 744void 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 882void 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 895void 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 907wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const 908{ 909 if (m_mainFrame) 910 return m_mainFrame->HitTest(pos); 911 912 return wxWebViewDOMElementInfo(); 913} 914 915bool wxWebView::ShouldClose() const 916{ 917 if (m_mainFrame) 918 return m_mainFrame->ShouldClose(); 919 920 return true; 921} 922 923/* static */ 924void wxWebView::SetDatabaseDirectory(const wxString& databaseDirectory) 925{ 926#if ENABLE(DATABASE) 927 WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(databaseDirectory); 928#endif 929} 930 931/* static */ 932wxString wxWebView::GetDatabaseDirectory() 933{ 934#if ENABLE(DATABASE) 935 return WebCore::DatabaseTracker::tracker().databaseDirectoryPath(); 936#else 937 return wxEmptyString; 938#endif 939} 940 941static 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 */ 956void 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 967wxWebSettings 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 976wxWebKitParseMode wxWebView::GetParseMode() const 977{ 978 if (m_mainFrame) 979 return m_mainFrame->GetParseMode(); 980 981 return NoDocument; 982}