diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
commit | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch) | |
tree | 988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebCore/html/HTMLLinkElement.cpp | |
parent | dd91e772430dc294e3bf478c119ef8d43c0a3358 (diff) | |
download | qtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz |
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebCore/html/HTMLLinkElement.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLLinkElement.cpp | 131 |
1 files changed, 60 insertions, 71 deletions
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp index efe76155a..0db663604 100644 --- a/Source/WebCore/html/HTMLLinkElement.cpp +++ b/Source/WebCore/html/HTMLLinkElement.cpp @@ -29,7 +29,6 @@ #include "CachedCSSStyleSheet.h" #include "CachedResource.h" #include "CachedResourceLoader.h" -#include "CSSStyleSelector.h" #include "Document.h" #include "EventSender.h" #include "Frame.h" @@ -42,10 +41,10 @@ #include "MediaList.h" #include "MediaQueryEvaluator.h" #include "Page.h" -#include "ResourceHandle.h" #include "ScriptEventListener.h" #include "SecurityOrigin.h" #include "Settings.h" +#include "StyleResolver.h" #include <wtf/StdLibExtras.h> namespace WebCore { @@ -83,10 +82,8 @@ HTMLLinkElement::~HTMLLinkElement() if (m_sheet) m_sheet->clearOwnerNode(); - if (m_cachedSheet) { + if (m_cachedSheet) m_cachedSheet->removeClient(this); - removePendingSheet(); - } if (inDocument()) document()->removeStyleSheetCandidateNode(this); @@ -126,7 +123,7 @@ void HTMLLinkElement::setDisabledState(bool disabled) if (!m_sheet && m_disabledState == EnabledViaScript) process(); else - document()->styleSelectorChanged(DeferRecalcStyle); // Update the style selector. + document()->styleResolverChanged(DeferRecalcStyle); // Update the style selector. } } @@ -208,8 +205,8 @@ void HTMLLinkElement::process() bool mediaQueryMatches = true; if (!m_media.isEmpty()) { - RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(document()); - RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media); + RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(document()); + RefPtr<MediaQuerySet> media = MediaQuerySet::createAllowingDescriptionSyntax(m_media); MediaQueryEvaluator evaluator(document()->frame()->view()->mediaType(), document()->frame(), documentStyle.get()); mediaQueryMatches = evaluator.eval(media.get()); } @@ -233,27 +230,40 @@ void HTMLLinkElement::process() } } else if (m_sheet) { // we no longer contain a stylesheet, e.g. perhaps rel or type was changed - m_sheet = 0; - document()->styleSelectorChanged(DeferRecalcStyle); + clearSheet(); + document()->styleResolverChanged(DeferRecalcStyle); } } -void HTMLLinkElement::insertedIntoDocument() +void HTMLLinkElement::clearSheet() +{ + ASSERT(m_sheet); + ASSERT(m_sheet->ownerNode() == this); + m_sheet->clearOwnerNode(); + m_sheet = 0; +} + +Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(Node* insertionPoint) { - HTMLElement::insertedIntoDocument(); + HTMLElement::insertedInto(insertionPoint); + if (!insertionPoint->inDocument()) + return InsertionDone; m_isInShadowTree = isInShadowTree(); if (m_isInShadowTree) - return; + return InsertionDone; document()->addStyleSheetCandidateNode(this, m_createdByParser); process(); + return InsertionDone; } -void HTMLLinkElement::removedFromDocument() +void HTMLLinkElement::removedFrom(Node* insertionPoint) { - HTMLElement::removedFromDocument(); + HTMLElement::removedFrom(insertionPoint); + if (!insertionPoint->inDocument()) + return; if (m_isInShadowTree) { ASSERT(!m_sheet); @@ -261,14 +271,14 @@ void HTMLLinkElement::removedFromDocument() } document()->removeStyleSheetCandidateNode(this); - if (m_sheet) { - ASSERT(m_sheet->ownerNode() == this); - m_sheet->clearOwnerNode(); - m_sheet = 0; - } + if (m_sheet) + clearSheet(); + + if (styleSheetIsLoading()) + removePendingSheet(); if (document()->renderer()) - document()->styleSelectorChanged(DeferRecalcStyle); + document()->styleResolverChanged(DeferRecalcStyle); } void HTMLLinkElement::finishParsingChildren() @@ -277,70 +287,49 @@ void HTMLLinkElement::finishParsingChildren() HTMLElement::finishParsingChildren(); } -void HTMLLinkElement::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet) +void HTMLLinkElement::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* cachedStyleSheet) { if (!inDocument()) { ASSERT(!m_sheet); return; } + // Completing the sheet load may cause scripts to execute. + RefPtr<Node> protector(this); - m_sheet = CSSStyleSheet::create(this, href, baseURL, charset); + CSSParserContext parserContext(document(), baseURL, charset); - bool strictParsing = !document()->inQuirksMode(); - bool enforceMIMEType = strictParsing; - bool crossOriginCSS = false; - bool validMIMEType = false; - bool needsSiteSpecificQuirks = document()->page() && document()->page()->settings()->needsSiteSpecificQuirks(); +#if ENABLE(PARSED_STYLE_SHEET_CACHING) + if (RefPtr<StyleSheetInternal> restoredSheet = const_cast<CachedCSSStyleSheet*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) { + ASSERT(restoredSheet->isCacheable()); + ASSERT(!restoredSheet->isLoading()); - // Check to see if we should enforce the MIME type of the CSS resource in strict mode. - // Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748> - if (enforceMIMEType && document()->page() && !document()->page()->settings()->enforceCSSMIMETypeInNoQuirksMode()) - enforceMIMEType = false; + m_sheet = CSSStyleSheet::create(restoredSheet, this); + m_sheet->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(m_media)); + m_sheet->setTitle(title()); -#ifdef BUILDING_ON_LEOPARD - if (enforceMIMEType && needsSiteSpecificQuirks) { - // Covers both http and https, with or without "www." - if (baseURL.string().contains("mcafee.com/japan/", false)) - enforceMIMEType = false; + m_loading = false; + sheetLoaded(); + notifyLoadedSheetAndAllCriticalSubresources(false); + return; } #endif - String sheetText = sheet->sheetText(enforceMIMEType, &validMIMEType); - m_sheet->parseString(sheetText, strictParsing); - - // If we're loading a stylesheet cross-origin, and the MIME type is not - // standard, require the CSS to at least start with a syntactically - // valid CSS rule. - // This prevents an attacker playing games by injecting CSS strings into - // HTML, XML, JSON, etc. etc. - if (!document()->securityOrigin()->canRequest(baseURL)) - crossOriginCSS = true; - - if (crossOriginCSS && !validMIMEType && !m_sheet->hasSyntacticallyValidCSSHeader()) - m_sheet = CSSStyleSheet::create(this, href, baseURL, charset); - - if (strictParsing && needsSiteSpecificQuirks) { - // Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>. - DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css")); - DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n")); - // There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet, - // while the other lacks the second trailing newline. - if (baseURL.string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText) - && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) { - ASSERT(m_sheet->length() == 1); - ExceptionCode ec; - m_sheet->deleteRule(0, ec); - } - } + RefPtr<StyleSheetInternal> styleSheet = StyleSheetInternal::create(href, baseURL, parserContext); + m_sheet = CSSStyleSheet::create(styleSheet, this); + m_sheet->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(m_media)); m_sheet->setTitle(title()); - RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media); - m_sheet->setMedia(media.get()); + styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document()->securityOrigin()); m_loading = false; - m_sheet->notifyLoadedSheet(sheet); - m_sheet->checkLoaded(); + styleSheet->notifyLoadedSheet(cachedStyleSheet); + styleSheet->checkLoaded(); + +#if ENABLE(PARSED_STYLE_SHEET_CACHING) + if (styleSheet->isCacheable()) + const_cast<CachedCSSStyleSheet*>(cachedStyleSheet)->saveParsedStyleSheet(styleSheet); +#endif } bool HTMLLinkElement::styleSheetIsLoading() const @@ -349,7 +338,7 @@ bool HTMLLinkElement::styleSheetIsLoading() const return true; if (!m_sheet) return false; - return m_sheet->isLoading(); + return m_sheet->internal()->isLoading(); } void HTMLLinkElement::linkLoaded() @@ -442,7 +431,7 @@ void HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const // Walk the URLs linked by the linked-to stylesheet. if (CSSStyleSheet* styleSheet = const_cast<HTMLLinkElement*>(this)->sheet()) - styleSheet->addSubresourceStyleURLs(urls); + styleSheet->internal()->addSubresourceStyleURLs(urls); } void HTMLLinkElement::addPendingSheet(PendingSheetType type) @@ -465,7 +454,7 @@ void HTMLLinkElement::removePendingSheet() return; if (type == NonBlocking) { // Document::removePendingSheet() triggers the style selector recalc for blocking sheets. - document()->styleSelectorChanged(RecalcStyleImmediately); + document()->styleResolverChanged(RecalcStyleImmediately); return; } document()->removePendingSheet(); |