darin@apple.com | a3c493e | 2008-03-18 13:47:47 +0000 | [diff] [blame] | 1 | /* |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 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) |
darin@apple.com | 4c71dea | 2019-07-17 20:02:37 +0000 | [diff] [blame] | 6 | * Copyright (C) 2004-2019 Apple Inc. All rights reserved. |
abarth@webkit.org | b8a1055 | 2009-12-02 02:40:35 +0000 | [diff] [blame] | 7 | * Copyright (C) 2009 Ericsson AB. All rights reserved. |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 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 |
ddkilzer | c8eccec | 2007-09-26 02:29:57 +0000 | [diff] [blame] | 21 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 22 | * Boston, MA 02110-1301, USA. |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 23 | */ |
darin@apple.com | a3c493e | 2008-03-18 13:47:47 +0000 | [diff] [blame] | 24 | |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 25 | #include "config.h" |
| 26 | #include "HTMLIFrameElement.h" |
| 27 | |
| 28 | #include "CSSPropertyNames.h" |
cdumez@apple.com | 786d889 | 2016-04-11 18:49:13 +0000 | [diff] [blame] | 29 | #include "DOMTokenList.h" |
jer.noble@apple.com | 872903d | 2021-10-08 23:31:51 +0000 | [diff] [blame] | 30 | #include "ElementInlines.h" |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 31 | #include "Frame.h" |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 32 | #include "HTMLNames.h" |
aperez@igalia.com | f113ebb | 2021-05-21 13:52:45 +0000 | [diff] [blame] | 33 | #include "HTMLParserIdioms.h" |
commit-queue@webkit.org | 87bc913 | 2020-09-12 08:35:27 +0000 | [diff] [blame] | 34 | #include "LazyLoadFrameObserver.h" |
simon.fraser@apple.com | 5d284af | 2010-04-20 04:02:54 +0000 | [diff] [blame] | 35 | #include "RenderIFrame.h" |
don.olmstead@sony.com | abd1edb | 2020-12-07 17:50:51 +0000 | [diff] [blame] | 36 | #include "ScriptController.h" |
mkwst@chromium.org | 04b67ee | 2012-11-15 13:04:54 +0000 | [diff] [blame] | 37 | #include "ScriptableDocumentParser.h" |
weinig@apple.com | 5216266 | 2020-08-31 18:16:31 +0000 | [diff] [blame] | 38 | #include "Settings.h" |
fpizlo@apple.com | 197cd32 | 2018-03-17 06:11:00 +0000 | [diff] [blame] | 39 | #include <wtf/IsoMallocInlines.h> |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 40 | |
| 41 | namespace WebCore { |
| 42 | |
fpizlo@apple.com | 197cd32 | 2018-03-17 06:11:00 +0000 | [diff] [blame] | 43 | WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLIFrameElement); |
| 44 | |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 45 | using namespace HTMLNames; |
| 46 | |
weinig@apple.com | 6becaaf | 2013-09-14 21:33:13 +0000 | [diff] [blame] | 47 | inline HTMLIFrameElement::HTMLIFrameElement(const QualifiedName& tagName, Document& document) |
weinig@apple.com | dedf67e | 2013-09-15 05:23:01 +0000 | [diff] [blame] | 48 | : HTMLFrameElementBase(tagName, document) |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 49 | { |
jchaffraix@webkit.org | 74dae40 | 2008-12-01 23:07:04 +0000 | [diff] [blame] | 50 | ASSERT(hasTagName(iframeTag)); |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 51 | } |
| 52 | |
weinig@apple.com | 02f433a | 2015-01-06 22:32:48 +0000 | [diff] [blame] | 53 | Ref<HTMLIFrameElement> HTMLIFrameElement::create(const QualifiedName& tagName, Document& document) |
darin@apple.com | cf9dd0f | 2009-08-23 06:55:57 +0000 | [diff] [blame] | 54 | { |
weinig@apple.com | 02f433a | 2015-01-06 22:32:48 +0000 | [diff] [blame] | 55 | return adoptRef(*new HTMLIFrameElement(tagName, document)); |
darin@apple.com | cf9dd0f | 2009-08-23 06:55:57 +0000 | [diff] [blame] | 56 | } |
| 57 | |
rniwa@webkit.org | fa9cad4 | 2019-08-29 03:14:24 +0000 | [diff] [blame] | 58 | int HTMLIFrameElement::defaultTabIndex() const |
| 59 | { |
| 60 | return 0; |
| 61 | } |
| 62 | |
cdumez@apple.com | 5863cc7 | 2016-02-04 16:57:44 +0000 | [diff] [blame] | 63 | DOMTokenList& HTMLIFrameElement::sandbox() |
cdumez@apple.com | 264cc03 | 2015-10-21 17:00:18 +0000 | [diff] [blame] | 64 | { |
darin@apple.com | 4c71dea | 2019-07-17 20:02:37 +0000 | [diff] [blame] | 65 | if (!m_sandbox) { |
ysuzuki@apple.com | 1d8e24d | 2019-08-19 06:59:40 +0000 | [diff] [blame] | 66 | m_sandbox = makeUnique<DOMTokenList>(*this, sandboxAttr, [](Document&, StringView token) { |
cdumez@apple.com | 2cfb7a4 | 2016-09-28 23:49:50 +0000 | [diff] [blame] | 67 | return SecurityContext::isSupportedSandboxPolicy(token); |
| 68 | }); |
darin@apple.com | 4c71dea | 2019-07-17 20:02:37 +0000 | [diff] [blame] | 69 | } |
cdumez@apple.com | 264cc03 | 2015-10-21 17:00:18 +0000 | [diff] [blame] | 70 | return *m_sandbox; |
| 71 | } |
| 72 | |
antti@apple.com | eceeb44 | 2021-05-31 15:02:54 +0000 | [diff] [blame] | 73 | bool HTMLIFrameElement::hasPresentationalHintsForAttribute(const QualifiedName& name) const |
kling@webkit.org | 8b0e843 | 2012-02-11 19:29:49 +0000 | [diff] [blame] | 74 | { |
rniwa@webkit.org | 3d4aa8a | 2019-01-14 22:51:56 +0000 | [diff] [blame] | 75 | if (name == widthAttr || name == heightAttr || name == frameborderAttr) |
kling@webkit.org | 11f2556 | 2012-02-13 10:36:55 +0000 | [diff] [blame] | 76 | return true; |
antti@apple.com | eceeb44 | 2021-05-31 15:02:54 +0000 | [diff] [blame] | 77 | return HTMLFrameElementBase::hasPresentationalHintsForAttribute(name); |
kling@webkit.org | 8b0e843 | 2012-02-11 19:29:49 +0000 | [diff] [blame] | 78 | } |
| 79 | |
antti@apple.com | eceeb44 | 2021-05-31 15:02:54 +0000 | [diff] [blame] | 80 | void HTMLIFrameElement::collectPresentationalHintsForAttribute(const QualifiedName& name, const AtomString& value, MutableStyleProperties& style) |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 81 | { |
akling@apple.com | b75eeea | 2013-02-23 17:57:50 +0000 | [diff] [blame] | 82 | 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.org | 8b0e843 | 2012-02-11 19:29:49 +0000 | [diff] [blame] | 89 | // 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.com | 7062448 | 2021-05-10 16:57:02 +0000 | [diff] [blame] | 91 | if (!parseHTMLInteger(value).value_or(0)) { |
kling@webkit.org | 8b0e843 | 2012-02-11 19:29:49 +0000 | [diff] [blame] | 92 | // Add a rule that nulls out our border width. |
antti@apple.com | eceeb44 | 2021-05-31 15:02:54 +0000 | [diff] [blame] | 93 | addPropertyToPresentationalHintStyle(style, CSSPropertyBorderWidth, 0, CSSUnitType::CSS_PX); |
kling@webkit.org | 8b0e843 | 2012-02-11 19:29:49 +0000 | [diff] [blame] | 94 | } |
kling@webkit.org | 11f2556 | 2012-02-13 10:36:55 +0000 | [diff] [blame] | 95 | } else |
antti@apple.com | eceeb44 | 2021-05-31 15:02:54 +0000 | [diff] [blame] | 96 | HTMLFrameElementBase::collectPresentationalHintsForAttribute(name, value, style); |
kling@webkit.org | 8b0e843 | 2012-02-11 19:29:49 +0000 | [diff] [blame] | 97 | } |
| 98 | |
darin@apple.com | 0ce67df | 2019-06-17 01:48:13 +0000 | [diff] [blame] | 99 | void HTMLIFrameElement::parseAttribute(const QualifiedName& name, const AtomString& value) |
kling@webkit.org | 8b0e843 | 2012-02-11 19:29:49 +0000 | [diff] [blame] | 100 | { |
rniwa@webkit.org | 068215b | 2013-05-07 00:20:05 +0000 | [diff] [blame] | 101 | if (name == sandboxAttr) { |
cdumez@apple.com | 264cc03 | 2015-10-21 17:00:18 +0000 | [diff] [blame] | 102 | if (m_sandbox) |
cdumez@apple.com | f8aea81 | 2016-04-12 16:21:50 +0000 | [diff] [blame] | 103 | m_sandbox->associatedAttributeValueChanged(value); |
cdumez@apple.com | 264cc03 | 2015-10-21 17:00:18 +0000 | [diff] [blame] | 104 | |
mkwst@chromium.org | 04b67ee | 2012-11-15 13:04:54 +0000 | [diff] [blame] | 105 | String invalidTokens; |
akling@apple.com | 43e9d04 | 2012-11-18 16:55:06 +0000 | [diff] [blame] | 106 | setSandboxFlags(value.isNull() ? SandboxNone : SecurityContext::parseSandboxPolicy(value, invalidTokens)); |
mkwst@chromium.org | d2e0adc | 2012-12-05 10:02:25 +0000 | [diff] [blame] | 107 | if (!invalidTokens.isNull()) |
joepeck@webkit.org | 1f45df9 | 2014-02-06 23:45:53 +0000 | [diff] [blame] | 108 | document().addConsoleMessage(MessageSource::Other, MessageLevel::Error, "Error while parsing the 'sandbox' attribute: " + invalidTokens); |
commit-queue@webkit.org | 87bc913 | 2020-09-12 08:35:27 +0000 | [diff] [blame] | 109 | } else if (name == allowAttr || name == allowfullscreenAttr || name == webkitallowfullscreenAttr) { |
darin@apple.com | 7c840b6 | 2021-05-28 01:26:23 +0000 | [diff] [blame] | 110 | m_featurePolicy = std::nullopt; |
commit-queue@webkit.org | 87bc913 | 2020-09-12 08:35:27 +0000 | [diff] [blame] | 111 | } 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.com | 43e9d04 | 2012-11-18 16:55:06 +0000 | [diff] [blame] | 119 | HTMLFrameElementBase::parseAttribute(name, value); |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 120 | } |
| 121 | |
antti@apple.com | b74dfb6 | 2013-08-20 21:22:53 +0000 | [diff] [blame] | 122 | bool HTMLIFrameElement::rendererIsNeeded(const RenderStyle& style) |
ggaren | 31614e2 | 2006-10-13 20:22:08 +0000 | [diff] [blame] | 123 | { |
darin@apple.com | 4c71dea | 2019-07-17 20:02:37 +0000 | [diff] [blame] | 124 | return style.display() != DisplayType::None && canLoad(); |
ggaren | 31614e2 | 2006-10-13 20:22:08 +0000 | [diff] [blame] | 125 | } |
| 126 | |
antti@apple.com | 454418f | 2016-04-25 19:49:23 +0000 | [diff] [blame] | 127 | RenderPtr<RenderElement> HTMLIFrameElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) |
ggaren | 31614e2 | 2006-10-13 20:22:08 +0000 | [diff] [blame] | 128 | { |
aestes@apple.com | 13aae08 | 2016-01-02 08:03:08 +0000 | [diff] [blame] | 129 | return createRenderer<RenderIFrame>(*this, WTFMove(style)); |
ggaren | 31614e2 | 2006-10-13 20:22:08 +0000 | [diff] [blame] | 130 | } |
| 131 | |
darin@apple.com | 0ce67df | 2019-06-17 01:48:13 +0000 | [diff] [blame] | 132 | void HTMLIFrameElement::setReferrerPolicyForBindings(const AtomString& value) |
commit-queue@webkit.org | f59b72d | 2019-03-06 11:28:38 +0000 | [diff] [blame] | 133 | { |
| 134 | setAttributeWithoutSynchronization(referrerpolicyAttr, value); |
| 135 | } |
| 136 | |
| 137 | String HTMLIFrameElement::referrerPolicyForBindings() const |
| 138 | { |
commit-queue@webkit.org | 9e8f845 | 2019-07-17 09:03:37 +0000 | [diff] [blame] | 139 | return referrerPolicyToString(referrerPolicy()); |
commit-queue@webkit.org | f59b72d | 2019-03-06 11:28:38 +0000 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | ReferrerPolicy HTMLIFrameElement::referrerPolicy() const |
| 143 | { |
commit-queue@webkit.org | 87bc913 | 2020-09-12 08:35:27 +0000 | [diff] [blame] | 144 | if (m_lazyLoadFrameObserver) |
| 145 | return m_lazyLoadFrameObserver->referrerPolicy(); |
weinig@apple.com | 5216266 | 2020-08-31 18:16:31 +0000 | [diff] [blame] | 146 | if (document().settings().referrerPolicyAttributeEnabled()) |
darin@apple.com | 7c840b6 | 2021-05-28 01:26:23 +0000 | [diff] [blame] | 147 | return parseReferrerPolicy(attributeWithoutSynchronization(referrerpolicyAttr), ReferrerPolicySource::ReferrerPolicyAttribute).value_or(ReferrerPolicy::EmptyString); |
commit-queue@webkit.org | f59b72d | 2019-03-06 11:28:38 +0000 | [diff] [blame] | 148 | return ReferrerPolicy::EmptyString; |
| 149 | } |
| 150 | |
youenn@apple.com | 2b8b02f | 2019-05-22 17:38:42 +0000 | [diff] [blame] | 151 | const FeaturePolicy& HTMLIFrameElement::featurePolicy() const |
| 152 | { |
| 153 | if (!m_featurePolicy) |
commit-queue@webkit.org | 5f0dc04 | 2020-01-27 20:54:54 +0000 | [diff] [blame] | 154 | m_featurePolicy = FeaturePolicy::parse(document(), *this, attributeWithoutSynchronization(allowAttr)); |
youenn@apple.com | 2b8b02f | 2019-05-22 17:38:42 +0000 | [diff] [blame] | 155 | return *m_featurePolicy; |
| 156 | } |
| 157 | |
commit-queue@webkit.org | 87bc913 | 2020-09-12 08:35:27 +0000 | [diff] [blame] | 158 | const 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 | |
| 165 | void HTMLIFrameElement::setLoadingForBindings(const AtomString& value) |
| 166 | { |
| 167 | setAttributeWithoutSynchronization(loadingAttr, value); |
| 168 | } |
| 169 | |
commit-queue@webkit.org | b4b915a | 2020-12-01 17:14:28 +0000 | [diff] [blame] | 170 | static bool isFrameLazyLoadable(const Document& document, const URL& completeURL, const AtomString& loadingAttributeValue) |
commit-queue@webkit.org | 87bc913 | 2020-09-12 08:35:27 +0000 | [diff] [blame] | 171 | { |
| 172 | if (!completeURL.protocolIsInHTTPFamily()) |
| 173 | return false; |
| 174 | |
commit-queue@webkit.org | b4b915a | 2020-12-01 17:14:28 +0000 | [diff] [blame] | 175 | if (!document.frame() || !document.frame()->script().canExecuteScripts(NotAboutToExecuteScript)) |
| 176 | return false; |
| 177 | |
commit-queue@webkit.org | 87bc913 | 2020-09-12 08:35:27 +0000 | [diff] [blame] | 178 | return equalLettersIgnoringASCIICase(loadingAttributeValue, "lazy"); |
| 179 | } |
| 180 | |
| 181 | bool HTMLIFrameElement::shouldLoadFrameLazily() |
| 182 | { |
| 183 | if (!m_lazyLoadFrameObserver && document().settings().lazyIframeLoadingEnabled()) { |
| 184 | URL completeURL = document().completeURL(frameURL()); |
commit-queue@webkit.org | b4b915a | 2020-12-01 17:14:28 +0000 | [diff] [blame] | 185 | if (isFrameLazyLoadable(document(), completeURL, attributeWithoutSynchronization(HTMLNames::loadingAttr))) { |
commit-queue@webkit.org | 87bc913 | 2020-09-12 08:35:27 +0000 | [diff] [blame] | 186 | auto currentReferrerPolicy = referrerPolicy(); |
| 187 | lazyLoadFrameObserver().observe(completeURL.string(), currentReferrerPolicy); |
| 188 | return true; |
| 189 | } |
| 190 | } |
| 191 | return false; |
| 192 | } |
| 193 | |
| 194 | bool HTMLIFrameElement::isLazyLoadObserverActive() const |
| 195 | { |
| 196 | return !!m_lazyLoadFrameObserver; |
| 197 | } |
| 198 | |
| 199 | void HTMLIFrameElement::loadDeferredFrame() |
| 200 | { |
| 201 | AtomString currentURL = frameURL(); |
| 202 | setFrameURL(m_lazyLoadFrameObserver->frameURL()); |
| 203 | openURL(); |
| 204 | setFrameURL(currentURL); |
| 205 | m_lazyLoadFrameObserver = nullptr; |
| 206 | } |
| 207 | |
| 208 | LazyLoadFrameObserver& HTMLIFrameElement::lazyLoadFrameObserver() |
| 209 | { |
| 210 | if (!m_lazyLoadFrameObserver) |
| 211 | m_lazyLoadFrameObserver = makeUnique<LazyLoadFrameObserver>(*this); |
| 212 | return *m_lazyLoadFrameObserver; |
| 213 | } |
| 214 | |
eseidel | 409f430 | 2006-05-12 22:56:41 +0000 | [diff] [blame] | 215 | } |