Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: third_party/WebKit/Source/core/html/HTMLLinkElement.cpp

Issue 2426513003: Refactor LinkStyle out of HTMLLinkElement (Closed)
Patch Set: Review comment Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
index 7b5cfd145bd2136c74b40fc4c2ef13be5512615f..9b402d3c27a141347a0b993a6164e753549fbd3b 100644
--- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -27,50 +27,25 @@
#include "bindings/core/v8/ScriptEventListener.h"
#include "core/HTMLNames.h"
-#include "core/css/MediaList.h"
-#include "core/css/MediaQueryEvaluator.h"
-#include "core/css/StyleSheetContents.h"
-#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
-#include "core/dom/StyleEngine.h"
#include "core/dom/TaskRunnerHelper.h"
#include "core/events/Event.h"
-#include "core/fetch/CSSStyleSheetResource.h"
-#include "core/fetch/FetchRequest.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/LocalFrame.h"
-#include "core/frame/SubresourceIntegrity.h"
#include "core/frame/UseCounter.h"
-#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/CrossOriginAttribute.h"
#include "core/html/LinkManifest.h"
#include "core/html/imports/LinkImport.h"
#include "core/inspector/ConsoleMessage.h"
-#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/loader/NetworkHintsInterface.h"
#include "core/origin_trials/OriginTrials.h"
-#include "core/style/StyleInheritedData.h"
-#include "platform/ContentType.h"
-#include "platform/Histogram.h"
-#include "platform/MIMETypeRegistry.h"
-#include "platform/RuntimeEnabledFeatures.h"
#include "public/platform/WebIconSizesParser.h"
#include "public/platform/WebSize.h"
-#include "wtf/StdLibExtras.h"
namespace blink {
using namespace HTMLNames;
-static bool styleSheetTypeIsSupported(const String& type) {
- String trimmedType = ContentType(type).type();
- return trimmedType.isEmpty() ||
- MIMETypeRegistry::isSupportedStyleSheetMIMEType(trimmedType);
-}
-
inline HTMLLinkElement::HTMLLinkElement(Document& document,
bool createdByParser)
: HTMLElement(linkTag, document),
@@ -384,391 +359,4 @@ DEFINE_TRACE_WRAPPERS(HTMLLinkElement) {
HTMLElement::traceWrappers(visitor);
}
-LinkStyle* LinkStyle::create(HTMLLinkElement* owner) {
- return new LinkStyle(owner);
-}
-
-LinkStyle::LinkStyle(HTMLLinkElement* owner)
- : LinkResource(owner),
- m_disabledState(Unset),
- m_pendingSheetType(None),
- m_loading(false),
- m_firedLoad(false),
- m_loadedSheet(false),
- m_fetchFollowingCORS(false) {}
-
-LinkStyle::~LinkStyle() {}
-
-Document& LinkStyle::document() {
- return m_owner->document();
-}
-
-enum StyleSheetCacheStatus {
- StyleSheetNewEntry,
- StyleSheetInDiskCache,
- StyleSheetInMemoryCache,
- StyleSheetCacheStatusCount,
-};
-
-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();
-}
-
-bool LinkStyle::sheetLoaded() {
- if (!styleSheetIsLoading()) {
- removePendingSheet();
- return true;
- }
- return false;
-}
-
-void LinkStyle::notifyLoadedSheetAndAllCriticalSubresources(
- Node::LoadedSheetErrorStatus errorStatus) {
- if (m_firedLoad)
- return;
- m_loadedSheet = (errorStatus == Node::NoErrorLoadingSubresource);
- if (m_owner)
- m_owner->scheduleEvent();
- m_firedLoad = true;
-}
-
-void LinkStyle::startLoadingDynamicSheet() {
- DCHECK_LT(m_pendingSheetType, Blocking);
- addPendingSheet(Blocking);
-}
-
-void LinkStyle::clearSheet() {
- DCHECK(m_sheet);
- DCHECK_EQ(m_sheet->ownerNode(), m_owner);
- m_sheet.release()->clearOwnerNode();
-}
-
-bool LinkStyle::styleSheetIsLoading() const {
- if (m_loading)
- return true;
- if (!m_sheet)
- return false;
- return m_sheet->contents()->isLoading();
-}
-
-void LinkStyle::addPendingSheet(PendingSheetType type) {
- if (type <= m_pendingSheetType)
- return;
- m_pendingSheetType = type;
-
- if (m_pendingSheetType == NonBlocking)
- return;
- m_owner->document().styleEngine().addPendingSheet(m_styleEngineContext);
-}
-
-void LinkStyle::removePendingSheet() {
- DCHECK(m_owner);
- PendingSheetType type = m_pendingSheetType;
- m_pendingSheetType = None;
-
- if (type == None)
- return;
- if (type == NonBlocking) {
- // Tell StyleEngine to re-compute styleSheets of this m_owner's treescope.
- m_owner->document().styleEngine().modifiedStyleSheetCandidateNode(*m_owner);
- return;
- }
-
- m_owner->document().styleEngine().removePendingSheet(*m_owner,
- m_styleEngineContext);
-}
-
-void LinkStyle::setDisabledState(bool disabled) {
- LinkStyle::DisabledState oldDisabledState = m_disabledState;
- m_disabledState = disabled ? Disabled : EnabledViaScript;
- if (oldDisabledState != m_disabledState) {
- // If we change the disabled state while the sheet is still loading, then we
- // have to perform three checks:
- if (styleSheetIsLoading()) {
- // Check #1: The sheet becomes disabled while loading.
- if (m_disabledState == Disabled)
- removePendingSheet();
-
- // Check #2: An alternate sheet becomes enabled while it is still loading.
- if (m_owner->relAttribute().isAlternate() &&
- m_disabledState == EnabledViaScript)
- addPendingSheet(Blocking);
-
- // Check #3: A main sheet becomes enabled while it was still loading and
- // after it was disabled via script. It takes really terrible code to make
- // this happen (a double toggle for no reason essentially). This happens
- // on virtualplastic.net, which manages to do about 12 enable/disables on
- // only 3 sheets. :)
- if (!m_owner->relAttribute().isAlternate() &&
- m_disabledState == EnabledViaScript && oldDisabledState == Disabled)
- addPendingSheet(Blocking);
-
- // If the sheet is already loading just bail.
- return;
- }
-
- if (m_sheet) {
- m_sheet->setDisabled(disabled);
- return;
- }
-
- if (m_disabledState == EnabledViaScript && m_owner->shouldProcessStyle())
- process();
- }
-}
-
-void LinkStyle::setCrossOriginStylesheetStatus(CSSStyleSheet* sheet) {
- if (m_fetchFollowingCORS && resource() && !resource()->errorOccurred()) {
- // Record the security origin the CORS access check succeeded at, if cross
- // origin. Only origins that are script accessible to it may access the
- // stylesheet's rules.
- sheet->setAllowRuleAccessFromOrigin(
- m_owner->document().getSecurityOrigin());
- }
- m_fetchFollowingCORS = false;
-}
-
-void LinkStyle::process() {
- DCHECK(m_owner->shouldProcessStyle());
- String type = m_owner->typeValue().lower();
- String as = m_owner->asValue().lower();
- String media = m_owner->media().lower();
- LinkRequestBuilder builder(m_owner);
-
- if (m_owner->relAttribute().getIconType() != InvalidIcon &&
- builder.url().isValid() && !builder.url().isEmpty()) {
- if (!m_owner->shouldLoadLink())
- return;
- if (!document().getSecurityOrigin()->canDisplay(builder.url()))
- return;
- if (!document().contentSecurityPolicy()->allowImageFromSource(
- builder.url()))
- return;
- if (document().frame() && document().frame()->loader().client())
- document().frame()->loader().client()->dispatchDidChangeIcons(
- m_owner->relAttribute().getIconType());
- }
-
- if (!m_owner->loadLink(type, as, media, builder.url()))
- return;
-
- if (m_disabledState != Disabled && m_owner->relAttribute().isStyleSheet() &&
- styleSheetTypeIsSupported(type) && shouldLoadResource() &&
- builder.url().isValid()) {
- if (resource()) {
- removePendingSheet();
- clearResource();
- clearFetchFollowingCORS();
- }
-
- if (!m_owner->shouldLoadLink())
- return;
-
- m_loading = true;
-
- String title = m_owner->title();
- if (!title.isEmpty() && !m_owner->isAlternate() &&
- m_disabledState != EnabledViaScript && m_owner->isInDocumentTree())
- document().styleEngine().setPreferredStylesheetSetNameIfNotSet(
- title, StyleEngine::DontUpdateActiveSheets);
-
- bool mediaQueryMatches = true;
- LocalFrame* frame = loadingFrame();
- if (!m_owner->media().isEmpty() && frame) {
- MediaQuerySet* media = MediaQuerySet::create(m_owner->media());
- MediaQueryEvaluator evaluator(frame);
- mediaQueryMatches = evaluator.eval(media);
- }
-
- // Don't hold up layout tree construction and script execution on
- // stylesheets that are not needed for the layout at the moment.
- bool blocking = mediaQueryMatches && !m_owner->isAlternate() &&
- m_owner->isCreatedByParser();
- addPendingSheet(blocking ? Blocking : NonBlocking);
-
- // Load stylesheets that are not needed for the layout immediately with low
- // priority. When the link element is created by scripts, load the
- // stylesheets asynchronously but in high priority.
- bool lowPriority = !mediaQueryMatches || m_owner->isAlternate();
- FetchRequest request = builder.build(lowPriority);
- CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue(
- m_owner->fastGetAttribute(HTMLNames::crossoriginAttr));
- if (crossOrigin != CrossOriginAttributeNotSet) {
- request.setCrossOriginAccessControl(document().getSecurityOrigin(),
- crossOrigin);
- setFetchFollowingCORS();
- }
-
- String integrityAttr = m_owner->fastGetAttribute(HTMLNames::integrityAttr);
- if (!integrityAttr.isEmpty()) {
- IntegrityMetadataSet metadataSet;
- SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet);
- request.setIntegrityMetadata(metadataSet);
- }
- setResource(CSSStyleSheetResource::fetch(request, document().fetcher()));
-
- if (m_loading && !resource()) {
- // The request may have been denied if (for example) the stylesheet is
- // local and the document is remote, or if there was a Content Security
- // Policy Failure. setCSSStyleSheet() can be called synchronuosly in
- // setResource() and thus resource() is null and |m_loading| is false in
- // such cases even if the request succeeds.
- m_loading = false;
- removePendingSheet();
- notifyLoadedSheetAndAllCriticalSubresources(
- Node::ErrorOccurredLoadingSubresource);
- }
- } else if (m_sheet) {
- // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
- StyleSheet* removedSheet = m_sheet.get();
- clearSheet();
- document().styleEngine().setNeedsActiveStyleUpdate(removedSheet,
- FullStyleUpdate);
- }
-}
-
-void LinkStyle::setSheetTitle(
- const String& title,
- StyleEngine::ActiveSheetsUpdate updateActiveSheets) {
- if (!m_owner->isInDocumentTree() || !m_owner->relAttribute().isStyleSheet())
- return;
-
- if (m_sheet)
- m_sheet->setTitle(title);
-
- if (title.isEmpty() || !isUnset() || m_owner->isAlternate())
- return;
-
- KURL href = m_owner->getNonEmptyURLAttribute(hrefAttr);
- if (href.isValid() && !href.isEmpty())
- document().styleEngine().setPreferredStylesheetSetNameIfNotSet(
- title, updateActiveSheets);
-}
-
-void LinkStyle::ownerRemoved() {
- if (m_sheet)
- clearSheet();
-
- if (styleSheetIsLoading())
- removePendingSheet();
-}
-
-DEFINE_TRACE(LinkStyle) {
- visitor->trace(m_sheet);
- LinkResource::trace(visitor);
- ResourceOwner<StyleSheetResource>::trace(visitor);
-}
-
} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLLinkElement.h ('k') | third_party/WebKit/Source/core/html/LinkStyle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698