diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp index 8233785616d..cea6ad5b960 100644 --- a/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp +++ b/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp @@ -21,6 +21,7 @@ #include "config.h" #include "core/dom/StyleElement.h" +#include "bindings/v8/ScriptController.h" #include "core/css/MediaList.h" #include "core/css/MediaQueryEvaluator.h" #include "core/css/StyleSheetContents.h" @@ -28,8 +29,10 @@ #include "core/dom/Element.h" #include "core/dom/ScriptableDocumentParser.h" #include "core/dom/StyleEngine.h" +#include "core/frame/LocalFrame.h" +#include "core/frame/csp/ContentSecurityPolicy.h" #include "core/html/HTMLStyleElement.h" -#include "core/frame/ContentSecurityPolicy.h" +#include "platform/TraceEvent.h" #include "wtf/text/StringBuilder.h" namespace WebCore { @@ -42,6 +45,7 @@ static bool isCSS(Element* element, const AtomicString& type) StyleElement::StyleElement(Document* document, bool createdByParser) : m_createdByParser(createdByParser) , m_loading(false) + , m_registeredAsCandidate(false) , m_startPosition(TextPosition::belowRangePosition()) { if (createdByParser && document && document->scriptableDocumentParser() && !document->isInDocumentWrite()) @@ -50,13 +54,19 @@ StyleElement::StyleElement(Document* document, bool createdByParser) StyleElement::~StyleElement() { +#if !ENABLE(OILPAN) if (m_sheet) clearSheet(); +#endif } void StyleElement::processStyleSheet(Document& document, Element* element) { + TRACE_EVENT0("webkit", "StyleElement::processStyleSheet"); ASSERT(element); + ASSERT(element->inDocument()); + + m_registeredAsCandidate = true; document.styleEngine()->addStyleSheetCandidateNode(element, m_createdByParser); if (m_createdByParser) return; @@ -64,17 +74,26 @@ void StyleElement::processStyleSheet(Document& document, Element* element) process(element); } -void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode) +void StyleElement::removedFromDocument(Document& document, Element* element) +{ + removedFromDocument(document, element, 0, document); +} + +void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode, TreeScope& treeScope) { ASSERT(element); - document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode); - RefPtr<StyleSheet> removedSheet = m_sheet; + if (m_registeredAsCandidate) { + document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope); + m_registeredAsCandidate = false; + } + + RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet.get(); if (m_sheet) - clearSheet(); - - document.removedStyleSheet(removedSheet.get(), RecalcStyleDeferred, AnalyzedStyleUpdate); + clearSheet(element); + if (removedSheet) + document.removedStyleSheet(removedSheet.get(), AnalyzedStyleUpdate); } void StyleElement::clearDocumentData(Document& document, Element* element) @@ -82,8 +101,11 @@ void StyleElement::clearDocumentData(Document& document, Element* element) if (m_sheet) m_sheet->clearOwnerNode(); - if (element->inDocument()) - document.styleEngine()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0); + if (element->inDocument()) { + ContainerNode* scopingNode = isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0; + TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : element->treeScope(); + document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope); + } } void StyleElement::childrenChanged(Element* element) @@ -109,9 +131,13 @@ void StyleElement::process(Element* element) createSheet(element, element->textFromChildren()); } -void StyleElement::clearSheet() +void StyleElement::clearSheet(Element* ownerElement) { ASSERT(m_sheet); + + if (ownerElement && m_sheet->isLoading()) + ownerElement->document().styleEngine()->removePendingSheet(ownerElement); + m_sheet.release()->clearOwnerNode(); } @@ -120,30 +146,27 @@ void StyleElement::createSheet(Element* e, const String& text) ASSERT(e); ASSERT(e->inDocument()); Document& document = e->document(); - if (m_sheet) { - if (m_sheet->isLoading()) - document.styleEngine()->removePendingSheet(e); - clearSheet(); - } + if (m_sheet) + clearSheet(e); + + // Inline style added from an isolated world should bypass the main world's + // CSP just as an inline script would. + LocalFrame* frame = document.frame(); + bool shouldBypassMainWorldContentSecurityPolicy = frame && frame->script().shouldBypassMainWorldContentSecurityPolicy(); // If type is empty or CSS, this is a CSS style sheet. const AtomicString& type = this->type(); - bool passesContentSecurityPolicyChecks = document.contentSecurityPolicy()->allowStyleNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line); + bool passesContentSecurityPolicyChecks = shouldBypassMainWorldContentSecurityPolicy || document.contentSecurityPolicy()->allowStyleHash(text) || document.contentSecurityPolicy()->allowStyleNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line); if (isCSS(e, type) && passesContentSecurityPolicyChecks) { - RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media()); + RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media()); MediaQueryEvaluator screenEval("screen", true); MediaQueryEvaluator printEval("print", true); if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) { - document.styleEngine()->addPendingSheet(); m_loading = true; - TextPosition startPosition = m_startPosition == TextPosition::belowRangePosition() ? TextPosition::minimumPosition() : m_startPosition; - m_sheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document.inputEncoding()); + m_sheet = document.styleEngine()->createSheet(e, text, startPosition, m_createdByParser); m_sheet->setMediaQueries(mediaQueries.release()); - m_sheet->setTitle(e->title()); - m_sheet->contents()->parseStringAtPosition(text, startPosition, m_createdByParser); - m_loading = false; } } @@ -173,4 +196,9 @@ void StyleElement::startLoadingDynamicSheet(Document& document) document.styleEngine()->addPendingSheet(); } +void StyleElement::trace(Visitor* visitor) +{ + visitor->trace(m_sheet); +} + } |