• 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 
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 "HostWindow.h"
37 #include "HTMLFrameOwnerElement.h"
38 #include "markup.h"
39 #include "Page.h"
40 #include "PlatformString.h"
41 #include "RenderTreeAsText.h"
42 #include "RenderObject.h"
43 #include "RenderView.h"
44 #include "ScriptController.h"
45 #include "ScriptValue.h"
46 #include "SubstituteData.h"
47 #include "TextEncoding.h"
48 
49 #include "JSDOMBinding.h"
50 #include <runtime/JSValue.h>
51 #include <runtime/UString.h>
52 #include <wtf/text/CString.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 "WebDOMNode.h"
63 
64 #include "WebDOMSelection.h"
65 #include "WebFrame.h"
66 #include "WebView.h"
67 #include "WebFramePrivate.h"
68 #include "WebViewPrivate.h"
69 
70 #include <wx/defs.h>
71 #include <wx/dcbuffer.h>
72 
73 // Match Safari's min/max zoom sizes by default
74 #define MinimumTextSizeMultiplier       0.5f
75 #define MaximumTextSizeMultiplier       3.0f
76 #define TextSizeMultiplierRatio         1.2f
77 
wxWebFrame(wxWebView * container,wxWebFrame * parent,WebViewFrameData * data)78 wxWebFrame::wxWebFrame(wxWebView* container, wxWebFrame* parent, WebViewFrameData* data) :
79     m_textMagnifier(1.0),
80     m_isInitialized(false),
81     m_beingDestroyed(false)
82 {
83 
84     m_impl = new WebFramePrivate();
85 
86     WebCore::HTMLFrameOwnerElement* parentFrame = 0;
87 
88     if (data) {
89         parentFrame = data->ownerElement;
90     }
91 
92     WebCore::FrameLoaderClientWx* loaderClient = new WebCore::FrameLoaderClientWx();
93     RefPtr<WebCore::Frame> newFrame = WebCore::Frame::create(container->m_impl->page, parentFrame, loaderClient);
94 
95     m_impl->frame = newFrame.get();
96 
97     if (data)
98         newFrame->tree()->setName(data->name);
99 
100     // Subframes expect to be added to the FrameTree before init is called.
101     if (parentFrame)
102         parentFrame->document()->frame()->tree()->appendChild(newFrame.get());
103 
104     loaderClient->setFrame(this);
105     loaderClient->setWebView(container);
106 
107     if (data && data->ownerElement)
108         m_impl->frame->ref();
109 
110     m_impl->frame->init();
111 
112     m_isInitialized = true;
113 }
114 
~wxWebFrame()115 wxWebFrame::~wxWebFrame()
116 {
117     if (m_impl)
118         delete m_impl;
119 }
120 
GetFrame()121 WebCore::Frame* wxWebFrame::GetFrame()
122 {
123     if (m_impl)
124         return m_impl->frame;
125 
126     return 0;
127 }
128 
Stop()129 void wxWebFrame::Stop()
130 {
131     if (m_impl->frame && m_impl->frame->loader())
132         m_impl->frame->loader()->stop();
133 }
134 
Reload()135 void wxWebFrame::Reload()
136 {
137     if (m_impl->frame && m_impl->frame->loader())
138         m_impl->frame->loader()->reload();
139 }
140 
GetPageSource()141 wxString wxWebFrame::GetPageSource()
142 {
143     if (m_impl->frame) {
144         if (m_impl->frame->view() && m_impl->frame->view()->layoutPending())
145             m_impl->frame->view()->layout();
146 
147         WebCore::Document* doc = m_impl->frame->document();
148 
149         if (doc) {
150             wxString source = createMarkup(doc);
151             return source;
152         }
153     }
154     return wxEmptyString;
155 }
156 
SetPageSource(const wxString & source,const wxString & baseUrl,const wxString & mimetype)157 void wxWebFrame::SetPageSource(const wxString& source, const wxString& baseUrl, const wxString& mimetype)
158 {
159     if (m_impl->frame && m_impl->frame->loader()) {
160         WebCore::KURL url(WebCore::KURL(), baseUrl);
161 
162         const wxCharBuffer charBuffer(source.utf8_str());
163         const char* contents = charBuffer;
164 
165         WTF::PassRefPtr<WebCore::SharedBuffer> sharedBuffer = WebCore::SharedBuffer::create(contents, strlen(contents));
166         WebCore::SubstituteData substituteData(sharedBuffer, mimetype, WTF::String("UTF-8"), WebCore::blankURL(), url);
167 
168         m_impl->frame->loader()->stop();
169         m_impl->frame->loader()->load(WebCore::ResourceRequest(url), substituteData, false);
170     }
171 }
172 
GetInnerText()173 wxString wxWebFrame::GetInnerText()
174 {
175     if (m_impl->frame->view() && m_impl->frame->view()->layoutPending())
176         m_impl->frame->view()->layout();
177 
178     WebCore::Element *documentElement = m_impl->frame->document()->documentElement();
179     return documentElement->innerText();
180 }
181 
GetAsMarkup()182 wxString wxWebFrame::GetAsMarkup()
183 {
184     if (!m_impl->frame || !m_impl->frame->document())
185         return wxEmptyString;
186 
187     return createMarkup(m_impl->frame->document());
188 }
189 
GetExternalRepresentation()190 wxString wxWebFrame::GetExternalRepresentation()
191 {
192     if (m_impl->frame->view() && m_impl->frame->view()->layoutPending())
193         m_impl->frame->view()->layout();
194 
195     return externalRepresentation(m_impl->frame);
196 }
197 
GetSelectionAsHTML()198 wxString wxWebFrame::GetSelectionAsHTML()
199 {
200     if (m_impl->frame)
201         return m_impl->frame->selection()->toNormalizedRange()->toHTML();
202 
203     return wxEmptyString;
204 }
205 
GetSelectionAsText()206 wxString wxWebFrame::GetSelectionAsText()
207 {
208     if (m_impl->frame)
209         return m_impl->frame->selection()->toNormalizedRange()->text();
210 
211     return wxEmptyString;
212 }
213 
GetSelection()214 wxWebKitSelection wxWebFrame::GetSelection()
215 {
216     if (m_impl->frame)
217         return wxWebKitSelection(m_impl->frame->selection());
218 
219     return 0;
220 }
221 
RunScript(const wxString & javascript)222 wxString wxWebFrame::RunScript(const wxString& javascript)
223 {
224     wxString returnValue = wxEmptyString;
225     if (m_impl->frame && m_impl->frame->loader()) {
226         bool hasLoaded = m_impl->frame->loader()->frameHasLoaded();
227         wxASSERT_MSG(hasLoaded, wxT("Document must be loaded before calling RunScript."));
228         if (hasLoaded) {
229             WebCore::ScriptController* controller = m_impl->frame->script();
230             bool jsEnabled = controller->canExecuteScripts(WebCore::AboutToExecuteScript);
231             wxASSERT_MSG(jsEnabled, wxT("RunScript requires JavaScript to be enabled."));
232             if (jsEnabled) {
233                 JSC::JSValue result = controller->executeScript(javascript, true).jsValue();
234                 if (result)
235                     returnValue = wxString(result.toString(m_impl->frame->script()->globalObject(WebCore::mainThreadNormalWorld())->globalExec()).utf8().data(), wxConvUTF8);
236             }
237         }
238     }
239     return returnValue;
240 }
241 
ExecuteEditCommand(const wxString & command,const wxString & parameter)242 bool wxWebFrame::ExecuteEditCommand(const wxString& command, const wxString& parameter)
243 {
244     if (m_impl->frame && IsEditable())
245         return m_impl->frame->editor()->command(command).execute(parameter);
246 }
247 
GetEditCommandState(const wxString & command) const248 EditState wxWebFrame::GetEditCommandState(const wxString& command) const
249 {
250     if (m_impl->frame && IsEditable()) {
251         WebCore::TriState state = m_impl->frame->editor()->command(command).state();
252         if (state == WebCore::TrueTriState)
253             return EditStateTrue;
254         if (state == WebCore::FalseTriState)
255             return EditStateFalse;
256 
257         return EditStateMixed;
258     }
259 
260     return EditStateFalse;
261 }
262 
GetEditCommandValue(const wxString & command) const263 wxString wxWebFrame::GetEditCommandValue(const wxString& command) const
264 {
265     if (m_impl->frame && IsEditable())
266         return m_impl->frame->editor()->command(command).value();
267 
268     return wxEmptyString;
269 }
270 
271 
FindString(const wxString & string,bool forward,bool caseSensitive,bool wrapSelection,bool startInSelection)272 bool wxWebFrame::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection)
273 {
274     if (m_impl->frame)
275         return m_impl->frame->editor()->findString(string, forward, caseSensitive, wrapSelection, startInSelection);
276 
277     return false;
278 }
279 
LoadURL(const wxString & url)280 void wxWebFrame::LoadURL(const wxString& url)
281 {
282     if (m_impl->frame && m_impl->frame->loader()) {
283         WebCore::KURL kurl = WebCore::KURL(WebCore::KURL(), url, WebCore::UTF8Encoding());
284         // NB: This is an ugly fix, but CURL won't load sub-resources if the
285         // protocol is omitted; sadly, it will not emit an error, either, so
286         // there's no way for us to catch this problem the correct way yet.
287         if (kurl.protocol().isEmpty()) {
288             // is it a file on disk?
289             if (wxFileExists(url)) {
290                 kurl.setProtocol("file");
291                 kurl.setPath("//" + kurl.path());
292             }
293             else {
294                 kurl.setProtocol("http");
295                 kurl.setPath("//" + kurl.path());
296             }
297         }
298         m_impl->frame->loader()->load(kurl, false);
299     }
300 }
301 
GoBack()302 bool wxWebFrame::GoBack()
303 {
304     if (m_impl->frame && m_impl->frame->page())
305         return m_impl->frame->page()->goBack();
306 
307     return false;
308 }
309 
GoForward()310 bool wxWebFrame::GoForward()
311 {
312     if (m_impl->frame && m_impl->frame->page())
313         return m_impl->frame->page()->goForward();
314 
315     return false;
316 }
317 
CanGoBack()318 bool wxWebFrame::CanGoBack()
319 {
320     if (m_impl->frame && m_impl->frame->page())
321         return m_impl->frame->page()->canGoBackOrForward(-1);
322 
323     return false;
324 }
325 
CanGoForward()326 bool wxWebFrame::CanGoForward()
327 {
328     if (m_impl->frame && m_impl->frame->page())
329         return m_impl->frame->page()->canGoBackOrForward(1);
330 
331     return false;
332 }
333 
Undo()334 void wxWebFrame::Undo()
335 {
336     if (m_impl->frame && m_impl->frame->editor() && CanUndo())
337         return m_impl->frame->editor()->undo();
338 }
339 
Redo()340 void wxWebFrame::Redo()
341 {
342     if (m_impl->frame && m_impl->frame->editor() && CanRedo())
343         return m_impl->frame->editor()->redo();
344 }
345 
CanUndo()346 bool wxWebFrame::CanUndo()
347 {
348     if (m_impl->frame && m_impl->frame->editor())
349         return m_impl->frame->editor()->canUndo();
350 
351     return false;
352 }
353 
CanRedo()354 bool wxWebFrame::CanRedo()
355 {
356     if (m_impl->frame && m_impl->frame->editor())
357         return m_impl->frame->editor()->canRedo();
358 
359     return false;
360 }
361 
CanIncreaseTextSize() const362 bool wxWebFrame::CanIncreaseTextSize() const
363 {
364     if (m_impl->frame && m_impl->frame->view()) {
365         if (m_textMagnifier*TextSizeMultiplierRatio <= MaximumTextSizeMultiplier)
366             return true;
367     }
368     return false;
369 }
370 
IncreaseTextSize()371 void wxWebFrame::IncreaseTextSize()
372 {
373     if (CanIncreaseTextSize()) {
374         m_textMagnifier = m_textMagnifier*TextSizeMultiplierRatio;
375         m_impl->frame->setTextZoomFactor(m_textMagnifier);
376     }
377 }
378 
CanDecreaseTextSize() const379 bool wxWebFrame::CanDecreaseTextSize() const
380 {
381     if (m_impl->frame && m_impl->frame->view()) {
382         if (m_textMagnifier/TextSizeMultiplierRatio >= MinimumTextSizeMultiplier)
383             return true;
384     }
385     return false;
386 }
387 
DecreaseTextSize()388 void wxWebFrame::DecreaseTextSize()
389 {
390     if (CanDecreaseTextSize()) {
391         m_textMagnifier = m_textMagnifier/TextSizeMultiplierRatio;
392         m_impl->frame->setTextZoomFactor(m_textMagnifier);
393     }
394 }
395 
ResetTextSize()396 void wxWebFrame::ResetTextSize()
397 {
398     m_textMagnifier = 1.0;
399     if (m_impl->frame)
400         m_impl->frame->setTextZoomFactor(m_textMagnifier);
401 }
402 
MakeEditable(bool enable)403 void wxWebFrame::MakeEditable(bool enable)
404 {
405     if (enable != IsEditable() && m_impl->frame && m_impl->frame->page())
406         m_impl->frame->page()->setEditable(enable);
407 }
408 
IsEditable() const409 bool wxWebFrame::IsEditable() const
410 {
411     if (m_impl->frame && m_impl->frame->page())
412         return m_impl->frame->page()->isEditable();
413     return false;
414 }
415 
CanCopy()416 bool wxWebFrame::CanCopy()
417 {
418     if (m_impl->frame && m_impl->frame->view())
419         return (m_impl->frame->editor()->canCopy() || m_impl->frame->editor()->canDHTMLCopy());
420 
421     return false;
422 }
423 
Copy()424 void wxWebFrame::Copy()
425 {
426     if (CanCopy())
427         m_impl->frame->editor()->copy();
428 }
429 
CanCut()430 bool wxWebFrame::CanCut()
431 {
432     if (m_impl->frame && m_impl->frame->view())
433         return (m_impl->frame->editor()->canCut() || m_impl->frame->editor()->canDHTMLCut());
434 
435     return false;
436 }
437 
Cut()438 void wxWebFrame::Cut()
439 {
440     if (CanCut())
441         m_impl->frame->editor()->cut();
442 }
443 
CanPaste()444 bool wxWebFrame::CanPaste()
445 {
446     if (m_impl->frame && m_impl->frame->view())
447         return (m_impl->frame->editor()->canPaste() || m_impl->frame->editor()->canDHTMLPaste());
448 
449     return false;
450 }
451 
Paste()452 void wxWebFrame::Paste()
453 {
454     if (CanPaste())
455         m_impl->frame->editor()->paste();
456 
457 }
458 
HitTest(const wxPoint & pos) const459 wxWebViewDOMElementInfo wxWebFrame::HitTest(const wxPoint& pos) const
460 {
461     wxWebViewDOMElementInfo domInfo;
462 
463     if (m_impl->frame->view()) {
464         WebCore::HitTestResult result = m_impl->frame->eventHandler()->hitTestResultAtPoint(m_impl->frame->view()->windowToContents(pos), false);
465         if (result.innerNode()) {
466             domInfo.SetLink(result.absoluteLinkURL().string());
467             domInfo.SetText(result.textContent());
468             domInfo.SetImageSrc(result.absoluteImageURL().string());
469             domInfo.SetSelected(result.isSelected());
470         }
471     }
472 
473     return domInfo;
474 }
475 
ShouldClose() const476 bool wxWebFrame::ShouldClose() const
477 {
478     if (m_impl->frame)
479         return m_impl->frame->loader()->shouldClose();
480 
481     return true;
482 }
483 
GetCompatibilityMode() const484 wxWebKitCompatibilityMode wxWebFrame::GetCompatibilityMode() const
485 {
486     if (m_impl->frame && m_impl->frame->document())
487         return (wxWebKitCompatibilityMode)m_impl->frame->document()->compatibilityMode();
488 
489     return QuirksMode;
490 }
491 
GrantUniversalAccess()492 void wxWebFrame::GrantUniversalAccess()
493 {
494     if (m_impl->frame && m_impl->frame->document())
495         m_impl->frame->document()->securityOrigin()->grantUniversalAccess();
496 }
497