TEST_F(StyleEngineTest, AnalyzedInject) { document().body()->setInnerHTML( "<style>div { color: red }</style><div id='t1'>Green</div><div></div>"); document().view()->updateAllLifecyclePhases(); Element* t1 = document().getElementById("t1"); ASSERT_TRUE(t1); ASSERT_TRUE(t1->computedStyle()); EXPECT_EQ(makeRGB(255, 0, 0), t1->computedStyle()->visitedDependentColor(CSSPropertyColor)); unsigned beforeCount = styleEngine().styleForElementCount(); StyleSheetContents* parsedSheet = StyleSheetContents::create(CSSParserContext(document(), nullptr)); parsedSheet->parseString("#t1 { color: green }"); styleEngine().injectAuthorSheet(parsedSheet); document().view()->updateAllLifecyclePhases(); unsigned afterCount = styleEngine().styleForElementCount(); EXPECT_EQ(1u, afterCount - beforeCount); ASSERT_TRUE(t1->computedStyle()); EXPECT_EQ(makeRGB(0, 128, 0), t1->computedStyle()->visitedDependentColor(CSSPropertyColor)); }
PassRefPtrWillBeRawPtr<CSSStyleSheet> StyleEngine::createSheet(Element* e, const String& text, TextPosition startPosition, bool createdByParser) { RefPtrWillBeRawPtr<CSSStyleSheet> styleSheet = nullptr; e->document().styleEngine()->addPendingSheet(); if (!e->document().inQuirksMode()) { AtomicString textContent(text); WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<StyleSheetContents> >::AddResult result = m_textToSheetCache.add(textContent, nullptr); if (result.isNewEntry || !result.storedValue->value) { styleSheet = StyleEngine::parseSheet(e, text, startPosition, createdByParser); if (result.isNewEntry && isCacheableForStyleElement(*styleSheet->contents())) { result.storedValue->value = styleSheet->contents(); m_sheetToTextCache.add(styleSheet->contents(), textContent); } } else { StyleSheetContents* contents = result.storedValue->value; ASSERT(contents); ASSERT(isCacheableForStyleElement(*contents)); ASSERT(contents->singleOwnerDocument() == e->document()); styleSheet = CSSStyleSheet::createInline(contents, e, startPosition); } } else { // FIXME: currently we don't cache StyleSheetContents inQuirksMode. styleSheet = StyleEngine::parseSheet(e, text, startPosition, createdByParser); } ASSERT(styleSheet); styleSheet->setTitle(e->title()); return styleSheet; }
void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents) { for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) { StyleSheetContents* contents = m_authorStyleSheets[i]->contents(); if (contents->hasOneClient() || visitedSharedStyleSheetContents.add(contents).isNewEntry) features.add(contents->ruleSet().features()); } }
static CSSStyleSheet* createSheet(const String& cssText = String()) { StyleSheetContents* contents = StyleSheetContents::create(CSSParserContext(HTMLStandardMode, nullptr)); contents->parseString(cssText); contents->ensureRuleSet(MediaQueryEvaluator(), RuleHasDocumentSecurityOrigin); return CSSStyleSheet::create(contents); }
void WebDocument::insertStyleSheet(const WebString& sourceCode) { Document* document = unwrap<Document>(); DCHECK(document); StyleSheetContents* parsedSheet = StyleSheetContents::create(CSSParserContext(*document, nullptr)); parsedSheet->parseString(sourceCode); document->styleEngine().injectAuthorSheet(parsedSheet); }
bool StyleSheetContents::loadCompleted() const { StyleSheetContents* parentSheet = parentStyleSheet(); if (parentSheet) return parentSheet->loadCompleted(); StyleSheetContents* root = rootStyleSheet(); return root->m_loadingClients.isEmpty(); }
Node* StyleSheetContents::singleOwnerNode() const { StyleSheetContents* root = rootStyleSheet(); if (!root->hasOneClient()) return nullptr; if (root->m_loadingClients.size()) return (*root->m_loadingClients.begin())->ownerNode(); return (*root->m_completedClients.begin())->ownerNode(); }
void TreeScopeStyleSheetCollection::clearMediaQueryRuleSetStyleSheets() { for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) { StyleSheetContents* contents = m_activeAuthorStyleSheets[i]->contents(); if (contents->hasMediaQueries()) contents->clearRuleSet(); } }
static StyleSheetContents* parseUASheet(const String& str) { StyleSheetContents* sheet = StyleSheetContents::create(CSSParserContext(UASheetMode, nullptr)); sheet->parseString(str); // User Agent stylesheets are parsed once for the lifetime of the renderer // process and are intentionally leaked. LEAK_SANITIZER_IGNORE_OBJECT(sheet); return sheet; }
TEST_F(StyleEngineTest, DocumentDirtyAfterInject) { StyleSheetContents* parsedSheet = StyleSheetContents::create(CSSParserContext(document(), nullptr)); parsedSheet->parseString("div {}"); styleEngine().injectAuthorSheet(parsedSheet); document().view()->updateAllLifecyclePhases(); EXPECT_TRUE(isDocumentStyleSheetCollectionClean()); }
void ScopedStyleResolver::addRulesFromSheet(CSSStyleSheet* cssSheet, const MediaQueryEvaluator& medium, StyleResolver* resolver) { m_authorStyleSheets.append(cssSheet); StyleSheetContents* sheet = cssSheet->contents(); AddRuleFlags addRuleFlags = resolver->document().securityOrigin()->canRequest(sheet->baseURL()) ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState; const RuleSet& ruleSet = sheet->ensureRuleSet(medium, addRuleFlags); resolver->addMediaQueryResults(ruleSet.viewportDependentMediaQueryResults()); resolver->processScopedRules(ruleSet, sheet->baseURL(), &m_scopingNode); }
static bool isCacheableForStyleElement(const StyleSheetContents& contents) { // Until import rules are supported in cached sheets it's not possible for loading to fail. ASSERT(!contents.didLoadErrorOccur()); // It is not the original sheet anymore. if (contents.isMutable()) return false; if (!contents.hasSyntacticallyValidCSSHeader()) return false; return true; }
void ScopedStyleResolver::appendCSSStyleSheet(CSSStyleSheet& cssSheet, const MediaQueryEvaluator& medium) { unsigned index = m_authorStyleSheets.size(); m_authorStyleSheets.append(&cssSheet); StyleSheetContents* sheet = cssSheet.contents(); AddRuleFlags addRuleFlags = treeScope().document().securityOrigin()->canRequest(sheet->baseURL()) ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState; const RuleSet& ruleSet = sheet->ensureRuleSet(medium, addRuleFlags); addKeyframeRules(ruleSet); addFontFaceRules(ruleSet); addTreeBoundaryCrossingRules(ruleSet, &cssSheet, index); treeScope().document().styleResolver()->addMediaQueryResults(ruleSet.viewportDependentMediaQueryResults()); }
void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features, WillBeHeapHashSet<RawPtrWillBeMember<const StyleSheetContents>>& visitedSharedStyleSheetContents) const { for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) { ASSERT(m_authorStyleSheets[i]->ownerNode()); StyleSheetContents* contents = m_authorStyleSheets[i]->contents(); if (contents->hasOneClient() || visitedSharedStyleSheetContents.add(contents).isNewEntry) features.add(contents->ruleSet().features()); } if (!m_treeBoundaryCrossingRuleSet) return; for (const auto& rules : *m_treeBoundaryCrossingRuleSet) features.add(rules->m_ruleSet->features()); }
StyleSheetContents::StyleSheetContents(const StyleSheetContents& o) : RefCounted<StyleSheetContents>() , m_ownerRule(0) , m_originalURL(o.m_originalURL) , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule) , m_importRules(o.m_importRules.size()) , m_childRules(o.m_childRules.size()) , m_namespaces(o.m_namespaces) , m_loadCompleted(true) , m_isUserStyleSheet(o.m_isUserStyleSheet) , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader) , m_didLoadErrorOccur(false) , m_usesRemUnits(o.m_usesRemUnits) , m_isMutable(false) , m_isInMemoryCache(false) , m_parserContext(o.m_parserContext) { ASSERT(o.isCacheable()); // FIXME: Copy import rules. ASSERT(o.m_importRules.isEmpty()); for (unsigned i = 0; i < m_childRules.size(); ++i) m_childRules[i] = o.m_childRules[i]->copy(); }
StyleSheetContents::StyleSheetContents(const StyleSheetContents& o) : m_ownerRule(nullptr) , m_originalURL(o.m_originalURL) , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule) , m_importRules(o.m_importRules.size()) , m_childRules(o.m_childRules.size()) , m_namespaces(o.m_namespaces) , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader) , m_didLoadErrorOccur(false) , m_usesRemUnits(o.m_usesRemUnits) , m_isMutable(false) , m_isInMemoryCache(false) , m_hasFontFaceRule(o.m_hasFontFaceRule) , m_hasMediaQueries(o.m_hasMediaQueries) , m_hasSingleOwnerDocument(true) , m_parserContext(o.m_parserContext) { ASSERT(o.isCacheable()); // FIXME: Copy import rules. ASSERT(o.m_importRules.isEmpty()); for (unsigned i = 0; i < m_childRules.size(); ++i) m_childRules[i] = o.m_childRules[i]->copy(); }
StyleEngineTest::RuleSetInvalidation StyleEngineTest::scheduleInvalidationsForRules(TreeScope& treeScope, const String& cssText) { StyleSheetContents* sheet = StyleSheetContents::create(CSSParserContext(HTMLStandardMode, nullptr)); sheet->parseString(cssText); HeapVector<Member<RuleSet>> ruleSets; RuleSet& ruleSet = sheet->ensureRuleSet(MediaQueryEvaluator(), RuleHasDocumentSecurityOrigin); ruleSet.compactRulesIfNeeded(); if (ruleSet.needsFullRecalcForRuleSetInvalidation()) return RuleSetInvalidationFullRecalc; ruleSets.append(&ruleSet); styleEngine().scheduleInvalidationsForRuleSets(treeScope, ruleSets); return RuleSetInvalidationsScheduled; }
void StyleRuleImport::requestStyleSheet() { if (!m_parentStyleSheet) return; Document* document = m_parentStyleSheet->singleOwnerDocument(); if (!document) return; CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader(); if (!cachedResourceLoader) return; URL absURL; if (!m_parentStyleSheet->baseURL().isNull()) // use parent styleheet's URL as the base URL absURL = URL(m_parentStyleSheet->baseURL(), m_strHref); else absURL = document->completeURL(m_strHref); // Check for a cycle in our import chain. If we encounter a stylesheet // in our parent chain with the same URL, then just bail. StyleSheetContents* rootSheet = m_parentStyleSheet; for (StyleSheetContents* sheet = m_parentStyleSheet; sheet; sheet = sheet->parentStyleSheet()) { if (equalIgnoringFragmentIdentifier(absURL, sheet->baseURL()) || equalIgnoringFragmentIdentifier(absURL, document->completeURL(sheet->originalURL()))) return; rootSheet = sheet; } CachedResourceRequest request(ResourceRequest(absURL), m_parentStyleSheet->charset()); request.setInitiator(cachedResourceRequestInitiators().css); if (m_cachedSheet) m_cachedSheet->removeClient(&m_styleSheetClient); if (m_parentStyleSheet->isUserStyleSheet()) m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request); else m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request); if (m_cachedSheet) { // if the import rule is issued dynamically, the sheet may be // removed from the pending sheet count, so let the doc know // the sheet being imported is pending. if (m_parentStyleSheet && m_parentStyleSheet->loadCompleted() && rootSheet == m_parentStyleSheet) m_parentStyleSheet->startLoadingDynamicSheet(); m_loading = true; m_cachedSheet->addClient(&m_styleSheetClient); } }
void StyleRuleImport::requestStyleSheet() { if (!m_parentStyleSheet) return; Document* document = m_parentStyleSheet->singleOwnerDocument(); if (!document) return; ResourceFetcher* fetcher = document->fetcher(); if (!fetcher) return; KURL absURL; if (!m_parentStyleSheet->baseURL().isNull()) { // use parent styleheet's URL as the base URL absURL = KURL(m_parentStyleSheet->baseURL(), m_strHref); } else { absURL = document->completeURL(m_strHref); } // Check for a cycle in our import chain. If we encounter a stylesheet // in our parent chain with the same URL, then just bail. StyleSheetContents* rootSheet = m_parentStyleSheet; for (StyleSheetContents* sheet = m_parentStyleSheet; sheet; sheet = sheet->parentStyleSheet()) { if (equalIgnoringFragmentIdentifier(absURL, sheet->baseURL()) || equalIgnoringFragmentIdentifier( absURL, document->completeURL(sheet->originalURL()))) return; rootSheet = sheet; } FetchRequest request(ResourceRequest(absURL), FetchInitiatorTypeNames::css, m_parentStyleSheet->charset()); m_resource = CSSStyleSheetResource::fetch(request, fetcher); if (m_resource) { // if the import rule is issued dynamically, the sheet may be // removed from the pending sheet count, so let the doc know // the sheet being imported is pending. if (m_parentStyleSheet && m_parentStyleSheet->loadCompleted() && rootSheet == m_parentStyleSheet) m_parentStyleSheet->startLoadingDynamicSheet(); m_loading = true; m_resource->addClient(m_styleSheetClient); } }
void RuleSet::addRulesFromSheet(StyleSheetContents& sheet, const MediaQueryEvaluator& medium, StyleResolver* resolver) { for (auto& rule : sheet.importRules()) { if (rule->styleSheet() && (!rule->mediaQueries() || medium.eval(rule->mediaQueries(), resolver))) addRulesFromSheet(*rule->styleSheet(), medium, resolver); } bool hasDocumentSecurityOrigin = resolver && resolver->document().securityOrigin()->canRequest(sheet.baseURL()); AddRuleFlags addRuleFlags = static_cast<AddRuleFlags>((hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : 0)); // FIXME: Skip Content Security Policy check when stylesheet is in a user agent shadow tree. // See <https://bugs.webkit.org/show_bug.cgi?id=146663>. bool isInitiatingElementInUserAgentShadowTree = false; addChildRules(sheet.childRules(), medium, resolver, hasDocumentSecurityOrigin, isInitiatingElementInUserAgentShadowTree, addRuleFlags); if (m_autoShrinkToFitEnabled) shrinkToFit(); }
void StyleSheetContents::checkLoaded() { if (isLoading()) return; // Avoid |this| being deleted by scripts that run via // ScriptableDocumentParser::executeScriptsWaitingForResources(). // See https://bugs.webkit.org/show_bug.cgi?id=95106 RefPtrWillBeRawPtr<StyleSheetContents> protect(this); StyleSheetContents* parentSheet = parentStyleSheet(); if (parentSheet) { parentSheet->checkLoaded(); return; } ASSERT(this == rootStyleSheet()); if (m_loadingClients.isEmpty()) return; // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also protect // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoaded| // method. // // When a sheet is loaded it is moved from the set of loading clients // to the set of completed clients. We therefore need the copy in order to // not modify the set while iterating it. WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > loadingClients; copyToVector(m_loadingClients, loadingClients); for (unsigned i = 0; i < loadingClients.size(); ++i) { if (loadingClients[i]->loadCompleted()) continue; // sheetLoaded might be invoked after its owner node is removed from document. if (RefPtrWillBeRawPtr<Node> ownerNode = loadingClients[i]->ownerNode()) { if (loadingClients[i]->sheetLoaded()) ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur); } } }
void DocumentStyleSheetCollection::maybeAddContentExtensionSheet(const String& identifier, StyleSheetContents& sheet) { ASSERT(sheet.isUserStyleSheet()); if (m_contentExtensionSheets.contains(identifier)) return; Ref<CSSStyleSheet> cssSheet = CSSStyleSheet::create(sheet, &m_document); m_contentExtensionSheets.set(identifier, &cssSheet.get()); m_userStyleSheets.append(adoptRef(cssSheet.leakRef())); m_styleResolverChangedTimer.startOneShot(0); }
void StyleSheetContents::checkLoaded() { if (isLoading()) return; StyleSheetContents* parentSheet = parentStyleSheet(); if (parentSheet) { parentSheet->checkLoaded(); return; } ASSERT(this == rootStyleSheet()); if (m_loadingClients.isEmpty()) return; // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run // via ScriptableDocumentParser::executeScriptsWaitingForResources(). Also // protect the |CSSStyleSheet| from being deleted during iteration via the // |sheetLoaded| method. // // When a sheet is loaded it is moved from the set of loading clients // to the set of completed clients. We therefore need the copy in order to // not modify the set while iterating it. HeapVector<Member<CSSStyleSheet>> loadingClients; copyToVector(m_loadingClients, loadingClients); for (unsigned i = 0; i < loadingClients.size(); ++i) { if (loadingClients[i]->loadCompleted()) continue; // sheetLoaded might be invoked after its owner node is removed from // document. if (Node* ownerNode = loadingClients[i]->ownerNode()) { if (loadingClients[i]->sheetLoaded()) ownerNode->notifyLoadedSheetAndAllCriticalSubresources( m_didLoadErrorOccur ? Node::ErrorOccurredLoadingSubresource : Node::NoErrorLoadingSubresource); } } }
void StyleRuleImport::requestStyleSheet(CSSStyleSheet* rootSheet, const CSSParserContext& parserContext) { ASSERT(!rootSheet->parentStyleSheet()); ASSERT(!m_cachedSheet); Node* ownerNode = rootSheet->ownerNode(); if (!ownerNode) return; Document* document = ownerNode->document(); KURL resolvedURL; if (!parserContext.baseURL.isNull()) resolvedURL = KURL(parserContext.baseURL, m_strHref); else resolvedURL = document->completeURL(m_strHref); StyleSheetContents* rootSheetContents = rootSheet->contents(); if (rootSheetContents->hasImportCycle(this, resolvedURL, document->baseURL())) return; ResourceRequest request(resolvedURL); CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader(); if (rootSheetContents->isUserStyleSheet()) m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, parserContext.charset); else m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request, parserContext.charset); if (!m_cachedSheet) return; // if the import rule is issued dynamically, the sheet may be // removed from the pending sheet count, so let the doc know // the sheet being imported is pending. if (rootSheetContents->loadCompleted()) ownerNode->startLoadingDynamicSheet(); m_loadContext = adoptPtr(new LoadContext(rootSheet, parserContext)); m_cachedSheet->addClient(this); }
PassRefPtr<CSSStyleSheet> StyleEngine::createSheet(Element* e, const String& text, TextPosition startPosition, bool createdByParser) { RefPtr<CSSStyleSheet> styleSheet = nullptr; AtomicString textContent(text); HashMap<AtomicString, RawPtr<StyleSheetContents> >::AddResult result = m_textToSheetCache.add(textContent, nullptr); if (result.isNewEntry || !result.storedValue->value) { styleSheet = StyleEngine::parseSheet(e, text, startPosition, createdByParser); if (result.isNewEntry && isCacheableForStyleElement(*styleSheet->contents())) { result.storedValue->value = styleSheet->contents(); m_sheetToTextCache.add(styleSheet->contents(), textContent); } } else { StyleSheetContents* contents = result.storedValue->value; ASSERT(contents); ASSERT(isCacheableForStyleElement(*contents)); ASSERT(contents->singleOwnerDocument() == e->document()); styleSheet = CSSStyleSheet::createInline(contents, e, startPosition); } ASSERT(styleSheet); return styleSheet; }
static StyleSheetContents* parseUASheet(const String& str) { StyleSheetContents* sheet = StyleSheetContents::create(CSSParserContext(UASheetMode)).leakRef(); // leak the sheet on purpose sheet->parseString(str); return sheet; }
Document* StyleSheetContents::singleOwnerDocument() const { StyleSheetContents* root = rootStyleSheet(); return root->clientSingleOwnerDocument(); }
void LinkStyle::setCSSStyleSheet( const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* cachedStyleSheet) { if (!m_owner->isConnected()) { // While the stylesheet is asynchronously loading, the owner can be // disconnected from a document. // In that case, cancel any processing on the loaded content. m_loading = false; removePendingSheet(); if (m_sheet) clearSheet(); return; } // See the comment in PendingScript.cpp about why this check is necessary // here, instead of in the resource fetcher. https://crbug.com/500701. if (!cachedStyleSheet->errorOccurred() && !m_owner->fastGetAttribute(HTMLNames::integrityAttr).isEmpty() && !cachedStyleSheet->integrityMetadata().isEmpty()) { ResourceIntegrityDisposition disposition = cachedStyleSheet->integrityDisposition(); if (disposition == ResourceIntegrityDisposition::NotChecked && !cachedStyleSheet->loadFailedOrCanceled()) { bool checkResult; // cachedStyleSheet->resourceBuffer() can be nullptr on load success. // If response size == 0. const char* data = nullptr; size_t size = 0; if (cachedStyleSheet->resourceBuffer()) { data = cachedStyleSheet->resourceBuffer()->data(); size = cachedStyleSheet->resourceBuffer()->size(); } checkResult = SubresourceIntegrity::CheckSubresourceIntegrity( *m_owner, data, size, KURL(baseURL, href), *cachedStyleSheet); disposition = checkResult ? ResourceIntegrityDisposition::Passed : ResourceIntegrityDisposition::Failed; // TODO(kouhei): Remove this const_cast crbug.com/653502 const_cast<CSSStyleSheetResource*>(cachedStyleSheet) ->setIntegrityDisposition(disposition); } if (disposition == ResourceIntegrityDisposition::Failed) { m_loading = false; removePendingSheet(); notifyLoadedSheetAndAllCriticalSubresources( Node::ErrorOccurredLoadingSubresource); return; } } CSSParserContext parserContext(m_owner->document(), nullptr, baseURL, charset); DEFINE_STATIC_LOCAL(EnumerationHistogram, restoredCachedStyleSheetHistogram, ("Blink.RestoredCachedStyleSheet", 2)); DEFINE_STATIC_LOCAL( EnumerationHistogram, restoredCachedStyleSheet2Histogram, ("Blink.RestoredCachedStyleSheet2", StyleSheetCacheStatusCount)); if (StyleSheetContents* restoredSheet = const_cast<CSSStyleSheetResource*>(cachedStyleSheet) ->restoreParsedStyleSheet(parserContext)) { DCHECK(restoredSheet->isCacheableForResource()); DCHECK(!restoredSheet->isLoading()); if (m_sheet) clearSheet(); m_sheet = CSSStyleSheet::create(restoredSheet, *m_owner); m_sheet->setMediaQueries(MediaQuerySet::create(m_owner->media())); if (m_owner->isInDocumentTree()) setSheetTitle(m_owner->title()); setCrossOriginStylesheetStatus(m_sheet.get()); m_loading = false; restoredSheet->checkLoaded(); restoredCachedStyleSheetHistogram.count(true); restoredCachedStyleSheet2Histogram.count(StyleSheetInMemoryCache); return; } restoredCachedStyleSheetHistogram.count(false); StyleSheetCacheStatus cacheStatus = cachedStyleSheet->response().wasCached() ? StyleSheetInDiskCache : StyleSheetNewEntry; restoredCachedStyleSheet2Histogram.count(cacheStatus); StyleSheetContents* styleSheet = StyleSheetContents::create(href, parserContext); if (m_sheet) clearSheet(); m_sheet = CSSStyleSheet::create(styleSheet, *m_owner); m_sheet->setMediaQueries(MediaQuerySet::create(m_owner->media())); if (m_owner->isInDocumentTree()) setSheetTitle(m_owner->title()); setCrossOriginStylesheetStatus(m_sheet.get()); styleSheet->parseAuthorStyleSheet(cachedStyleSheet, m_owner->document().getSecurityOrigin()); m_loading = false; styleSheet->notifyLoadedSheet(cachedStyleSheet); styleSheet->checkLoaded(); if (styleSheet->isCacheableForResource()) { const_cast<CSSStyleSheetResource*>(cachedStyleSheet) ->saveParsedStyleSheet(styleSheet); } clearResource(); }
CSSDeferredParser::CSSDeferredParser(const CSSParserContext& context, const String& sheetText, StyleSheetContents& styleSheet) : m_context(context) , m_sheetText(sheetText) , m_styleSheet(styleSheet.createWeakPtr()) { }