1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2000 Simon Hausmann (hausmann@kde.org)
5 *           (C) 2001 Dirk Mueller (mueller@kde.org)
6 * Copyright (C) 2004, 2006, 2008, 2009 Apple Inc. All rights reserved.
7 * Copyright (C) 2009 Ericsson AB. All rights reserved.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB.  If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25#include "config.h"
26#include "core/html/HTMLIFrameElement.h"
27
28#include "bindings/core/v8/V8DOMActivityLogger.h"
29#include "core/CSSPropertyNames.h"
30#include "core/HTMLNames.h"
31#include "core/html/HTMLDocument.h"
32#include "core/inspector/ConsoleMessage.h"
33#include "core/rendering/RenderIFrame.h"
34
35namespace blink {
36
37using namespace HTMLNames;
38
39inline HTMLIFrameElement::HTMLIFrameElement(Document& document)
40    : HTMLFrameElementBase(iframeTag, document)
41    , m_didLoadNonEmptyDocument(false)
42{
43}
44
45DEFINE_NODE_FACTORY(HTMLIFrameElement)
46
47bool HTMLIFrameElement::isPresentationAttribute(const QualifiedName& name) const
48{
49    if (name == widthAttr || name == heightAttr || name == alignAttr || name == frameborderAttr)
50        return true;
51    return HTMLFrameElementBase::isPresentationAttribute(name);
52}
53
54void HTMLIFrameElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
55{
56    if (name == widthAttr)
57        addHTMLLengthToStyle(style, CSSPropertyWidth, value);
58    else if (name == heightAttr)
59        addHTMLLengthToStyle(style, CSSPropertyHeight, value);
60    else if (name == alignAttr)
61        applyAlignmentAttributeToStyle(value, style);
62    else if (name == frameborderAttr) {
63        // LocalFrame border doesn't really match the HTML4 spec definition for iframes. It simply adds
64        // a presentational hint that the border should be off if set to zero.
65        if (!value.toInt()) {
66            // Add a rule that nulls out our border width.
67            addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderWidth, 0, CSSPrimitiveValue::CSS_PX);
68        }
69    } else
70        HTMLFrameElementBase::collectStyleForPresentationAttribute(name, value, style);
71}
72
73void HTMLIFrameElement::attributeWillChange(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
74{
75    if (name == srcAttr && inDocument()) {
76        V8DOMActivityLogger* activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld();
77        if (activityLogger) {
78            Vector<String> argv;
79            argv.append("iframe");
80            argv.append(srcAttr.toString());
81            argv.append(oldValue);
82            argv.append(newValue);
83            activityLogger->logEvent("blinkSetAttribute", argv.size(), argv.data());
84        }
85    }
86    HTMLFrameElementBase::attributeWillChange(name, oldValue, newValue);
87}
88
89void HTMLIFrameElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
90{
91    if (name == nameAttr) {
92        if (inDocument() && document().isHTMLDocument() && !isInShadowTree()) {
93            HTMLDocument& document = toHTMLDocument(this->document());
94            document.removeExtraNamedItem(m_name);
95            document.addExtraNamedItem(value);
96        }
97        m_name = value;
98    } else if (name == sandboxAttr) {
99        String invalidTokens;
100        setSandboxFlags(value.isNull() ? SandboxNone : parseSandboxPolicy(value, invalidTokens));
101        if (!invalidTokens.isNull())
102            document().addConsoleMessage(ConsoleMessage::create(OtherMessageSource, ErrorMessageLevel, "Error while parsing the 'sandbox' attribute: " + invalidTokens));
103    } else {
104        HTMLFrameElementBase::parseAttribute(name, value);
105    }
106}
107
108bool HTMLIFrameElement::rendererIsNeeded(const RenderStyle& style)
109{
110    return isURLAllowed() && HTMLElement::rendererIsNeeded(style);
111}
112
113RenderObject* HTMLIFrameElement::createRenderer(RenderStyle*)
114{
115    return new RenderIFrame(this);
116}
117
118Node::InsertionNotificationRequest HTMLIFrameElement::insertedInto(ContainerNode* insertionPoint)
119{
120    if (insertionPoint->inDocument()) {
121        V8DOMActivityLogger* activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld();
122        if (activityLogger) {
123            Vector<String> argv;
124            argv.append("iframe");
125            argv.append(fastGetAttribute(srcAttr));
126            activityLogger->logEvent("blinkAddElement", argv.size(), argv.data());
127        }
128    }
129    InsertionNotificationRequest result = HTMLFrameElementBase::insertedInto(insertionPoint);
130    if (insertionPoint->inDocument() && document().isHTMLDocument() && !insertionPoint->isInShadowTree())
131        toHTMLDocument(document()).addExtraNamedItem(m_name);
132    return result;
133}
134
135void HTMLIFrameElement::removedFrom(ContainerNode* insertionPoint)
136{
137    HTMLFrameElementBase::removedFrom(insertionPoint);
138    if (insertionPoint->inDocument() && document().isHTMLDocument() && !insertionPoint->isInShadowTree())
139        toHTMLDocument(document()).removeExtraNamedItem(m_name);
140}
141
142bool HTMLIFrameElement::isInteractiveContent() const
143{
144    return true;
145}
146
147}
148