• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
rint(double val)100 int 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 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent,wxCommandEvent)110 IMPLEMENT_DYNAMIC_CLASS(wxWebViewLoadEvent, wxCommandEvent)
111 
112 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_LOAD)
113 
114 wxWebViewLoadEvent::wxWebViewLoadEvent(wxWindow* win)
115 {
116     SetEventType( wxEVT_WEBVIEW_LOAD);
117     SetEventObject( win );
118     if (win)
119         SetId(win->GetId());
120 }
121 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent,wxCommandEvent)122 IMPLEMENT_DYNAMIC_CLASS(wxWebViewBeforeLoadEvent, wxCommandEvent)
123 
124 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_BEFORE_LOAD)
125 
126 wxWebViewBeforeLoadEvent::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 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent,wxCommandEvent)135 IMPLEMENT_DYNAMIC_CLASS(wxWebViewNewWindowEvent, wxCommandEvent)
136 
137 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_NEW_WINDOW)
138 
139 wxWebViewNewWindowEvent::wxWebViewNewWindowEvent(wxWindow* win)
140 {
141     SetEventType(wxEVT_WEBVIEW_NEW_WINDOW);
142     SetEventObject(win);
143     if (win)
144         SetId(win->GetId());
145 }
146 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent,wxCommandEvent)147 IMPLEMENT_DYNAMIC_CLASS(wxWebViewRightClickEvent, wxCommandEvent)
148 
149 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RIGHT_CLICK)
150 
151 wxWebViewRightClickEvent::wxWebViewRightClickEvent(wxWindow* win)
152 {
153     SetEventType(wxEVT_WEBVIEW_RIGHT_CLICK);
154     SetEventObject(win);
155     if (win)
156         SetId(win->GetId());
157 }
158 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent,wxCommandEvent)159 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConsoleMessageEvent, wxCommandEvent)
160 
161 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONSOLE_MESSAGE)
162 
163 wxWebViewConsoleMessageEvent::wxWebViewConsoleMessageEvent(wxWindow* win)
164 {
165     SetEventType(wxEVT_WEBVIEW_CONSOLE_MESSAGE);
166     SetEventObject(win);
167     if (win)
168         SetId(win->GetId());
169 }
170 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent,wxCommandEvent)171 IMPLEMENT_DYNAMIC_CLASS(wxWebViewAlertEvent, wxCommandEvent)
172 
173 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_ALERT)
174 
175 wxWebViewAlertEvent::wxWebViewAlertEvent(wxWindow* win)
176 {
177     SetEventType(wxEVT_WEBVIEW_JS_ALERT);
178     SetEventObject(win);
179     if (win)
180         SetId(win->GetId());
181 }
182 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent,wxCommandEvent)183 IMPLEMENT_DYNAMIC_CLASS(wxWebViewConfirmEvent, wxCommandEvent)
184 
185 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_CONFIRM)
186 
187 wxWebViewConfirmEvent::wxWebViewConfirmEvent(wxWindow* win)
188 {
189     SetEventType(wxEVT_WEBVIEW_JS_CONFIRM);
190     SetEventObject(win);
191     if (win)
192         SetId(win->GetId());
193 }
194 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent,wxCommandEvent)195 IMPLEMENT_DYNAMIC_CLASS(wxWebViewPromptEvent, wxCommandEvent)
196 
197 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_JS_PROMPT)
198 
199 wxWebViewPromptEvent::wxWebViewPromptEvent(wxWindow* win)
200 {
201     SetEventType(wxEVT_WEBVIEW_JS_PROMPT);
202     SetEventObject(win);
203     if (win)
204         SetId(win->GetId());
205 }
206 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent,wxCommandEvent)207 IMPLEMENT_DYNAMIC_CLASS(wxWebViewReceivedTitleEvent, wxCommandEvent)
208 
209 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_RECEIVED_TITLE)
210 
211 wxWebViewReceivedTitleEvent::wxWebViewReceivedTitleEvent(wxWindow* win)
212 {
213     SetEventType(wxEVT_WEBVIEW_RECEIVED_TITLE);
214     SetEventObject(win);
215     if (win)
216         SetId(win->GetId());
217 }
218 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent,wxCommandEvent)219 IMPLEMENT_DYNAMIC_CLASS(wxWebViewWindowObjectClearedEvent, wxCommandEvent)
220 
221 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED)
222 
223 wxWebViewWindowObjectClearedEvent::wxWebViewWindowObjectClearedEvent(wxWindow* win)
224 {
225     SetEventType(wxEVT_WEBVIEW_WINDOW_OBJECT_CLEARED);
226     SetEventObject(win);
227     if (win)
228         SetId(win->GetId());
229 }
230 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewContentsChangedEvent,wxCommandEvent)231 IMPLEMENT_DYNAMIC_CLASS(wxWebViewContentsChangedEvent, wxCommandEvent)
232 
233 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_CONTENTS_CHANGED)
234 
235 wxWebViewContentsChangedEvent::wxWebViewContentsChangedEvent(wxWindow* win)
236 {
237     SetEventType(wxEVT_WEBVIEW_CONTENTS_CHANGED);
238     SetEventObject(win);
239     if (win)
240         SetId(win->GetId());
241 }
242 
IMPLEMENT_DYNAMIC_CLASS(wxWebViewSelectionChangedEvent,wxCommandEvent)243 IMPLEMENT_DYNAMIC_CLASS(wxWebViewSelectionChangedEvent, wxCommandEvent)
244 
245 DEFINE_EVENT_TYPE(wxEVT_WEBVIEW_SELECTION_CHANGED)
246 
247 wxWebViewSelectionChangedEvent::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 
wxWebViewDOMElementInfo()259 wxWebViewDOMElementInfo::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 
269 static wxWebViewCachePolicy gs_cachePolicy;
270 
271 /* static */
SetCachePolicy(const wxWebViewCachePolicy & cachePolicy)272 void 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 */
GetCachePolicy()284 wxWebViewCachePolicy wxWebView::GetCachePolicy()
285 {
286     return gs_cachePolicy;
287 }
288 
wxWebViewDOMElementInfo(const wxWebViewDOMElementInfo & other)289 wxWebViewDOMElementInfo::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 
~wxWebViewDOMElementInfo()299 wxWebViewDOMElementInfo::~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
310 void InitWebCoreSystemInterface(void);
311 #endif
312 
313 BEGIN_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)
323 END_EVENT_TABLE()
324 
325 IMPLEMENT_DYNAMIC_CLASS(wxWebView, wxWindow)
326 
327 const wxChar* wxWebViewNameStr = wxT("webView");
328 
wxWebView()329 wxWebView::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 
wxWebView(wxWindow * parent,int id,const wxPoint & position,const wxSize & size,long style,const wxString & name)338 wxWebView::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 
Create(wxWindow * parent,int id,const wxPoint & position,const wxSize & size,long style,const wxString & name)349 bool 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 
~wxWebView()418 wxWebView::~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.
OnTLWActivated(wxActivateEvent & event)435 void 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 
Stop()444 void wxWebView::Stop()
445 {
446     if (m_mainFrame)
447         m_mainFrame->Stop();
448 }
449 
Reload()450 void wxWebView::Reload()
451 {
452     if (m_mainFrame)
453         m_mainFrame->Reload();
454 }
455 
GetPageSource()456 wxString wxWebView::GetPageSource()
457 {
458     if (m_mainFrame)
459         return m_mainFrame->GetPageSource();
460 
461     return wxEmptyString;
462 }
463 
SetPageSource(const wxString & source,const wxString & baseUrl,const wxString & mimetype)464 void 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 
GetInnerText()470 wxString wxWebView::GetInnerText()
471 {
472     if (m_mainFrame)
473         return m_mainFrame->GetInnerText();
474 
475     return wxEmptyString;
476 }
477 
GetAsMarkup()478 wxString wxWebView::GetAsMarkup()
479 {
480     if (m_mainFrame)
481         return m_mainFrame->GetAsMarkup();
482 
483     return wxEmptyString;
484 }
485 
GetExternalRepresentation()486 wxString wxWebView::GetExternalRepresentation()
487 {
488     if (m_mainFrame)
489         return m_mainFrame->GetExternalRepresentation();
490 
491     return wxEmptyString;
492 }
493 
GetSelection()494 wxWebKitSelection wxWebView::GetSelection()
495 {
496     if (m_mainFrame)
497         return m_mainFrame->GetSelection();
498 
499     return 0;
500 }
501 
GetSelectionAsHTML()502 wxString wxWebView::GetSelectionAsHTML()
503 {
504     if (m_mainFrame)
505         return m_mainFrame->GetSelectionAsHTML();
506 
507     return wxEmptyString;
508 }
509 
GetSelectionAsText()510 wxString wxWebView::GetSelectionAsText()
511 {
512     if (m_mainFrame)
513         return m_mainFrame->GetSelectionAsText();
514 
515     return wxEmptyString;
516 }
517 
SetTransparent(bool transparent)518 void 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 
IsTransparent() const530 bool 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 
RunScript(const wxString & javascript)542 wxString wxWebView::RunScript(const wxString& javascript)
543 {
544     if (m_mainFrame)
545         return m_mainFrame->RunScript(javascript);
546 
547     return wxEmptyString;
548 }
549 
ExecuteEditCommand(const wxString & command,const wxString & parameter)550 bool wxWebView::ExecuteEditCommand(const wxString& command, const wxString& parameter)
551 {
552     if (m_mainFrame)
553         return m_mainFrame->ExecuteEditCommand(command, parameter);
554 }
555 
GetEditCommandState(const wxString & command) const556 EditState wxWebView::GetEditCommandState(const wxString& command) const
557 {
558     if (m_mainFrame)
559         return m_mainFrame->GetEditCommandState(command);
560 }
561 
GetEditCommandValue(const wxString & command) const562 wxString wxWebView::GetEditCommandValue(const wxString& command) const
563 {
564     if (m_mainFrame)
565         return m_mainFrame->GetEditCommandValue(command);
566 
567     return wxEmptyString;
568 }
569 
LoadURL(const wxString & url)570 void wxWebView::LoadURL(const wxString& url)
571 {
572     if (m_mainFrame)
573         m_mainFrame->LoadURL(url);
574 }
575 
GoBack()576 bool wxWebView::GoBack()
577 {
578     if (m_mainFrame)
579         return m_mainFrame->GoBack();
580 
581     return false;
582 }
583 
GoForward()584 bool wxWebView::GoForward()
585 {
586     if (m_mainFrame)
587         return m_mainFrame->GoForward();
588 
589     return false;
590 }
591 
CanGoBack()592 bool wxWebView::CanGoBack()
593 {
594     if (m_mainFrame)
595         return m_mainFrame->CanGoBack();
596 
597     return false;
598 }
599 
CanGoForward()600 bool wxWebView::CanGoForward()
601 {
602     if (m_mainFrame)
603         return m_mainFrame->CanGoForward();
604 
605     return false;
606 }
607 
CanIncreaseTextSize() const608 bool wxWebView::CanIncreaseTextSize() const
609 {
610     if (m_mainFrame)
611         return m_mainFrame->CanIncreaseTextSize();
612 
613     return false;
614 }
615 
IncreaseTextSize()616 void wxWebView::IncreaseTextSize()
617 {
618     if (m_mainFrame)
619         m_mainFrame->IncreaseTextSize();
620 }
621 
CanDecreaseTextSize() const622 bool wxWebView::CanDecreaseTextSize() const
623 {
624     if (m_mainFrame)
625         m_mainFrame->CanDecreaseTextSize();
626 
627     return false;
628 }
629 
DecreaseTextSize()630 void wxWebView::DecreaseTextSize()
631 {
632     if (m_mainFrame)
633         m_mainFrame->DecreaseTextSize();
634 }
635 
ResetTextSize()636 void wxWebView::ResetTextSize()
637 {
638     if (m_mainFrame)
639         m_mainFrame->ResetTextSize();
640 }
641 
MakeEditable(bool enable)642 void wxWebView::MakeEditable(bool enable)
643 {
644     if (m_mainFrame)
645         m_mainFrame->MakeEditable(enable);
646 }
647 
IsEditable() const648 bool 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 
OnPaint(wxPaintEvent & event)662 void 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 
FindString(const wxString & string,bool forward,bool caseSensitive,bool wrapSelection,bool startInSelection)694 bool 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 
OnSize(wxSizeEvent & event)702 void 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 
getDoubleClickTime()713 static int getDoubleClickTime()
714 {
715 #if __WXMSW__
716     return ::GetDoubleClickTime();
717 #else
718     return 500;
719 #endif
720 }
721 
OnMouseEvents(wxMouseEvent & event)722 void 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 
OnContextMenuEvents(wxContextMenuEvent & event)794 void 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 
OnMenuSelectEvents(wxCommandEvent & event)830 void 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 
CanCopy()846 bool wxWebView::CanCopy()
847 {
848     if (m_mainFrame)
849         return m_mainFrame->CanCopy();
850 
851     return false;
852 }
853 
Copy()854 void wxWebView::Copy()
855 {
856     if (m_mainFrame)
857         m_mainFrame->Copy();
858 }
859 
CanCut()860 bool wxWebView::CanCut()
861 {
862     if (m_mainFrame)
863         return m_mainFrame->CanCut();
864 
865     return false;
866 }
867 
Cut()868 void wxWebView::Cut()
869 {
870     if (m_mainFrame)
871         m_mainFrame->Cut();
872 }
873 
CanPaste()874 bool wxWebView::CanPaste()
875 {
876     if (m_mainFrame)
877         return m_mainFrame->CanPaste();
878 
879     return false;
880 }
881 
Paste()882 void wxWebView::Paste()
883 {
884     if (m_mainFrame)
885         m_mainFrame->Paste();
886 }
887 
OnKeyEvents(wxKeyEvent & event)888 void 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 
OnSetFocus(wxFocusEvent & event)1023 void 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 
OnKillFocus(wxFocusEvent & event)1036 void 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 
HitTest(const wxPoint & pos) const1057 wxWebViewDOMElementInfo wxWebView::HitTest(const wxPoint& pos) const
1058 {
1059     if (m_mainFrame)
1060         return m_mainFrame->HitTest(pos);
1061 
1062     return wxWebViewDOMElementInfo();
1063 }
1064 
ShouldClose() const1065 bool wxWebView::ShouldClose() const
1066 {
1067     if (m_mainFrame)
1068         return m_mainFrame->ShouldClose();
1069 
1070     return true;
1071 }
1072 
1073 /* static */
SetDatabaseDirectory(const wxString & databaseDirectory)1074 void wxWebView::SetDatabaseDirectory(const wxString& databaseDirectory)
1075 {
1076 #if ENABLE(DATABASE)
1077     WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(databaseDirectory);
1078 #endif
1079 }
1080 
1081 /* static */
GetDatabaseDirectory()1082 wxString wxWebView::GetDatabaseDirectory()
1083 {
1084 #if ENABLE(DATABASE)
1085     return WebCore::DatabaseTracker::tracker().databaseDirectoryPath();
1086 #else
1087     return wxEmptyString;
1088 #endif
1089 }
1090 
1091 /* static */
SetDatabasesEnabled(bool enabled)1092 void wxWebView::SetDatabasesEnabled(bool enabled)
1093 {
1094 #if ENABLE(DATABASE)
1095     WebCore::AbstractDatabase::setIsAvailable(enabled);
1096 #endif
1097 }
1098 
1099 /* static */
AreDatabasesEnabled()1100 bool wxWebView::AreDatabasesEnabled()
1101 {
1102 #if ENABLE(DATABASE)
1103     return WebCore::AbstractDatabase::isAvailable();
1104 #endif
1105     return false;
1106 }
1107 
curlProxyType(wxProxyType type)1108 static 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 */
SetProxyInfo(const wxString & host,unsigned long port,wxProxyType type,const wxString & username,const wxString & password)1123 void 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 
GetWebSettings()1134 wxWebSettings 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 
GetCompatibilityMode() const1143 wxWebKitCompatibilityMode wxWebView::GetCompatibilityMode() const
1144 {
1145     if (m_mainFrame)
1146         return m_mainFrame->GetCompatibilityMode();
1147 
1148     return QuirksMode;
1149 }
1150 
GrantUniversalAccess()1151 void wxWebView::GrantUniversalAccess()
1152 {
1153     if (m_mainFrame)
1154         m_mainFrame->GrantUniversalAccess();
1155 }
1156