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