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 "HTMLIFrameElement.h"
27
28#include "CSSPropertyNames.h"
29#include "DOMTokenList.h"
30#include "Frame.h"
31#include "HTMLNames.h"
32#include "RenderIFrame.h"
33#include "RuntimeEnabledFeatures.h"
34#include "ScriptableDocumentParser.h"
35#include <wtf/IsoMallocInlines.h>
36
37namespace WebCore {
38
39WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLIFrameElement);
40
41using namespace HTMLNames;
42
43inline HTMLIFrameElement::HTMLIFrameElement(const QualifiedName& tagName, Document& document)
44 : HTMLFrameElementBase(tagName, document)
45{
46 ASSERT(hasTagName(iframeTag));
47}
48
49Ref<HTMLIFrameElement> HTMLIFrameElement::create(const QualifiedName& tagName, Document& document)
50{
51 return adoptRef(*new HTMLIFrameElement(tagName, document));
52}
53
54DOMTokenList& HTMLIFrameElement::sandbox()
55{
56 if (!m_sandbox)
57 m_sandbox = std::make_unique<DOMTokenList>(*this, sandboxAttr, [](Document&, StringView token) {
58 return SecurityContext::isSupportedSandboxPolicy(token);
59 });
60 return *m_sandbox;
61}
62
63bool HTMLIFrameElement::isPresentationAttribute(const QualifiedName& name) const
64{
65 if (name == widthAttr || name == heightAttr || name == frameborderAttr)
66 return true;
67 return HTMLFrameElementBase::isPresentationAttribute(name);
68}
69
70void HTMLIFrameElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
71{
72 if (name == widthAttr)
73 addHTMLLengthToStyle(style, CSSPropertyWidth, value);
74 else if (name == heightAttr)
75 addHTMLLengthToStyle(style, CSSPropertyHeight, value);
76 else if (name == alignAttr)
77 applyAlignmentAttributeToStyle(value, style);
78 else if (name == frameborderAttr) {
79 // Frame border doesn't really match the HTML4 spec definition for iframes. It simply adds
80 // a presentational hint that the border should be off if set to zero.
81 if (!value.toInt()) {
82 // Add a rule that nulls out our border width.
83 addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderWidth, 0, CSSPrimitiveValue::CSS_PX);
84 }
85 } else
86 HTMLFrameElementBase::collectStyleForPresentationAttribute(name, value, style);
87}
88
89void HTMLIFrameElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
90{
91 if (name == sandboxAttr) {
92 if (m_sandbox)
93 m_sandbox->associatedAttributeValueChanged(value);
94
95 String invalidTokens;
96 setSandboxFlags(value.isNull() ? SandboxNone : SecurityContext::parseSandboxPolicy(value, invalidTokens));
97 if (!invalidTokens.isNull())
98 document().addConsoleMessage(MessageSource::Other, MessageLevel::Error, "Error while parsing the 'sandbox' attribute: " + invalidTokens);
99 } else if (name == allowAttr)
100 m_allow = value;
101 else
102 HTMLFrameElementBase::parseAttribute(name, value);
103}
104
105bool HTMLIFrameElement::rendererIsNeeded(const RenderStyle& style)
106{
107 return isURLAllowed() && style.display() != DisplayType::None;
108}
109
110RenderPtr<RenderElement> HTMLIFrameElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
111{
112 return createRenderer<RenderIFrame>(*this, WTFMove(style));
113}
114
115void HTMLIFrameElement::setReferrerPolicyForBindings(const AtomicString& value)
116{
117 setAttributeWithoutSynchronization(referrerpolicyAttr, value);
118}
119
120String HTMLIFrameElement::referrerPolicyForBindings() const
121{
122 switch (referrerPolicy()) {
123 case ReferrerPolicy::NoReferrer:
124 return "no-referrer"_s;
125 case ReferrerPolicy::UnsafeUrl:
126 return "unsafe-url"_s;
127 case ReferrerPolicy::Origin:
128 return "origin"_s;
129 case ReferrerPolicy::OriginWhenCrossOrigin:
130 return "origin-when-cross-origin"_s;
131 case ReferrerPolicy::SameOrigin:
132 return "same-origin"_s;
133 case ReferrerPolicy::StrictOrigin:
134 return "strict-origin"_s;
135 case ReferrerPolicy::StrictOriginWhenCrossOrigin:
136 return "strict-origin-when-cross-origin"_s;
137 case ReferrerPolicy::NoReferrerWhenDowngrade:
138 return "no-referrer-when-downgrade"_s;
139 case ReferrerPolicy::EmptyString:
140 return { };
141 }
142 ASSERT_NOT_REACHED();
143 return { };
144}
145
146ReferrerPolicy HTMLIFrameElement::referrerPolicy() const
147{
148 if (RuntimeEnabledFeatures::sharedFeatures().referrerPolicyAttributeEnabled())
149 return parseReferrerPolicy(attributeWithoutSynchronization(referrerpolicyAttr), ReferrerPolicySource::ReferrerPolicyAttribute).valueOr(ReferrerPolicy::EmptyString);
150 return ReferrerPolicy::EmptyString;
151}
152
153}
154