• 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 "CString.h"
28 #include "Document.h"
29 #include "Editor.h"
30 #include "Element.h"
31 #include "EventHandler.h"
32 #include "Frame.h"
33 #include "FrameLoader.h"
34 #include "FrameView.h"
35 #include "HitTestResult.h"
36 #include "HTMLFrameOwnerElement.h"
37 #include "markup.h"
38 #include "Page.h"
39 #include "PlatformString.h"
40 #include "RenderTreeAsText.h"
41 #include "RenderObject.h"
42 #include "RenderView.h"
43 #include "ScriptController.h"
44 #include "ScriptValue.h"
45 #include "TextEncoding.h"
46 
47 #include "JSDOMBinding.h"
48 #include <runtime/JSValue.h>
49 #include <runtime/UString.h>
50 
51 #include "EditorClientWx.h"
52 #include "FrameLoaderClientWx.h"
53 
54 #include "wx/wxprec.h"
55 #ifndef WX_PRECOMP
56     #include "wx/wx.h"
57 #endif
58 
59 #include "WebFrame.h"
60 #include "WebView.h"
61 #include "WebFramePrivate.h"
62 #include "WebViewPrivate.h"
63 
64 #include <wx/defs.h>
65 #include <wx/dcbuffer.h>
66 
67 // Match Safari's min/max zoom sizes by default
68 #define MinimumTextSizeMultiplier       0.5f
69 #define MaximumTextSizeMultiplier       3.0f
70 #define TextSizeMultiplierRatio         1.2f
71 
wxWebFrame(wxWebView * container,wxWebFrame * parent,WebViewFrameData * data)72 wxWebFrame::wxWebFrame(wxWebView* container, wxWebFrame* parent, WebViewFrameData* data) :
73     m_textMagnifier(1.0),
74     m_isEditable(false),
75     m_isInitialized(false),
76     m_beingDestroyed(false),
77     m_title(wxEmptyString)
78 {
79 
80     m_impl = new WebFramePrivate();
81 
82     WebCore::HTMLFrameOwnerElement* parentFrame = 0;
83 
84     if (data) {
85         parentFrame = data->ownerElement;
86     }
87 
88     WebCore::FrameLoaderClientWx* loaderClient = new WebCore::FrameLoaderClientWx();
89 
90     m_impl->frame = WebCore::Frame::create(container->m_impl->page, parentFrame, loaderClient);
91     m_impl->frame->deref();
92 
93     loaderClient->setFrame(m_impl->frame.get());
94     loaderClient->setWebView(container);
95 
96     m_impl->frame->init();
97 
98     m_isInitialized = true;
99 }
100 
~wxWebFrame()101 wxWebFrame::~wxWebFrame()
102 {
103     m_impl->frame->loader()->detachFromParent();
104 }
105 
GetFrame()106 WebCore::Frame* wxWebFrame::GetFrame()
107 {
108     if (m_impl)
109         return m_impl->frame.get();
110 
111     return 0;
112 }
113 
Stop()114 void wxWebFrame::Stop()
115 {
116     if (m_impl->frame && m_impl->frame->loader())
117         m_impl->frame->loader()->stop();
118 }
119 
Reload()120 void wxWebFrame::Reload()
121 {
122     if (m_impl->frame && m_impl->frame->loader())
123         m_impl->frame->loader()->reload();
124 }
125 
GetPageSource()126 wxString wxWebFrame::GetPageSource()
127 {
128     if (m_impl->frame) {
129         if (m_impl->frame->view() && m_impl->frame->view()->layoutPending())
130             m_impl->frame->view()->layout();
131 
132         WebCore::Document* doc = m_impl->frame->document();
133 
134         if (doc) {
135             wxString source = createMarkup(doc);
136             return source;
137         }
138     }
139     return wxEmptyString;
140 }
141 
SetPageSource(const wxString & source,const wxString & baseUrl)142 void wxWebFrame::SetPageSource(const wxString& source, const wxString& baseUrl)
143 {
144     if (m_impl->frame && m_impl->frame->loader()) {
145         WebCore::FrameLoader* loader = m_impl->frame->loader();
146         loader->begin(WebCore::KURL(WebCore::KURL(), static_cast<const char*>(baseUrl.mb_str(wxConvUTF8)), WebCore::UTF8Encoding()));
147         loader->write(static_cast<const WebCore::String>(source));
148         loader->end();
149     }
150 }
151 
GetInnerText()152 wxString wxWebFrame::GetInnerText()
153 {
154     if (m_impl->frame->view() && m_impl->frame->view()->layoutPending())
155         m_impl->frame->view()->layout();
156 
157     WebCore::Element *documentElement = m_impl->frame->document()->documentElement();
158     return documentElement->innerText();
159 }
160 
GetAsMarkup()161 wxString wxWebFrame::GetAsMarkup()
162 {
163     if (!m_impl->frame || !m_impl->frame->document())
164         return wxEmptyString;
165 
166     return createMarkup(m_impl->frame->document());
167 }
168 
GetExternalRepresentation()169 wxString wxWebFrame::GetExternalRepresentation()
170 {
171     if (m_impl->frame->view() && m_impl->frame->view()->layoutPending())
172         m_impl->frame->view()->layout();
173 
174     return externalRepresentation(m_impl->frame->contentRenderer());
175 }
176 
RunScript(const wxString & javascript)177 wxString wxWebFrame::RunScript(const wxString& javascript)
178 {
179     wxString returnValue = wxEmptyString;
180     if (m_impl->frame) {
181         JSC::JSValue result = m_impl->frame->loader()->executeScript(javascript, true).jsValue();
182         if (result)
183             returnValue = wxString(result.toString(m_impl->frame->script()->globalObject()->globalExec()).UTF8String().c_str(), wxConvUTF8);
184     }
185     return returnValue;
186 }
187 
FindString(const wxString & string,bool forward,bool caseSensitive,bool wrapSelection,bool startInSelection)188 bool wxWebFrame::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
189 {
190     if (m_impl->frame)
191         return m_impl->frame->findString(string, forward, caseSensitive, wrapSelection, startInSelection);
192 
193     return false;
194 }
195 
LoadURL(const wxString & url)196 void wxWebFrame::LoadURL(const wxString& url)
197 {
198     if (m_impl->frame && m_impl->frame->loader()) {
199         WebCore::KURL kurl = WebCore::KURL(WebCore::KURL(), static_cast<const char*>(url.mb_str(wxConvUTF8)), WebCore::UTF8Encoding());
200         // NB: This is an ugly fix, but CURL won't load sub-resources if the
201         // protocol is omitted; sadly, it will not emit an error, either, so
202         // there's no way for us to catch this problem the correct way yet.
203         if (kurl.protocol().isEmpty()) {
204             // is it a file on disk?
205             if (wxFileExists(url)) {
206                 kurl.setProtocol("file");
207                 kurl.setPath("//" + kurl.path());
208             }
209             else {
210                 kurl.setProtocol("http");
211                 kurl.setPath("//" + kurl.path());
212             }
213         }
214         m_impl->frame->loader()->load(kurl, false);
215     }
216 }
217 
GoBack()218 bool wxWebFrame::GoBack()
219 {
220     if (m_impl->frame && m_impl->frame->page())
221         return m_impl->frame->page()->goBack();
222 
223     return false;
224 }
225 
GoForward()226 bool wxWebFrame::GoForward()
227 {
228     if (m_impl->frame && m_impl->frame->page())
229         return m_impl->frame->page()->goForward();
230 
231     return false;
232 }
233 
CanGoBack()234 bool wxWebFrame::CanGoBack()
235 {
236     if (m_impl->frame && m_impl->frame->page() && m_impl->frame->page()->backForwardList())
237         return m_impl->frame->page()->backForwardList()->backItem() != NULL;
238 
239     return false;
240 }
241 
CanGoForward()242 bool wxWebFrame::CanGoForward()
243 {
244     if (m_impl->frame && m_impl->frame->page() && m_impl->frame->page()->backForwardList())
245         return m_impl->frame->page()->backForwardList()->forwardItem() != NULL;
246 
247     return false;
248 }
249 
Undo()250 void wxWebFrame::Undo()
251 {
252     if (m_impl->frame && m_impl->frame->editor() && CanUndo())
253         return m_impl->frame->editor()->undo();
254 }
255 
Redo()256 void wxWebFrame::Redo()
257 {
258     if (m_impl->frame && m_impl->frame->editor() && CanRedo())
259         return m_impl->frame->editor()->redo();
260 }
261 
CanUndo()262 bool wxWebFrame::CanUndo()
263 {
264     if (m_impl->frame && m_impl->frame->editor())
265         return m_impl->frame->editor()->canUndo();
266 
267     return false;
268 }
269 
CanRedo()270 bool wxWebFrame::CanRedo()
271 {
272     if (m_impl->frame && m_impl->frame->editor())
273         return m_impl->frame->editor()->canRedo();
274 
275     return false;
276 }
277 
CanIncreaseTextSize() const278 bool wxWebFrame::CanIncreaseTextSize() const
279 {
280     if (m_impl->frame) {
281         if (m_textMagnifier*TextSizeMultiplierRatio <= MaximumTextSizeMultiplier)
282             return true;
283     }
284     return false;
285 }
286 
IncreaseTextSize()287 void wxWebFrame::IncreaseTextSize()
288 {
289     if (CanIncreaseTextSize()) {
290         m_textMagnifier = m_textMagnifier*TextSizeMultiplierRatio;
291         m_impl->frame->setZoomFactor(m_textMagnifier, true);
292     }
293 }
294 
CanDecreaseTextSize() const295 bool wxWebFrame::CanDecreaseTextSize() const
296 {
297     if (m_impl->frame) {
298         if (m_textMagnifier/TextSizeMultiplierRatio >= MinimumTextSizeMultiplier)
299             return true;
300     }
301     return false;
302 }
303 
DecreaseTextSize()304 void wxWebFrame::DecreaseTextSize()
305 {
306     if (CanDecreaseTextSize()) {
307         m_textMagnifier = m_textMagnifier/TextSizeMultiplierRatio;
308         m_impl->frame->setZoomFactor(m_textMagnifier, true);
309     }
310 }
311 
ResetTextSize()312 void wxWebFrame::ResetTextSize()
313 {
314     m_textMagnifier = 1.0;
315     if (m_impl->frame)
316         m_impl->frame->setZoomFactor(m_textMagnifier, true);
317 }
318 
MakeEditable(bool enable)319 void wxWebFrame::MakeEditable(bool enable)
320 {
321     m_isEditable = enable;
322 }
323 
324 
325 
CanCopy()326 bool wxWebFrame::CanCopy()
327 {
328     if (m_impl->frame && m_impl->frame->view())
329         return (m_impl->frame->editor()->canCopy() || m_impl->frame->editor()->canDHTMLCopy());
330 
331     return false;
332 }
333 
Copy()334 void wxWebFrame::Copy()
335 {
336     if (CanCopy())
337         m_impl->frame->editor()->copy();
338 }
339 
CanCut()340 bool wxWebFrame::CanCut()
341 {
342     if (m_impl->frame && m_impl->frame->view())
343         return (m_impl->frame->editor()->canCut() || m_impl->frame->editor()->canDHTMLCut());
344 
345     return false;
346 }
347 
Cut()348 void wxWebFrame::Cut()
349 {
350     if (CanCut())
351         m_impl->frame->editor()->cut();
352 }
353 
CanPaste()354 bool wxWebFrame::CanPaste()
355 {
356     if (m_impl->frame && m_impl->frame->view())
357         return (m_impl->frame->editor()->canPaste() || m_impl->frame->editor()->canDHTMLPaste());
358 
359     return false;
360 }
361 
Paste()362 void wxWebFrame::Paste()
363 {
364     if (CanPaste())
365         m_impl->frame->editor()->paste();
366 
367 }
368 
HitTest(const wxPoint & pos) const369 wxWebViewDOMElementInfo wxWebFrame::HitTest(const wxPoint& pos) const
370 {
371     wxWebViewDOMElementInfo domInfo;
372 
373     if (m_impl->frame->view()) {
374         WebCore::HitTestResult result = m_impl->frame->eventHandler()->hitTestResultAtPoint(m_impl->frame->view()->windowToContents(pos), false);
375         if (result.innerNode()) {
376             domInfo.SetLink(result.absoluteLinkURL().string());
377             domInfo.SetText(result.textContent());
378             domInfo.SetImageSrc(result.absoluteImageURL().string());
379             domInfo.SetSelected(result.isSelected());
380         }
381     }
382 
383     return domInfo;
384 }
385 
386