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