source: webkit/trunk/Source/WebCore/css/StyleRuleImport.cpp

Last change on this file was 288879, checked in by Oriol Brufau, 3 years ago

[css-cascade] Fix removal of not yet loaded CSS @import
https://bugs.webkit.org/show_bug.cgi?id=235930

Reviewed by Antti Koivisto.

LayoutTests/imported/w3c:

Add new test.

  • web-platform-tests/css/css-cascade/import-removal-expected.html: Added.
  • web-platform-tests/css/css-cascade/import-removal.html: Added.

Source/WebCore:

When removing a not yet loaded CSS @import, the hasPendingSheet() flag
was not cleared. This resulted in a completely blank page.
This patch makes sure to cancel the load before deleting the rule.

Test: imported/w3c/web-platform-tests/css/css-cascade/import-removal.html

  • css/StyleRuleImport.cpp:

(WebCore::StyleRuleImport::cancelLoad):

  • css/StyleRuleImport.h:
  • css/StyleSheetContents.cpp:

(WebCore::StyleSheetContents::wrapperDeleteRule):

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1/*
2 * (C) 1999-2003 Lars Knoll ([email protected])
3 * (C) 2002-2003 Dirk Mueller ([email protected])
4 * Copyright (C) 2002-2017 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#include "config.h"
23#include "StyleRuleImport.h"
24
25#include "CSSStyleSheet.h"
26#include "CachedCSSStyleSheet.h"
27#include "CachedResourceLoader.h"
28#include "CachedResourceRequest.h"
29#include "CachedResourceRequestInitiators.h"
30#include "Document.h"
31#include "MediaList.h"
32#include "MediaQueryParser.h"
33#include "SecurityOrigin.h"
34#include "StyleSheetContents.h"
35#include <wtf/StdLibExtras.h>
36
37namespace WebCore {
38
39Ref<StyleRuleImport> StyleRuleImport::create(const String& href, Ref<MediaQuerySet>&& media, std::optional<CascadeLayerName>&& cascadeLayerName)
40{
41 return adoptRef(*new StyleRuleImport(href, WTFMove(media), WTFMove(cascadeLayerName)));
42}
43
44StyleRuleImport::StyleRuleImport(const String& href, Ref<MediaQuerySet>&& media, std::optional<CascadeLayerName>&& cascadeLayerName)
45 : StyleRuleBase(StyleRuleType::Import)
46 , m_styleSheetClient(this)
47 , m_strHref(href)
48 , m_mediaQueries(WTFMove(media))
49 , m_cascadeLayerName(WTFMove(cascadeLayerName))
50{
51 if (!m_mediaQueries)
52 m_mediaQueries = MediaQuerySet::create(String(), MediaQueryParserContext());
53}
54
55void StyleRuleImport::cancelLoad()
56{
57 if (!isLoading())
58 return;
59
60 m_loading = false;
61 if (m_parentStyleSheet)
62 m_parentStyleSheet->checkLoaded();
63}
64
65StyleRuleImport::~StyleRuleImport()
66{
67 if (m_styleSheet)
68 m_styleSheet->clearOwnerRule();
69 if (m_cachedSheet)
70 m_cachedSheet->removeClient(m_styleSheetClient);
71}
72
73void StyleRuleImport::setCSSStyleSheet(const String& href, const URL& baseURL, const String& charset, const CachedCSSStyleSheet* cachedStyleSheet)
74{
75 if (m_styleSheet)
76 m_styleSheet->clearOwnerRule();
77
78 CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : HTMLStandardMode;
79 context.charset = charset;
80 if (!baseURL.isNull())
81 context.baseURL = baseURL;
82
83 Document* document = m_parentStyleSheet ? m_parentStyleSheet->singleOwnerDocument() : nullptr;
84 m_styleSheet = StyleSheetContents::create(this, href, context);
85 if ((m_parentStyleSheet && m_parentStyleSheet->isContentOpaque()) || !cachedStyleSheet->isCORSSameOrigin())
86 m_styleSheet->setAsOpaque();
87
88 bool parseSucceeded = m_styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document ? &document->securityOrigin() : nullptr);
89
90 m_loading = false;
91
92 if (m_parentStyleSheet) {
93 if (parseSucceeded)
94 m_parentStyleSheet->notifyLoadedSheet(cachedStyleSheet);
95 else
96 m_parentStyleSheet->setLoadErrorOccured();
97 m_parentStyleSheet->checkLoaded();
98 }
99}
100
101bool StyleRuleImport::isLoading() const
102{
103 return m_loading || (m_styleSheet && m_styleSheet->isLoading());
104}
105
106void StyleRuleImport::requestStyleSheet()
107{
108 if (!m_parentStyleSheet)
109 return;
110 auto* document = m_parentStyleSheet->singleOwnerDocument();
111 if (!document)
112 return;
113 auto* page = document->page();
114 if (!page)
115 return;
116
117 URL absURL;
118 if (!m_parentStyleSheet->baseURL().isNull())
119 // use parent styleheet's URL as the base URL
120 absURL = URL(m_parentStyleSheet->baseURL(), m_strHref);
121 else
122 absURL = document->completeURL(m_strHref);
123
124 // Check for a cycle in our import chain. If we encounter a stylesheet
125 // in our parent chain with the same URL, then just bail.
126 StyleSheetContents* rootSheet = m_parentStyleSheet;
127 for (StyleSheetContents* sheet = m_parentStyleSheet; sheet; sheet = sheet->parentStyleSheet()) {
128 if (equalIgnoringFragmentIdentifier(absURL, sheet->baseURL())
129 || equalIgnoringFragmentIdentifier(absURL, document->completeURL(sheet->originalURL())))
130 return;
131 rootSheet = sheet;
132 }
133
134 // FIXME: Skip Content Security Policy check when stylesheet is in a user agent shadow tree.
135 // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
136 CachedResourceRequest request(absURL, CachedResourceLoader::defaultCachedResourceOptions(), std::nullopt, String(m_parentStyleSheet->charset()));
137 request.setInitiator(cachedResourceRequestInitiators().css);
138 if (m_cachedSheet)
139 m_cachedSheet->removeClient(m_styleSheetClient);
140 if (m_parentStyleSheet->isUserStyleSheet()) {
141 ResourceLoaderOptions options {
142 SendCallbackPolicy::DoNotSendCallbacks,
143 ContentSniffingPolicy::SniffContent,
144 DataBufferingPolicy::BufferData,
145 StoredCredentialsPolicy::Use,
146 ClientCredentialPolicy::MayAskClientForCredentials,
147 FetchOptions::Credentials::Include,
148 SecurityCheckPolicy::SkipSecurityCheck,
149 FetchOptions::Mode::NoCors,
150 CertificateInfoPolicy::DoNotIncludeCertificateInfo,
151 ContentSecurityPolicyImposition::SkipPolicyCheck,
152 DefersLoadingPolicy::AllowDefersLoading,
153 CachingPolicy::AllowCaching
154 };
155 options.loadedFromOpaqueSource = m_parentStyleSheet->isContentOpaque() ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No;
156
157 request.setOptions(WTFMove(options));
158
159 m_cachedSheet = document->cachedResourceLoader().requestUserCSSStyleSheet(*page, WTFMove(request));
160 } else {
161 auto options = request.options();
162 options.loadedFromOpaqueSource = m_parentStyleSheet->isContentOpaque() ? LoadedFromOpaqueSource::Yes : LoadedFromOpaqueSource::No;
163 request.setOptions(WTFMove(options));
164 m_cachedSheet = document->cachedResourceLoader().requestCSSStyleSheet(WTFMove(request)).value_or(nullptr);
165 }
166 if (m_cachedSheet) {
167 // if the import rule is issued dynamically, the sheet may be
168 // removed from the pending sheet count, so let the doc know
169 // the sheet being imported is pending.
170 if (m_parentStyleSheet && m_parentStyleSheet->loadCompleted() && rootSheet == m_parentStyleSheet)
171 m_parentStyleSheet->startLoadingDynamicSheet();
172 m_loading = true;
173 m_cachedSheet->addClient(m_styleSheetClient);
174 } else if (m_parentStyleSheet) {
175 m_parentStyleSheet->setLoadErrorOccured();
176 m_parentStyleSheet->checkLoaded();
177 }
178}
179
180} // namespace WebCore
Note: See TracBrowser for help on using the repository browser.