HTMLFrameElementBase.cpp [plain text]
#include "config.h"
#include "HTMLFrameElementBase.h"
#include "CSSHelper.h"
#include "Document.h"
#include "EventNames.h"
#include "FocusController.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
#include "ScriptEventListener.h"
#include "KURL.h"
#include "MappedAttribute.h"
#include "Page.h"
#include "RenderFrame.h"
#include "Settings.h"
namespace WebCore {
using namespace HTMLNames;
HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Document* document)
: HTMLFrameOwnerElement(tagName, document)
, m_scrolling(ScrollbarAuto)
, m_marginWidth(-1)
, m_marginHeight(-1)
, m_checkAttachedTimer(this, &HTMLFrameElementBase::checkAttachedTimerFired)
, m_viewSource(false)
, m_shouldOpenURLAfterAttach(false)
, m_remainsAliveOnRemovalFromTree(false)
{
}
bool HTMLFrameElementBase::isURLAllowed() const
{
if (m_URL.isEmpty())
return true;
const KURL& completeURL = document()->completeURL(m_URL);
if (Frame* parentFrame = document()->frame()) {
if (parentFrame->page()->frameCount() > 200)
return false;
}
bool foundSelfReference = false;
for (Frame* frame = document()->frame(); frame; frame = frame->tree()->parent()) {
if (equalIgnoringFragmentIdentifier(frame->loader()->url(), completeURL)) {
if (foundSelfReference)
return false;
foundSelfReference = true;
}
}
return true;
}
void HTMLFrameElementBase::openURL(bool lockHistory, bool lockBackForwardList)
{
ASSERT(!m_frameName.isEmpty());
if (!isURLAllowed())
return;
if (m_URL.isEmpty())
m_URL = blankURL().string();
Frame* parentFrame = document()->frame();
if (!parentFrame)
return;
parentFrame->loader()->requestFrame(this, m_URL, m_frameName, lockHistory, lockBackForwardList);
if (contentFrame())
contentFrame()->setInViewSourceMode(viewSourceMode());
}
void HTMLFrameElementBase::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == srcAttr)
setLocation(deprecatedParseURL(attr->value()));
else if (attr->name() == idAttributeName()) {
HTMLFrameOwnerElement::parseMappedAttribute(attr);
m_frameName = attr->value();
} else if (attr->name() == nameAttr) {
m_frameName = attr->value();
} else if (attr->name() == marginwidthAttr) {
m_marginWidth = attr->value().toInt();
} else if (attr->name() == marginheightAttr) {
m_marginHeight = attr->value().toInt();
} else if (attr->name() == scrollingAttr) {
if (equalIgnoringCase(attr->value(), "auto") || equalIgnoringCase(attr->value(), "yes"))
m_scrolling = document()->frameElementsShouldIgnoreScrolling() ? ScrollbarAlwaysOff : ScrollbarAuto;
else if (equalIgnoringCase(attr->value(), "no"))
m_scrolling = ScrollbarAlwaysOff;
} else if (attr->name() == viewsourceAttr) {
m_viewSource = !attr->isNull();
if (contentFrame())
contentFrame()->setInViewSourceMode(viewSourceMode());
} else if (attr->name() == onloadAttr)
setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
else if (attr->name() == onbeforeloadAttr)
setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
else if (attr->name() == onbeforeunloadAttr) {
setAttributeEventListener(eventNames().beforeunloadEvent, createAttributeEventListener(this, attr));
} else
HTMLFrameOwnerElement::parseMappedAttribute(attr);
}
void HTMLFrameElementBase::setName()
{
m_frameName = getAttribute(nameAttr);
if (m_frameName.isNull())
m_frameName = getAttribute(idAttributeName());
if (Frame* parentFrame = document()->frame())
m_frameName = parentFrame->tree()->uniqueChildName(m_frameName);
}
void HTMLFrameElementBase::setNameAndOpenURL()
{
setName();
openURL();
}
void HTMLFrameElementBase::setNameAndOpenURLCallback(Node* n)
{
static_cast<HTMLFrameElementBase*>(n)->setNameAndOpenURL();
}
void HTMLFrameElementBase::updateOnReparenting()
{
ASSERT(m_remainsAliveOnRemovalFromTree);
if (Frame* frame = contentFrame())
frame->transferChildFrameToNewDocument();
}
void HTMLFrameElementBase::insertedIntoDocument()
{
HTMLFrameOwnerElement::insertedIntoDocument();
m_shouldOpenURLAfterAttach = true;
if (m_remainsAliveOnRemovalFromTree)
updateOnReparenting();
}
void HTMLFrameElementBase::removedFromDocument()
{
m_shouldOpenURLAfterAttach = false;
HTMLFrameOwnerElement::removedFromDocument();
}
void HTMLFrameElementBase::attach()
{
if (m_shouldOpenURLAfterAttach) {
m_shouldOpenURLAfterAttach = false;
if (!m_remainsAliveOnRemovalFromTree)
queuePostAttachCallback(&HTMLFrameElementBase::setNameAndOpenURLCallback, this);
}
setRemainsAliveOnRemovalFromTree(false);
HTMLFrameOwnerElement::attach();
if (RenderPart* renderPart = toRenderPart(renderer())) {
if (Frame* frame = contentFrame())
renderPart->setWidget(frame->view());
}
}
KURL HTMLFrameElementBase::location() const
{
return document()->completeURL(getAttribute(srcAttr));
}
void HTMLFrameElementBase::setLocation(const String& str)
{
Settings* settings = document()->settings();
if (settings && settings->needsAcrobatFrameReloadingQuirk() && m_URL == str)
return;
m_URL = AtomicString(str);
if (inDocument())
openURL(false, false);
}
bool HTMLFrameElementBase::supportsFocus() const
{
return true;
}
void HTMLFrameElementBase::setFocus(bool received)
{
HTMLFrameOwnerElement::setFocus(received);
if (Page* page = document()->page()) {
if (received)
page->focusController()->setFocusedFrame(contentFrame());
else if (page->focusController()->focusedFrame() == contentFrame()) page->focusController()->setFocusedFrame(0);
}
}
bool HTMLFrameElementBase::isURLAttribute(Attribute *attr) const
{
return attr->name() == srcAttr;
}
int HTMLFrameElementBase::width() const
{
if (!renderer())
return 0;
document()->updateLayoutIgnorePendingStylesheets();
return toRenderBox(renderer())->width();
}
int HTMLFrameElementBase::height() const
{
if (!renderer())
return 0;
document()->updateLayoutIgnorePendingStylesheets();
return toRenderBox(renderer())->height();
}
void HTMLFrameElementBase::setRemainsAliveOnRemovalFromTree(bool value)
{
m_remainsAliveOnRemovalFromTree = value;
if (value)
m_checkAttachedTimer.startOneShot(0);
else
m_checkAttachedTimer.stop();
}
void HTMLFrameElementBase::checkAttachedTimerFired(Timer<HTMLFrameElementBase>*)
{
ASSERT(!attached());
ASSERT(m_remainsAliveOnRemovalFromTree);
m_remainsAliveOnRemovalFromTree = false;
willRemove();
}
void HTMLFrameElementBase::willRemove()
{
if (m_remainsAliveOnRemovalFromTree)
return;
HTMLFrameOwnerElement::willRemove();
}
}