haikuwebkit/Source/WebKitLegacy/haiku/API/WebFrame.cpp

441 lines
11 KiB
C++

/*
* Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
* Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
*
* 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 <WebCore/ScriptController.h>
#include "WebFrame.h"
#include "EditorClientHaiku.h"
#include "FrameLoaderClientHaiku.h"
#include "ProgressTrackerHaiku.h"
#include "WebCore/Document.h"
#include "WebCore/DocumentLoader.h"
#include "WebCore/Editor.h"
#include "WebCore/Element.h"
#include "WebCore/Frame.h"
#include "WebCore/FrameLoadRequest.h"
#include "WebCore/FrameLoader.h"
#include "WebCore/FrameView.h"
#include "WebCore/HTMLFrameOwnerElement.h"
#include "WebCore/Page.h"
#include "WebCore/ProgressTracker.h"
#include "WebCore/Range.h"
#include "WebCore/RenderObject.h"
#include "WebCore/RenderTreeAsText.h"
#include "WebCore/RenderView.h"
#include "wtf/URL.h"
#include "WebFramePrivate.h"
#include "WebPage.h"
#include "WebCore/markup.h"
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/CString.h>
#include <Entry.h>
#include <String.h>
static const float kMinimumZoomFactorMultiplier = 0.5;
static const float kMaximumZoomFactorMultiplier = 3;
static const float kZoomFactorMultiplierRatio = 1.1;
using namespace WebCore;
BWebFrame::BWebFrame(BWebPage* webPage, BWebFrame* parentFrame,
WebFramePrivate* data)
: fZoomFactor(1.0)
, fIsEditable(false)
, fTitle(0)
, fData(data)
{
if (!parentFrame) {
// No parent, we are creating the main BWebFrame.
// mainframe is already created in WebCore::Page, just use it.
fData->frame = &webPage->page()->mainFrame();
FrameLoaderClientHaiku& client
= static_cast<FrameLoaderClientHaiku&>(data->frame->loader().client());
client.setFrame(this);
fData->frame->init();
fData->frame->tree().setName(fData->name);
} else {
// Will be initialized in BWebFrame::AddChild
}
}
BWebFrame::~BWebFrame()
{
delete fData;
}
void BWebFrame::SetListener(const BMessenger& listener)
{
FrameLoaderClientHaiku& client
= static_cast<FrameLoaderClientHaiku&>(fData->frame->loader().client());
client.setDispatchTarget(listener);
}
void BWebFrame::LoadURL(BString urlString)
{
WTF::URL url;
if (BEntry(urlString.String()).Exists()) {
url.setProtocol("file");
url.setPath(String(urlString));
} else
url = WTF::URL(WTF::URL(), urlString.Trim());
if (!url.isValid()) {
BString fixedUrl("http://");
fixedUrl << urlString.Trim();
url = WTF::URL(WTF::URL(), fixedUrl);
}
LoadURL(url);
}
void BWebFrame::LoadURL(WTF::URL url)
{
if (url.isEmpty())
return;
if (!fData->frame)
return;
fData->requestedURL = url.string();
WebCore::ResourceRequest req(url);
fData->frame->loader().load(WebCore::FrameLoadRequest(*fData->frame, req));
}
void BWebFrame::StopLoading()
{
if (fData->frame)
fData->frame->loader().stop();
}
void BWebFrame::Reload()
{
if (fData->frame)
fData->frame->loader().reload();
}
BString BWebFrame::URL() const
{
if (fData->frame->document() == NULL)
return "";
return fData->frame->document()->url().string();
}
BString BWebFrame::RequestedURL() const
{
return fData->requestedURL;
}
bool BWebFrame::CanCopy() const
{
if (fData->frame && fData->frame->view())
return fData->frame->editor().canCopy() || fData->frame->editor().canDHTMLCopy();
return false;
}
bool BWebFrame::CanCut() const
{
if (fData->frame && fData->frame->view())
return fData->frame->editor().canCut() || fData->frame->editor().canDHTMLCut();
return false;
}
bool BWebFrame::CanPaste() const
{
if (fData->frame && fData->frame->view())
return fData->frame->editor().canPaste() || fData->frame->editor().canDHTMLPaste();
return false;
}
void BWebFrame::Copy()
{
if (CanCopy())
fData->frame->editor().copy();
}
void BWebFrame::Cut()
{
if (CanCut())
fData->frame->editor().cut();
}
void BWebFrame::Paste()
{
if (CanPaste())
fData->frame->editor().paste();
}
bool BWebFrame::CanUndo() const
{
if (fData->frame)
return fData->frame->editor().canUndo();
return false;
}
bool BWebFrame::CanRedo() const
{
if (fData->frame)
return fData->frame->editor().canRedo();
return false;
}
void BWebFrame::Undo()
{
if (CanUndo())
return fData->frame->editor().undo();
}
void BWebFrame::Redo()
{
if (CanRedo())
return fData->frame->editor().redo();
}
bool BWebFrame::AllowsScrolling() const
{
if (fData->frame && fData->frame->view())
return fData->frame->view()->canHaveScrollbars();
return false;
}
void BWebFrame::SetAllowsScrolling(bool flag)
{
if (fData->frame && fData->frame->view())
fData->frame->view()->setCanHaveScrollbars(flag);
}
BPoint BWebFrame::ScrollPosition()
{
return fData->frame->view()->scrollPosition();
}
/*!
Returns the frame's content as HTML, enclosed in HTML and BODY tags.
*/
BString BWebFrame::FrameSource() const
{
if (fData->frame) {
WebCore::Document* document = fData->frame->document();
if (document)
return serializeFragment(*document, SerializedNodes::SubtreeIncludingNode);
}
return BString();
}
void BWebFrame::SetFrameSource(const BString& /*source*/)
{
// FIXME: see QWebFrame::setHtml/setContent
}
void BWebFrame::SetTransparent(bool transparent)
{
if (fData->frame && fData->frame->view())
fData->frame->view()->setTransparent(transparent);
}
bool BWebFrame::IsTransparent() const
{
if (fData->frame && fData->frame->view())
return fData->frame->view()->isTransparent();
return false;
}
BString BWebFrame::InnerText() const
{
WebCore::Element *documentElement = fData->frame->document()->documentElement();
if (!documentElement)
return String();
return documentElement->innerText();
}
BString BWebFrame::AsMarkup() const
{
if (!fData->frame->document())
return BString();
return serializeFragment(*fData->frame->document(), SerializedNodes::SubtreeIncludingNode);
}
BString BWebFrame::ExternalRepresentation() const
{
return externalRepresentation(fData->frame);
}
bool BWebFrame::FindString(const BString& string, WebCore::FindOptions options)
{
if (fData->page)
return fData->page->findString(string, options);
return false;
}
bool BWebFrame::CanIncreaseZoomFactor() const
{
if (fData->frame) {
if (fZoomFactor * kZoomFactorMultiplierRatio <= kMaximumZoomFactorMultiplier)
return true;
}
return false;
}
bool BWebFrame::CanDecreaseZoomFactor() const
{
if (fData->frame)
return fZoomFactor / kZoomFactorMultiplierRatio >= kMinimumZoomFactorMultiplier;
return false;
}
void BWebFrame::IncreaseZoomFactor(bool textOnly)
{
if (CanIncreaseZoomFactor()) {
fZoomFactor = fZoomFactor * kZoomFactorMultiplierRatio;
if (textOnly)
fData->frame->setTextZoomFactor(fZoomFactor);
else
fData->frame->setPageAndTextZoomFactors(fZoomFactor, fZoomFactor);
}
}
void BWebFrame::DecreaseZoomFactor(bool textOnly)
{
if (CanDecreaseZoomFactor()) {
fZoomFactor = fZoomFactor / kZoomFactorMultiplierRatio;
if (textOnly)
fData->frame->setTextZoomFactor(fZoomFactor);
else
fData->frame->setPageAndTextZoomFactors(fZoomFactor, fZoomFactor);
}
}
void BWebFrame::ResetZoomFactor()
{
if (fZoomFactor == 1)
return;
fZoomFactor = 1;
if (fData->frame)
fData->frame->setPageAndTextZoomFactors(fZoomFactor, fZoomFactor);
}
void BWebFrame::SetEditable(bool editable)
{
fIsEditable = editable;
}
bool BWebFrame::IsEditable() const
{
return fIsEditable;
}
void BWebFrame::SetTitle(const BString& title)
{
if (fTitle == title)
return;
fTitle = title;
}
const BString& BWebFrame::Title() const
{
return fTitle;
}
// #pragma mark - private
const char* BWebFrame::Name() const
{
fName = WTF::String(Frame()->tree().uniqueName()).utf8().data();
return fName.String();
}
JSGlobalContextRef BWebFrame::GlobalContext() const
{
return toGlobalRef(Frame()->script().globalObject(mainThreadNormalWorld()));
}
WebCore::Frame* BWebFrame::Frame() const
{
return fData->frame;
}
BWebFrame* BWebFrame::AddChild(BWebPage* page, BString name,
WebCore::HTMLFrameOwnerElement* ownerElement)
{
WebFramePrivate* data = new WebFramePrivate(page->page());
data->name = name;
data->ownerElement = ownerElement;
BWebFrame* frame = new(std::nothrow) BWebFrame(page, this, data);
if (!frame)
return nullptr;
RefPtr<WebCore::Frame> coreFrame = WebCore::Frame::create(fData->page,
ownerElement, makeUniqueRef<FrameLoaderClientHaiku>(page));
// We don't keep the reference to the Frame, see WebFramePrivate.h.
data->frame = coreFrame.get();
FrameLoaderClientHaiku& client = static_cast<FrameLoaderClientHaiku&>(data->frame->loader().client());
client.setFrame(frame);
coreFrame->tree().setName(name.String());
if (ownerElement)
ownerElement->document().frame()->tree().appendChild(*coreFrame.get());
data->frame->init();
// TODO? evas_object_smart_member_add(frame, ewkFrame);
// The creation of the frame may have run arbitrary JavaScript that removed
// it from the page already.
if (!coreFrame->page()) {
return nullptr;
}
return frame;
}