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