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