Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / css / StyleSheetContents.cpp
blob4d9fd42bb41b046127ab9f192d282ac7c8c44ef8
1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include "config.h"
22 #include "core/css/StyleSheetContents.h"
24 #include "core/css/CSSStyleSheet.h"
25 #include "core/css/StylePropertySet.h"
26 #include "core/css/StyleRule.h"
27 #include "core/css/StyleRuleImport.h"
28 #include "core/css/StyleRuleNamespace.h"
29 #include "core/css/parser/CSSParser.h"
30 #include "core/dom/Document.h"
31 #include "core/dom/Node.h"
32 #include "core/dom/StyleEngine.h"
33 #include "core/fetch/CSSStyleSheetResource.h"
34 #include "core/frame/UseCounter.h"
35 #include "core/inspector/InspectorTraceEvents.h"
36 #include "platform/TraceEvent.h"
37 #include "platform/weborigin/SecurityOrigin.h"
38 #include "wtf/Deque.h"
40 namespace blink {
42 // Rough size estimate for the memory cache.
43 unsigned StyleSheetContents::estimatedSizeInBytes() const
45 // Note that this does not take into account size of the strings hanging from various objects.
46 // The assumption is that nearly all of of them are atomic and would exist anyway.
47 unsigned size = sizeof(*this);
49 // FIXME: This ignores the children of media rules.
50 // Most rules are StyleRules.
51 size += ruleCount() * StyleRule::averageSizeInBytes();
53 for (unsigned i = 0; i < m_importRules.size(); ++i) {
54 if (StyleSheetContents* sheet = m_importRules[i]->styleSheet())
55 size += sheet->estimatedSizeInBytes();
57 return size;
60 StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
61 : m_ownerRule(ownerRule)
62 , m_originalURL(originalURL)
63 , m_defaultNamespace(starAtom)
64 , m_hasSyntacticallyValidCSSHeader(true)
65 , m_didLoadErrorOccur(false)
66 , m_isMutable(false)
67 , m_isInMemoryCache(false)
68 , m_hasFontFaceRule(false)
69 , m_hasMediaQueries(false)
70 , m_hasSingleOwnerDocument(true)
71 , m_parserContext(context)
75 StyleSheetContents::StyleSheetContents(const StyleSheetContents& o)
76 : m_ownerRule(nullptr)
77 , m_originalURL(o.m_originalURL)
78 , m_importRules(o.m_importRules.size())
79 , m_namespaceRules(o.m_namespaceRules.size())
80 , m_childRules(o.m_childRules.size())
81 , m_namespaces(o.m_namespaces)
82 , m_defaultNamespace(o.m_defaultNamespace)
83 , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader)
84 , m_didLoadErrorOccur(false)
85 , m_isMutable(false)
86 , m_isInMemoryCache(false)
87 , m_hasFontFaceRule(o.m_hasFontFaceRule)
88 , m_hasMediaQueries(o.m_hasMediaQueries)
89 , m_hasSingleOwnerDocument(true)
90 , m_parserContext(o.m_parserContext)
92 ASSERT(o.isCacheable());
94 // FIXME: Copy import rules.
95 ASSERT(o.m_importRules.isEmpty());
97 for (unsigned i = 0; i < m_childRules.size(); ++i)
98 m_childRules[i] = o.m_childRules[i]->copy();
101 StyleSheetContents::~StyleSheetContents()
103 #if !ENABLE(OILPAN)
104 clearRules();
105 #endif
108 void StyleSheetContents::setHasSyntacticallyValidCSSHeader(bool isValidCss)
110 if (!isValidCss) {
111 if (Document* document = clientSingleOwnerDocument())
112 removeSheetFromCache(document);
114 m_hasSyntacticallyValidCSSHeader = isValidCss;
117 bool StyleSheetContents::isCacheable() const
119 // This would require dealing with multiple clients for load callbacks.
120 if (!loadCompleted())
121 return false;
122 // FIXME: StyleSheets with media queries can't be cached because their RuleSet
123 // is processed differently based off the media queries, which might resolve
124 // differently depending on the context of the parent CSSStyleSheet (e.g.
125 // if they are in differently sized iframes). Once RuleSets are media query
126 // agnostic, we can restore sharing of StyleSheetContents with medea queries.
127 if (m_hasMediaQueries)
128 return false;
129 // FIXME: Support copying import rules.
130 if (!m_importRules.isEmpty())
131 return false;
132 // FIXME: Support cached stylesheets in import rules.
133 if (m_ownerRule)
134 return false;
135 if (m_didLoadErrorOccur)
136 return false;
137 // It is not the original sheet anymore.
138 if (m_isMutable)
139 return false;
140 // If the header is valid we are not going to need to check the SecurityOrigin.
141 // FIXME: Valid mime type avoids the check too.
142 if (!m_hasSyntacticallyValidCSSHeader)
143 return false;
144 return true;
147 void StyleSheetContents::parserAppendRule(PassRefPtrWillBeRawPtr<StyleRuleBase> rule)
149 if (rule->isImportRule()) {
150 // Parser enforces that @import rules come before anything else
151 ASSERT(m_childRules.isEmpty());
152 StyleRuleImport* importRule = toStyleRuleImport(rule.get());
153 if (importRule->mediaQueries())
154 setHasMediaQueries();
155 m_importRules.append(importRule);
156 m_importRules.last()->setParentStyleSheet(this);
157 m_importRules.last()->requestStyleSheet();
158 return;
161 if (rule->isNamespaceRule()) {
162 // Parser enforces that @namespace rules come before all rules other than
163 // import/charset rules
164 ASSERT(m_childRules.isEmpty());
165 StyleRuleNamespace& namespaceRule = toStyleRuleNamespace(*rule);
166 parserAddNamespace(namespaceRule.prefix(), namespaceRule.uri());
167 m_namespaceRules.append(&namespaceRule);
168 return;
171 if (rule->isMediaRule())
172 setHasMediaQueries();
174 m_childRules.append(rule);
177 void StyleSheetContents::setHasMediaQueries()
179 m_hasMediaQueries = true;
180 if (parentStyleSheet())
181 parentStyleSheet()->setHasMediaQueries();
184 StyleRuleBase* StyleSheetContents::ruleAt(unsigned index) const
186 ASSERT_WITH_SECURITY_IMPLICATION(index < ruleCount());
188 if (index < m_importRules.size())
189 return m_importRules[index].get();
191 index -= m_importRules.size();
193 if (index < m_namespaceRules.size())
194 return m_namespaceRules[index].get();
196 index -= m_namespaceRules.size();
198 return m_childRules[index].get();
201 unsigned StyleSheetContents::ruleCount() const
203 return m_importRules.size() + m_namespaceRules.size() + m_childRules.size();
206 void StyleSheetContents::clearRules()
208 for (unsigned i = 0; i < m_importRules.size(); ++i) {
209 ASSERT(m_importRules.at(i)->parentStyleSheet() == this);
210 m_importRules[i]->clearParentStyleSheet();
212 m_importRules.clear();
213 m_namespaceRules.clear();
214 m_childRules.clear();
217 bool StyleSheetContents::wrapperInsertRule(PassRefPtrWillBeRawPtr<StyleRuleBase> rule, unsigned index)
219 ASSERT(m_isMutable);
220 ASSERT_WITH_SECURITY_IMPLICATION(index <= ruleCount());
222 if (index < m_importRules.size() || (index == m_importRules.size() && rule->isImportRule())) {
223 // Inserting non-import rule before @import is not allowed.
224 if (!rule->isImportRule())
225 return false;
227 StyleRuleImport* importRule = toStyleRuleImport(rule.get());
228 if (importRule->mediaQueries())
229 setHasMediaQueries();
231 m_importRules.insert(index, importRule);
232 m_importRules[index]->setParentStyleSheet(this);
233 m_importRules[index]->requestStyleSheet();
234 // FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded.
235 return true;
237 // Inserting @import rule after a non-import rule is not allowed.
238 if (rule->isImportRule())
239 return false;
241 if (rule->isMediaRule())
242 setHasMediaQueries();
244 index -= m_importRules.size();
246 if (index < m_namespaceRules.size() || (index == m_namespaceRules.size() && rule->isNamespaceRule())) {
247 // Inserting non-namespace rules other than import rule before @namespace is not allowed.
248 if (!rule->isNamespaceRule())
249 return false;
250 // Inserting @namespace rule when rules other than import/namespace/charset are present is not allowed.
251 if (!m_childRules.isEmpty())
252 return false;
254 StyleRuleNamespace* namespaceRule = toStyleRuleNamespace(rule.get());
255 m_namespaceRules.insert(index, namespaceRule);
256 // For now to be compatible with IE and Firefox if namespace rule with same prefix is added
257 // irrespective of adding the rule at any index, last added rule's value is considered.
258 // TODO (ramya.v@samsung.com): As per spec last valid rule should be considered,
259 // which means if namespace rule is added in the middle of existing namespace rules,
260 // rule which comes later in rule list with same prefix needs to be considered.
261 parserAddNamespace(namespaceRule->prefix(), namespaceRule->uri());
262 return true;
265 if (rule->isNamespaceRule())
266 return false;
268 index -= m_namespaceRules.size();
270 if (rule->isFontFaceRule())
271 setHasFontFaceRule(true);
272 m_childRules.insert(index, rule);
273 return true;
276 bool StyleSheetContents::wrapperDeleteRule(unsigned index)
278 ASSERT(m_isMutable);
279 ASSERT_WITH_SECURITY_IMPLICATION(index < ruleCount());
281 if (index < m_importRules.size()) {
282 m_importRules[index]->clearParentStyleSheet();
283 if (m_importRules[index]->isFontFaceRule())
284 notifyRemoveFontFaceRule(toStyleRuleFontFace(m_importRules[index].get()));
285 m_importRules.remove(index);
286 return true;
288 index -= m_importRules.size();
290 if (index < m_namespaceRules.size()) {
291 if (!m_childRules.isEmpty())
292 return false;
293 m_namespaceRules.remove(index);
294 return true;
296 index -= m_namespaceRules.size();
298 if (m_childRules[index]->isFontFaceRule())
299 notifyRemoveFontFaceRule(toStyleRuleFontFace(m_childRules[index].get()));
300 m_childRules.remove(index);
301 return true;
304 void StyleSheetContents::parserAddNamespace(const AtomicString& prefix, const AtomicString& uri)
306 ASSERT(!uri.isNull());
307 if (prefix.isNull()) {
308 m_defaultNamespace = uri;
309 return;
311 PrefixNamespaceURIMap::AddResult result = m_namespaces.add(prefix, uri);
312 if (result.isNewEntry)
313 return;
314 result.storedValue->value = uri;
317 const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& prefix)
319 if (prefix.isNull())
320 return defaultNamespace();
321 if (prefix.isEmpty())
322 return emptyAtom; // No namespace. If an element/attribute has a namespace, we won't match it.
323 if (prefix == starAtom)
324 return starAtom; // We'll match any namespace.
325 return m_namespaces.get(prefix);
328 void StyleSheetContents::parseAuthorStyleSheet(const CSSStyleSheetResource* cachedStyleSheet, const SecurityOrigin* securityOrigin)
330 TRACE_EVENT1("blink,devtools.timeline", "ParseAuthorStyleSheet", "data", InspectorParseAuthorStyleSheetEvent::data(cachedStyleSheet));
332 bool isSameOriginRequest = securityOrigin && securityOrigin->canRequest(baseURL());
333 CSSStyleSheetResource::MIMETypeCheck mimeTypeCheck = isQuirksModeBehavior(m_parserContext.mode()) && isSameOriginRequest ? CSSStyleSheetResource::MIMETypeCheck::Lax : CSSStyleSheetResource::MIMETypeCheck::Strict;
334 String sheetText = cachedStyleSheet->sheetText(mimeTypeCheck);
336 const ResourceResponse& response = cachedStyleSheet->response();
337 m_sourceMapURL = response.httpHeaderField("SourceMap");
338 if (m_sourceMapURL.isEmpty()) {
339 // Try to get deprecated header.
340 m_sourceMapURL = response.httpHeaderField("X-SourceMap");
343 CSSParserContext context(parserContext(), UseCounter::getFrom(this));
344 CSSParser::parseSheet(context, this, sheetText);
347 void StyleSheetContents::parseString(const String& sheetText)
349 parseStringAtPosition(sheetText, TextPosition::minimumPosition());
352 void StyleSheetContents::parseStringAtPosition(const String& sheetText, const TextPosition& startPosition)
354 CSSParserContext context(parserContext(), UseCounter::getFrom(this));
355 CSSParser::parseSheet(context, this, sheetText);
358 bool StyleSheetContents::isLoading() const
360 for (unsigned i = 0; i < m_importRules.size(); ++i) {
361 if (m_importRules[i]->isLoading())
362 return true;
364 return false;
367 bool StyleSheetContents::loadCompleted() const
369 StyleSheetContents* parentSheet = parentStyleSheet();
370 if (parentSheet)
371 return parentSheet->loadCompleted();
373 StyleSheetContents* root = rootStyleSheet();
374 return root->m_loadingClients.isEmpty();
377 void StyleSheetContents::checkLoaded()
379 if (isLoading())
380 return;
382 // Avoid |this| being deleted by scripts that run via
383 // ScriptableDocumentParser::executeScriptsWaitingForResources().
384 // See https://bugs.webkit.org/show_bug.cgi?id=95106
385 RefPtrWillBeRawPtr<StyleSheetContents> protect(this);
387 StyleSheetContents* parentSheet = parentStyleSheet();
388 if (parentSheet) {
389 parentSheet->checkLoaded();
390 return;
393 ASSERT(this == rootStyleSheet());
394 if (m_loadingClients.isEmpty())
395 return;
397 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via
398 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also protect
399 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoaded|
400 // method.
402 // When a sheet is loaded it is moved from the set of loading clients
403 // to the set of completed clients. We therefore need the copy in order to
404 // not modify the set while iterating it.
405 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>> loadingClients;
406 copyToVector(m_loadingClients, loadingClients);
408 for (unsigned i = 0; i < loadingClients.size(); ++i) {
409 if (loadingClients[i]->loadCompleted())
410 continue;
412 // sheetLoaded might be invoked after its owner node is removed from document.
413 if (RefPtrWillBeRawPtr<Node> ownerNode = loadingClients[i]->ownerNode()) {
414 if (loadingClients[i]->sheetLoaded())
415 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur ? Node::ErrorOccurredLoadingSubresource : Node::NoErrorLoadingSubresource);
420 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet)
422 ASSERT(sheet);
423 m_didLoadErrorOccur |= sheet->errorOccurred();
424 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet on this
425 // sheet before its imports have loaded. So clear the RuleSet when the imports
426 // load since the import's subrules are flattened into its parent sheet's RuleSet.
427 clearRuleSet();
430 void StyleSheetContents::startLoadingDynamicSheet()
432 StyleSheetContents* root = rootStyleSheet();
433 for (const auto& client : root->m_loadingClients)
434 client->startLoadingDynamicSheet();
435 // Copy the completed clients to a vector for iteration.
436 // startLoadingDynamicSheet will move the style sheet from the
437 // completed state to the loading state which modifies the set of
438 // completed clients. We therefore need the copy in order to not
439 // modify the set of completed clients while iterating it.
440 WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet>> completedClients;
441 copyToVector(root->m_completedClients, completedClients);
442 for (unsigned i = 0; i < completedClients.size(); ++i)
443 completedClients[i]->startLoadingDynamicSheet();
446 StyleSheetContents* StyleSheetContents::rootStyleSheet() const
448 const StyleSheetContents* root = this;
449 while (root->parentStyleSheet())
450 root = root->parentStyleSheet();
451 return const_cast<StyleSheetContents*>(root);
454 bool StyleSheetContents::hasSingleOwnerNode() const
456 return rootStyleSheet()->hasOneClient();
459 Node* StyleSheetContents::singleOwnerNode() const
461 StyleSheetContents* root = rootStyleSheet();
462 if (!root->hasOneClient())
463 return nullptr;
464 if (root->m_loadingClients.size())
465 return (*root->m_loadingClients.begin())->ownerNode();
466 return (*root->m_completedClients.begin())->ownerNode();
469 Document* StyleSheetContents::singleOwnerDocument() const
471 StyleSheetContents* root = rootStyleSheet();
472 return root->clientSingleOwnerDocument();
475 static bool childRulesHaveFailedOrCanceledSubresources(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase>>& rules)
477 for (unsigned i = 0; i < rules.size(); ++i) {
478 const StyleRuleBase* rule = rules[i].get();
479 switch (rule->type()) {
480 case StyleRuleBase::Style:
481 if (toStyleRule(rule)->properties().hasFailedOrCanceledSubresources())
482 return true;
483 break;
484 case StyleRuleBase::FontFace:
485 if (toStyleRuleFontFace(rule)->properties().hasFailedOrCanceledSubresources())
486 return true;
487 break;
488 case StyleRuleBase::Media:
489 if (childRulesHaveFailedOrCanceledSubresources(toStyleRuleMedia(rule)->childRules()))
490 return true;
491 break;
492 case StyleRuleBase::Charset:
493 case StyleRuleBase::Import:
494 case StyleRuleBase::Namespace:
495 ASSERT_NOT_REACHED();
496 case StyleRuleBase::Page:
497 case StyleRuleBase::Keyframes:
498 case StyleRuleBase::Keyframe:
499 case StyleRuleBase::Supports:
500 case StyleRuleBase::Viewport:
501 break;
504 return false;
507 bool StyleSheetContents::hasFailedOrCanceledSubresources() const
509 ASSERT(isCacheable());
510 return childRulesHaveFailedOrCanceledSubresources(m_childRules);
513 Document* StyleSheetContents::clientSingleOwnerDocument() const
515 if (!m_hasSingleOwnerDocument || clientSize() <= 0)
516 return nullptr;
518 if (m_loadingClients.size())
519 return (*m_loadingClients.begin())->ownerDocument();
520 return (*m_completedClients.begin())->ownerDocument();
523 StyleSheetContents* StyleSheetContents::parentStyleSheet() const
525 return m_ownerRule ? m_ownerRule->parentStyleSheet() : nullptr;
528 void StyleSheetContents::registerClient(CSSStyleSheet* sheet)
530 ASSERT(!m_loadingClients.contains(sheet) && !m_completedClients.contains(sheet));
532 // InspectorCSSAgent::buildObjectForRule creates CSSStyleSheet without any owner node.
533 if (!sheet->ownerDocument())
534 return;
536 if (Document* document = clientSingleOwnerDocument()) {
537 if (sheet->ownerDocument() != document)
538 m_hasSingleOwnerDocument = false;
540 m_loadingClients.add(sheet);
543 void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet)
545 m_loadingClients.remove(sheet);
546 m_completedClients.remove(sheet);
548 if (!sheet->ownerDocument() || !m_loadingClients.isEmpty() || !m_completedClients.isEmpty())
549 return;
551 if (m_hasSingleOwnerDocument)
552 removeSheetFromCache(sheet->ownerDocument());
553 m_hasSingleOwnerDocument = true;
556 void StyleSheetContents::clientLoadCompleted(CSSStyleSheet* sheet)
558 ASSERT(m_loadingClients.contains(sheet) || !sheet->ownerDocument());
559 m_loadingClients.remove(sheet);
560 // In m_ownerNode->sheetLoaded, the CSSStyleSheet might be detached.
561 // (i.e. clearOwnerNode was invoked.)
562 // In this case, we don't need to add the stylesheet to completed clients.
563 if (!sheet->ownerDocument())
564 return;
565 m_completedClients.add(sheet);
568 void StyleSheetContents::clientLoadStarted(CSSStyleSheet* sheet)
570 ASSERT(m_completedClients.contains(sheet));
571 m_completedClients.remove(sheet);
572 m_loadingClients.add(sheet);
575 void StyleSheetContents::removeSheetFromCache(Document* document)
577 ASSERT(document);
578 document->styleEngine().removeSheet(this);
581 void StyleSheetContents::addedToMemoryCache()
583 ASSERT(!m_isInMemoryCache);
584 ASSERT(isCacheable());
585 m_isInMemoryCache = true;
588 void StyleSheetContents::removedFromMemoryCache()
590 ASSERT(m_isInMemoryCache);
591 ASSERT(isCacheable());
592 m_isInMemoryCache = false;
595 RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, AddRuleFlags addRuleFlags)
597 if (!m_ruleSet) {
598 m_ruleSet = RuleSet::create();
599 m_ruleSet->addRulesFromSheet(this, medium, addRuleFlags);
601 return *m_ruleSet.get();
604 static void clearResolvers(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet>>& clients)
606 for (const auto& sheet : clients) {
607 if (Document* document = sheet->ownerDocument())
608 document->styleEngine().clearResolver();
612 void StyleSheetContents::clearRuleSet()
614 if (StyleSheetContents* parentSheet = parentStyleSheet())
615 parentSheet->clearRuleSet();
617 // Don't want to clear the StyleResolver if the RuleSet hasn't been created
618 // since we only clear the StyleResolver so that it's members are properly
619 // updated in ScopedStyleResolver::addRulesFromSheet.
620 if (!m_ruleSet)
621 return;
623 // Clearing the ruleSet means we need to recreate the styleResolver data structures.
624 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet.
625 clearResolvers(m_loadingClients);
626 clearResolvers(m_completedClients);
627 m_ruleSet.clear();
630 static void removeFontFaceRules(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet>>& clients, const StyleRuleFontFace* fontFaceRule)
632 for (const auto& sheet : clients) {
633 if (Node* ownerNode = sheet->ownerNode())
634 ownerNode->document().styleEngine().removeFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace>>(1, fontFaceRule));
638 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontFaceRule)
640 StyleSheetContents* root = rootStyleSheet();
641 removeFontFaceRules(root->m_loadingClients, fontFaceRule);
642 removeFontFaceRules(root->m_completedClients, fontFaceRule);
645 static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase>>& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace>>& fontFaceRules)
647 for (unsigned i = 0; i < rules.size(); ++i) {
648 StyleRuleBase* rule = rules[i].get();
650 if (rule->isFontFaceRule()) {
651 fontFaceRules.append(toStyleRuleFontFace(rule));
652 } else if (rule->isMediaRule()) {
653 StyleRuleMedia* mediaRule = toStyleRuleMedia(rule);
654 // We cannot know whether the media rule matches or not, but
655 // for safety, remove @font-face in the media rule (if exists).
656 findFontFaceRulesFromRules(mediaRule->childRules(), fontFaceRules);
661 void StyleSheetContents::findFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace>>& fontFaceRules)
663 for (unsigned i = 0; i < m_importRules.size(); ++i) {
664 if (!m_importRules[i]->styleSheet())
665 continue;
666 m_importRules[i]->styleSheet()->findFontFaceRules(fontFaceRules);
669 findFontFaceRulesFromRules(childRules(), fontFaceRules);
672 DEFINE_TRACE(StyleSheetContents)
674 #if ENABLE(OILPAN)
675 visitor->trace(m_ownerRule);
676 visitor->trace(m_importRules);
677 visitor->trace(m_namespaceRules);
678 visitor->trace(m_childRules);
679 visitor->trace(m_loadingClients);
680 visitor->trace(m_completedClients);
681 visitor->trace(m_ruleSet);
682 #endif