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