blob: 1e81f5425b07e24d9a9c1207eb35592172465c84 [file] [log] [blame]
darin@apple.coma3c493e2008-03-18 13:47:47 +00001/*
eseidel409f4302006-05-12 22:56:41 +00002 * 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)
darin@apple.com4c71dea2019-07-17 20:02:37 +00006 * Copyright (C) 2004-2019 Apple Inc. All rights reserved.
abarth@webkit.orgb8a10552009-12-02 02:40:35 +00007 * Copyright (C) 2009 Ericsson AB. All rights reserved.
eseidel409f4302006-05-12 22:56:41 +00008 *
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
ddkilzerc8eccec2007-09-26 02:29:57 +000021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
eseidel409f4302006-05-12 22:56:41 +000023 */
darin@apple.coma3c493e2008-03-18 13:47:47 +000024
eseidel409f4302006-05-12 22:56:41 +000025#include "config.h"
26#include "HTMLIFrameElement.h"
27
28#include "CSSPropertyNames.h"
cdumez@apple.com786d8892016-04-11 18:49:13 +000029#include "DOMTokenList.h"
jer.noble@apple.com872903d2021-10-08 23:31:51 +000030#include "ElementInlines.h"
eseidel409f4302006-05-12 22:56:41 +000031#include "Frame.h"
eseidel409f4302006-05-12 22:56:41 +000032#include "HTMLNames.h"
aperez@igalia.comf113ebb2021-05-21 13:52:45 +000033#include "HTMLParserIdioms.h"
commit-queue@webkit.org87bc9132020-09-12 08:35:27 +000034#include "LazyLoadFrameObserver.h"
simon.fraser@apple.com5d284af2010-04-20 04:02:54 +000035#include "RenderIFrame.h"
don.olmstead@sony.comabd1edb2020-12-07 17:50:51 +000036#include "ScriptController.h"
mkwst@chromium.org04b67ee2012-11-15 13:04:54 +000037#include "ScriptableDocumentParser.h"
weinig@apple.com52162662020-08-31 18:16:31 +000038#include "Settings.h"
fpizlo@apple.com197cd322018-03-17 06:11:00 +000039#include <wtf/IsoMallocInlines.h>
eseidel409f4302006-05-12 22:56:41 +000040
41namespace WebCore {
42
fpizlo@apple.com197cd322018-03-17 06:11:00 +000043WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLIFrameElement);
44
eseidel409f4302006-05-12 22:56:41 +000045using namespace HTMLNames;
46
weinig@apple.com6becaaf2013-09-14 21:33:13 +000047inline HTMLIFrameElement::HTMLIFrameElement(const QualifiedName& tagName, Document& document)
weinig@apple.comdedf67e2013-09-15 05:23:01 +000048 : HTMLFrameElementBase(tagName, document)
eseidel409f4302006-05-12 22:56:41 +000049{
jchaffraix@webkit.org74dae402008-12-01 23:07:04 +000050 ASSERT(hasTagName(iframeTag));
eseidel409f4302006-05-12 22:56:41 +000051}
52
weinig@apple.com02f433a2015-01-06 22:32:48 +000053Ref<HTMLIFrameElement> HTMLIFrameElement::create(const QualifiedName& tagName, Document& document)
darin@apple.comcf9dd0f2009-08-23 06:55:57 +000054{
weinig@apple.com02f433a2015-01-06 22:32:48 +000055 return adoptRef(*new HTMLIFrameElement(tagName, document));
darin@apple.comcf9dd0f2009-08-23 06:55:57 +000056}
57
rniwa@webkit.orgfa9cad42019-08-29 03:14:24 +000058int HTMLIFrameElement::defaultTabIndex() const
59{
60 return 0;
61}
62
cdumez@apple.com5863cc72016-02-04 16:57:44 +000063DOMTokenList& HTMLIFrameElement::sandbox()
cdumez@apple.com264cc032015-10-21 17:00:18 +000064{
darin@apple.com4c71dea2019-07-17 20:02:37 +000065 if (!m_sandbox) {
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +000066 m_sandbox = makeUnique<DOMTokenList>(*this, sandboxAttr, [](Document&, StringView token) {
cdumez@apple.com2cfb7a42016-09-28 23:49:50 +000067 return SecurityContext::isSupportedSandboxPolicy(token);
68 });
darin@apple.com4c71dea2019-07-17 20:02:37 +000069 }
cdumez@apple.com264cc032015-10-21 17:00:18 +000070 return *m_sandbox;
71}
72
antti@apple.comeceeb442021-05-31 15:02:54 +000073bool HTMLIFrameElement::hasPresentationalHintsForAttribute(const QualifiedName& name) const
kling@webkit.org8b0e8432012-02-11 19:29:49 +000074{
rniwa@webkit.org3d4aa8a2019-01-14 22:51:56 +000075 if (name == widthAttr || name == heightAttr || name == frameborderAttr)
kling@webkit.org11f25562012-02-13 10:36:55 +000076 return true;
antti@apple.comeceeb442021-05-31 15:02:54 +000077 return HTMLFrameElementBase::hasPresentationalHintsForAttribute(name);
kling@webkit.org8b0e8432012-02-11 19:29:49 +000078}
79
antti@apple.comeceeb442021-05-31 15:02:54 +000080void HTMLIFrameElement::collectPresentationalHintsForAttribute(const QualifiedName& name, const AtomString& value, MutableStyleProperties& style)
eseidel409f4302006-05-12 22:56:41 +000081{
akling@apple.comb75eeea2013-02-23 17:57:50 +000082 if (name == widthAttr)
83 addHTMLLengthToStyle(style, CSSPropertyWidth, value);
84 else if (name == heightAttr)
85 addHTMLLengthToStyle(style, CSSPropertyHeight, value);
86 else if (name == alignAttr)
87 applyAlignmentAttributeToStyle(value, style);
88 else if (name == frameborderAttr) {
kling@webkit.org8b0e8432012-02-11 19:29:49 +000089 // Frame border doesn't really match the HTML4 spec definition for iframes. It simply adds
90 // a presentational hint that the border should be off if set to zero.
darin@apple.com70624482021-05-10 16:57:02 +000091 if (!parseHTMLInteger(value).value_or(0)) {
kling@webkit.org8b0e8432012-02-11 19:29:49 +000092 // Add a rule that nulls out our border width.
antti@apple.comeceeb442021-05-31 15:02:54 +000093 addPropertyToPresentationalHintStyle(style, CSSPropertyBorderWidth, 0, CSSUnitType::CSS_PX);
kling@webkit.org8b0e8432012-02-11 19:29:49 +000094 }
kling@webkit.org11f25562012-02-13 10:36:55 +000095 } else
antti@apple.comeceeb442021-05-31 15:02:54 +000096 HTMLFrameElementBase::collectPresentationalHintsForAttribute(name, value, style);
kling@webkit.org8b0e8432012-02-11 19:29:49 +000097}
98
darin@apple.com0ce67df2019-06-17 01:48:13 +000099void HTMLIFrameElement::parseAttribute(const QualifiedName& name, const AtomString& value)
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000100{
rniwa@webkit.org068215b2013-05-07 00:20:05 +0000101 if (name == sandboxAttr) {
cdumez@apple.com264cc032015-10-21 17:00:18 +0000102 if (m_sandbox)
cdumez@apple.comf8aea812016-04-12 16:21:50 +0000103 m_sandbox->associatedAttributeValueChanged(value);
cdumez@apple.com264cc032015-10-21 17:00:18 +0000104
mkwst@chromium.org04b67ee2012-11-15 13:04:54 +0000105 String invalidTokens;
akling@apple.com43e9d042012-11-18 16:55:06 +0000106 setSandboxFlags(value.isNull() ? SandboxNone : SecurityContext::parseSandboxPolicy(value, invalidTokens));
mkwst@chromium.orgd2e0adc2012-12-05 10:02:25 +0000107 if (!invalidTokens.isNull())
joepeck@webkit.org1f45df92014-02-06 23:45:53 +0000108 document().addConsoleMessage(MessageSource::Other, MessageLevel::Error, "Error while parsing the 'sandbox' attribute: " + invalidTokens);
commit-queue@webkit.org87bc9132020-09-12 08:35:27 +0000109 } else if (name == allowAttr || name == allowfullscreenAttr || name == webkitallowfullscreenAttr) {
darin@apple.com7c840b62021-05-28 01:26:23 +0000110 m_featurePolicy = std::nullopt;
commit-queue@webkit.org87bc9132020-09-12 08:35:27 +0000111 } else if (name == loadingAttr) {
112 // Allow loading=eager to load the frame immediately if the lazy load was started, but
113 // do not allow the reverse situation since the eager load is already started.
114 if (m_lazyLoadFrameObserver && !equalLettersIgnoringASCIICase(value, "lazy")) {
115 m_lazyLoadFrameObserver->unobserve();
116 loadDeferredFrame();
117 }
118 } else
akling@apple.com43e9d042012-11-18 16:55:06 +0000119 HTMLFrameElementBase::parseAttribute(name, value);
eseidel409f4302006-05-12 22:56:41 +0000120}
121
antti@apple.comb74dfb62013-08-20 21:22:53 +0000122bool HTMLIFrameElement::rendererIsNeeded(const RenderStyle& style)
ggaren31614e22006-10-13 20:22:08 +0000123{
darin@apple.com4c71dea2019-07-17 20:02:37 +0000124 return style.display() != DisplayType::None && canLoad();
ggaren31614e22006-10-13 20:22:08 +0000125}
126
antti@apple.com454418f2016-04-25 19:49:23 +0000127RenderPtr<RenderElement> HTMLIFrameElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
ggaren31614e22006-10-13 20:22:08 +0000128{
aestes@apple.com13aae082016-01-02 08:03:08 +0000129 return createRenderer<RenderIFrame>(*this, WTFMove(style));
ggaren31614e22006-10-13 20:22:08 +0000130}
131
darin@apple.com0ce67df2019-06-17 01:48:13 +0000132void HTMLIFrameElement::setReferrerPolicyForBindings(const AtomString& value)
commit-queue@webkit.orgf59b72d2019-03-06 11:28:38 +0000133{
134 setAttributeWithoutSynchronization(referrerpolicyAttr, value);
135}
136
137String HTMLIFrameElement::referrerPolicyForBindings() const
138{
commit-queue@webkit.org9e8f8452019-07-17 09:03:37 +0000139 return referrerPolicyToString(referrerPolicy());
commit-queue@webkit.orgf59b72d2019-03-06 11:28:38 +0000140}
141
142ReferrerPolicy HTMLIFrameElement::referrerPolicy() const
143{
commit-queue@webkit.org87bc9132020-09-12 08:35:27 +0000144 if (m_lazyLoadFrameObserver)
145 return m_lazyLoadFrameObserver->referrerPolicy();
weinig@apple.com52162662020-08-31 18:16:31 +0000146 if (document().settings().referrerPolicyAttributeEnabled())
darin@apple.com7c840b62021-05-28 01:26:23 +0000147 return parseReferrerPolicy(attributeWithoutSynchronization(referrerpolicyAttr), ReferrerPolicySource::ReferrerPolicyAttribute).value_or(ReferrerPolicy::EmptyString);
commit-queue@webkit.orgf59b72d2019-03-06 11:28:38 +0000148 return ReferrerPolicy::EmptyString;
149}
150
youenn@apple.com2b8b02f2019-05-22 17:38:42 +0000151const FeaturePolicy& HTMLIFrameElement::featurePolicy() const
152{
153 if (!m_featurePolicy)
commit-queue@webkit.org5f0dc042020-01-27 20:54:54 +0000154 m_featurePolicy = FeaturePolicy::parse(document(), *this, attributeWithoutSynchronization(allowAttr));
youenn@apple.com2b8b02f2019-05-22 17:38:42 +0000155 return *m_featurePolicy;
156}
157
commit-queue@webkit.org87bc9132020-09-12 08:35:27 +0000158const AtomString& HTMLIFrameElement::loadingForBindings() const
159{
160 static MainThreadNeverDestroyed<const AtomString> eager("eager", AtomString::ConstructFromLiteral);
161 static MainThreadNeverDestroyed<const AtomString> lazy("lazy", AtomString::ConstructFromLiteral);
162 return equalLettersIgnoringASCIICase(attributeWithoutSynchronization(HTMLNames::loadingAttr), "lazy") ? lazy : eager;
163}
164
165void HTMLIFrameElement::setLoadingForBindings(const AtomString& value)
166{
167 setAttributeWithoutSynchronization(loadingAttr, value);
168}
169
commit-queue@webkit.orgb4b915a2020-12-01 17:14:28 +0000170static bool isFrameLazyLoadable(const Document& document, const URL& completeURL, const AtomString& loadingAttributeValue)
commit-queue@webkit.org87bc9132020-09-12 08:35:27 +0000171{
172 if (!completeURL.protocolIsInHTTPFamily())
173 return false;
174
commit-queue@webkit.orgb4b915a2020-12-01 17:14:28 +0000175 if (!document.frame() || !document.frame()->script().canExecuteScripts(NotAboutToExecuteScript))
176 return false;
177
commit-queue@webkit.org87bc9132020-09-12 08:35:27 +0000178 return equalLettersIgnoringASCIICase(loadingAttributeValue, "lazy");
179}
180
181bool HTMLIFrameElement::shouldLoadFrameLazily()
182{
183 if (!m_lazyLoadFrameObserver && document().settings().lazyIframeLoadingEnabled()) {
184 URL completeURL = document().completeURL(frameURL());
commit-queue@webkit.orgb4b915a2020-12-01 17:14:28 +0000185 if (isFrameLazyLoadable(document(), completeURL, attributeWithoutSynchronization(HTMLNames::loadingAttr))) {
commit-queue@webkit.org87bc9132020-09-12 08:35:27 +0000186 auto currentReferrerPolicy = referrerPolicy();
187 lazyLoadFrameObserver().observe(completeURL.string(), currentReferrerPolicy);
188 return true;
189 }
190 }
191 return false;
192}
193
194bool HTMLIFrameElement::isLazyLoadObserverActive() const
195{
196 return !!m_lazyLoadFrameObserver;
197}
198
199void HTMLIFrameElement::loadDeferredFrame()
200{
201 AtomString currentURL = frameURL();
202 setFrameURL(m_lazyLoadFrameObserver->frameURL());
203 openURL();
204 setFrameURL(currentURL);
205 m_lazyLoadFrameObserver = nullptr;
206}
207
208LazyLoadFrameObserver& HTMLIFrameElement::lazyLoadFrameObserver()
209{
210 if (!m_lazyLoadFrameObserver)
211 m_lazyLoadFrameObserver = makeUnique<LazyLoadFrameObserver>(*this);
212 return *m_lazyLoadFrameObserver;
213}
214
eseidel409f4302006-05-12 22:56:41 +0000215}