/* * Copyright (C) 2007 Kevin Ollivier All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "CString.h" #include "Document.h" #include "Editor.h" #include "Element.h" #include "EventHandler.h" #include "Frame.h" #include "FrameLoader.h" #include "FrameView.h" #include "HitTestResult.h" #include "HTMLFrameOwnerElement.h" #include "markup.h" #include "Page.h" #include "RenderTreeAsText.h" #include "RenderObject.h" #include "RenderView.h" #include "EditorClientWx.h" #include "FrameLoaderClientWx.h" #include "ScriptController.h" #include "ScriptValue.h" #include "JSDOMBinding.h" #include <runtime/JSValue.h> #include <runtime/UString.h> #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "WebFrame.h" #include "WebView.h" #include "WebFramePrivate.h" #include "WebViewPrivate.h" #include <wx/defs.h> #include <wx/dcbuffer.h> // Match Safari's min/max zoom sizes by default #define MinimumTextSizeMultiplier 0.5f #define MaximumTextSizeMultiplier 3.0f #define TextSizeMultiplierRatio 1.2f wxWebFrame::wxWebFrame(wxWebView* container, wxWebFrame* parent, WebViewFrameData* data) : m_textMagnifier(1.0), m_isEditable(false), m_isInitialized(false), m_beingDestroyed(false), m_title(wxEmptyString) { m_impl = new WebFramePrivate(); WebCore::HTMLFrameOwnerElement* parentFrame = 0; if (data) { parentFrame = data->ownerElement; } WebCore::FrameLoaderClientWx* loaderClient = new WebCore::FrameLoaderClientWx(); m_impl->frame = WebCore::Frame::create(container->m_impl->page, parentFrame, loaderClient); m_impl->frame->deref(); loaderClient->setFrame(m_impl->frame.get()); loaderClient->setWebView(container); m_impl->frame->init(); m_isInitialized = true; } wxWebFrame::~wxWebFrame() { m_impl->frame->loader()->detachFromParent(); } WebCore::Frame* wxWebFrame::GetFrame() { if (m_impl) return m_impl->frame.get(); return 0; } void wxWebFrame::Stop() { if (m_impl->frame && m_impl->frame->loader()) m_impl->frame->loader()->stop(); } void wxWebFrame::Reload() { if (m_impl->frame && m_impl->frame->loader()) m_impl->frame->loader()->reload(); } wxString wxWebFrame::GetPageSource() { if (m_impl->frame) { if (m_impl->frame->view() && m_impl->frame->view()->layoutPending()) m_impl->frame->view()->layout(); WebCore::Document* doc = m_impl->frame->document(); if (doc) { wxString source = createMarkup(doc); return source; } } return wxEmptyString; } void wxWebFrame::SetPageSource(const wxString& source, const wxString& baseUrl) { if (m_impl->frame && m_impl->frame->loader()) { WebCore::FrameLoader* loader = m_impl->frame->loader(); loader->begin(WebCore::KURL(static_cast<const char*>(baseUrl.mb_str(wxConvUTF8)))); loader->write(static_cast<const WebCore::String>(source)); loader->end(); } } wxString wxWebFrame::GetInnerText() { if (m_impl->frame->view() && m_impl->frame->view()->layoutPending()) m_impl->frame->view()->layout(); WebCore::Element *documentElement = m_impl->frame->document()->documentElement(); return documentElement->innerText(); } wxString wxWebFrame::GetAsMarkup() { if (!m_impl->frame || !m_impl->frame->document()) return wxEmptyString; return createMarkup(m_impl->frame->document()); } wxString wxWebFrame::GetExternalRepresentation() { if (m_impl->frame->view() && m_impl->frame->view()->layoutPending()) m_impl->frame->view()->layout(); return externalRepresentation(m_impl->frame->contentRenderer()); } wxString wxWebFrame::RunScript(const wxString& javascript) { wxString returnValue = wxEmptyString; if (m_impl->frame) { JSC::JSValuePtr result = m_impl->frame->loader()->executeScript(javascript, true).jsValue(); if (result) returnValue = wxString(result.toString(m_impl->frame->script()->globalObject()->globalExec()).UTF8String().c_str(), wxConvUTF8); } return returnValue; } bool wxWebFrame::FindString(const wxString& string, bool forward, bool caseSensitive, bool wrapSelection, bool startInSelection) { if (m_impl->frame) return m_impl->frame->findString(string, forward, caseSensitive, wrapSelection, startInSelection); return false; } void wxWebFrame::LoadURL(const wxString& url) { if (m_impl->frame && m_impl->frame->loader()) { WebCore::KURL kurl = WebCore::KURL(static_cast<const char*>(url.mb_str(wxConvUTF8))); // NB: This is an ugly fix, but CURL won't load sub-resources if the // protocol is omitted; sadly, it will not emit an error, either, so // there's no way for us to catch this problem the correct way yet. if (kurl.protocol().isEmpty()) { // is it a file on disk? if (wxFileExists(url)) { kurl.setProtocol("file"); kurl.setPath("//" + kurl.path()); } else { kurl.setProtocol("http"); kurl.setPath("//" + kurl.path()); } } m_impl->frame->loader()->load(kurl); } } bool wxWebFrame::GoBack() { if (m_impl->frame && m_impl->frame->page()) return m_impl->frame->page()->goBack(); return false; } bool wxWebFrame::GoForward() { if (m_impl->frame && m_impl->frame->page()) return m_impl->frame->page()->goForward(); return false; } bool wxWebFrame::CanGoBack() { if (m_impl->frame && m_impl->frame->page() && m_impl->frame->page()->backForwardList()) return m_impl->frame->page()->backForwardList()->backItem() != NULL; return false; } bool wxWebFrame::CanGoForward() { if (m_impl->frame && m_impl->frame->page() && m_impl->frame->page()->backForwardList()) return m_impl->frame->page()->backForwardList()->forwardItem() != NULL; return false; } void wxWebFrame::Undo() { if (m_impl->frame && m_impl->frame->editor() && CanUndo()) return m_impl->frame->editor()->undo(); } void wxWebFrame::Redo() { if (m_impl->frame && m_impl->frame->editor() && CanRedo()) return m_impl->frame->editor()->redo(); } bool wxWebFrame::CanUndo() { if (m_impl->frame && m_impl->frame->editor()) return m_impl->frame->editor()->canUndo(); return false; } bool wxWebFrame::CanRedo() { if (m_impl->frame && m_impl->frame->editor()) return m_impl->frame->editor()->canRedo(); return false; } bool wxWebFrame::CanIncreaseTextSize() const { if (m_impl->frame) { if (m_textMagnifier*TextSizeMultiplierRatio <= MaximumTextSizeMultiplier) return true; } return false; } void wxWebFrame::IncreaseTextSize() { if (CanIncreaseTextSize()) { m_textMagnifier = m_textMagnifier*TextSizeMultiplierRatio; m_impl->frame->setZoomFactor(m_textMagnifier, true); } } bool wxWebFrame::CanDecreaseTextSize() const { if (m_impl->frame) { if (m_textMagnifier/TextSizeMultiplierRatio >= MinimumTextSizeMultiplier) return true; } return false; } void wxWebFrame::DecreaseTextSize() { if (CanDecreaseTextSize()) { m_textMagnifier = m_textMagnifier/TextSizeMultiplierRatio; m_impl->frame->setZoomFactor(m_textMagnifier, true); } } void wxWebFrame::MakeEditable(bool enable) { m_isEditable = enable; } bool wxWebFrame::CanCopy() { if (m_impl->frame && m_impl->frame->view()) return (m_impl->frame->editor()->canCopy() || m_impl->frame->editor()->canDHTMLCopy()); return false; } void wxWebFrame::Copy() { if (CanCopy()) m_impl->frame->editor()->copy(); } bool wxWebFrame::CanCut() { if (m_impl->frame && m_impl->frame->view()) return (m_impl->frame->editor()->canCut() || m_impl->frame->editor()->canDHTMLCut()); return false; } void wxWebFrame::Cut() { if (CanCut()) m_impl->frame->editor()->cut(); } bool wxWebFrame::CanPaste() { if (m_impl->frame && m_impl->frame->view()) return (m_impl->frame->editor()->canPaste() || m_impl->frame->editor()->canDHTMLPaste()); return false; } void wxWebFrame::Paste() { if (CanPaste()) m_impl->frame->editor()->paste(); } wxWebViewDOMElementInfo wxWebFrame::HitTest(const wxPoint& pos) const { wxWebViewDOMElementInfo domInfo; if (m_impl->frame->view()) { WebCore::HitTestResult result = m_impl->frame->eventHandler()->hitTestResultAtPoint(m_impl->frame->view()->windowToContents(pos), false); if (result.innerNode()) { domInfo.SetLink(result.absoluteLinkURL().string()); domInfo.SetText(result.textContent()); domInfo.SetImageSrc(result.absoluteImageURL().string()); domInfo.SetSelected(result.isSelected()); } } return domInfo; }