| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007 Rob Buis | 2 * Copyright (C) 2006, 2007 Rob Buis |
| 3 * Copyright (C) 2008 Apple, Inc. All rights reserved. | 3 * Copyright (C) 2008 Apple, Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "core/dom/shadow/ShadowRoot.h" | 31 #include "core/dom/shadow/ShadowRoot.h" |
| 32 #include "core/frame/LocalFrame.h" | 32 #include "core/frame/LocalFrame.h" |
| 33 #include "core/frame/csp/ContentSecurityPolicy.h" | 33 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 34 #include "core/html/HTMLStyleElement.h" | 34 #include "core/html/HTMLStyleElement.h" |
| 35 #include "core/svg/SVGStyleElement.h" | 35 #include "core/svg/SVGStyleElement.h" |
| 36 #include "platform/TraceEvent.h" | 36 #include "platform/TraceEvent.h" |
| 37 #include "wtf/text/StringBuilder.h" | 37 #include "wtf/text/StringBuilder.h" |
| 38 | 38 |
| 39 namespace blink { | 39 namespace blink { |
| 40 | 40 |
| 41 static bool isCSS(Element* element, const AtomicString& type) | 41 static bool isCSS(const Element& element, const AtomicString& type) |
| 42 { | 42 { |
| 43 return type.isEmpty() || (element->isHTMLElement() ? equalIgnoringCase(type,
"text/css") : (type == "text/css")); | 43 return type.isEmpty() || (element.isHTMLElement() ? equalIgnoringCase(type,
"text/css") : (type == "text/css")); |
| 44 } | 44 } |
| 45 | 45 |
| 46 StyleElement::StyleElement(Document* document, bool createdByParser) | 46 StyleElement::StyleElement(Document* document, bool createdByParser) |
| 47 : m_createdByParser(createdByParser) | 47 : m_createdByParser(createdByParser) |
| 48 , m_loading(false) | 48 , m_loading(false) |
| 49 , m_registeredAsCandidate(false) | 49 , m_registeredAsCandidate(false) |
| 50 , m_startPosition(TextPosition::belowRangePosition()) | 50 , m_startPosition(TextPosition::belowRangePosition()) |
| 51 { | 51 { |
| 52 if (createdByParser && document && document->scriptableDocumentParser() && !
document->isInDocumentWrite()) | 52 if (createdByParser && document && document->scriptableDocumentParser() && !
document->isInDocumentWrite()) |
| 53 m_startPosition = document->scriptableDocumentParser()->textPosition(); | 53 m_startPosition = document->scriptableDocumentParser()->textPosition(); |
| 54 } | 54 } |
| 55 | 55 |
| 56 StyleElement::~StyleElement() | 56 StyleElement::~StyleElement() |
| 57 { | 57 { |
| 58 } | 58 } |
| 59 | 59 |
| 60 StyleElement::ProcessingResult StyleElement::processStyleSheet(Document& documen
t, Element* element) | 60 StyleElement::ProcessingResult StyleElement::processStyleSheet(Document& documen
t, Element& element) |
| 61 { | 61 { |
| 62 TRACE_EVENT0("blink", "StyleElement::processStyleSheet"); | 62 TRACE_EVENT0("blink", "StyleElement::processStyleSheet"); |
| 63 DCHECK(element); | 63 DCHECK(element.isConnected()); |
| 64 DCHECK(element->isConnected()); | |
| 65 | 64 |
| 66 m_registeredAsCandidate = true; | 65 m_registeredAsCandidate = true; |
| 67 document.styleEngine().addStyleSheetCandidateNode(element); | 66 document.styleEngine().addStyleSheetCandidateNode(element); |
| 68 if (m_createdByParser) | 67 if (m_createdByParser) |
| 69 return ProcessingSuccessful; | 68 return ProcessingSuccessful; |
| 70 | 69 |
| 71 return process(element); | 70 return process(element); |
| 72 } | 71 } |
| 73 | 72 |
| 74 void StyleElement::insertedInto(Element* element, ContainerNode* insertionPoint) | 73 void StyleElement::insertedInto(const Element& element, ContainerNode* insertion
Point) |
| 75 { | 74 { |
| 76 if (!insertionPoint->isConnected() || !element->isInShadowTree()) | 75 if (!insertionPoint->isConnected() || !element.isInShadowTree()) |
| 77 return; | 76 return; |
| 78 if (ShadowRoot* scope = element->containingShadowRoot()) | 77 if (ShadowRoot* scope = element.containingShadowRoot()) |
| 79 scope->registerScopedHTMLStyleChild(); | 78 scope->registerScopedHTMLStyleChild(); |
| 80 } | 79 } |
| 81 | 80 |
| 82 void StyleElement::removedFrom(Element* element, ContainerNode* insertionPoint) | 81 void StyleElement::removedFrom(Element& element, ContainerNode* insertionPoint) |
| 83 { | 82 { |
| 84 if (!insertionPoint->isConnected()) | 83 if (!insertionPoint->isConnected()) |
| 85 return; | 84 return; |
| 86 | 85 |
| 87 ShadowRoot* shadowRoot = element->containingShadowRoot(); | 86 ShadowRoot* shadowRoot = element.containingShadowRoot(); |
| 88 if (!shadowRoot) | 87 if (!shadowRoot) |
| 89 shadowRoot = insertionPoint->containingShadowRoot(); | 88 shadowRoot = insertionPoint->containingShadowRoot(); |
| 90 | 89 |
| 91 if (shadowRoot) | 90 if (shadowRoot) |
| 92 shadowRoot->unregisterScopedHTMLStyleChild(); | 91 shadowRoot->unregisterScopedHTMLStyleChild(); |
| 93 | 92 |
| 94 Document& document = element->document(); | 93 Document& document = element.document(); |
| 95 if (m_registeredAsCandidate) { | 94 if (m_registeredAsCandidate) { |
| 96 document.styleEngine().removeStyleSheetCandidateNode(element, shadowRoot
? *toTreeScope(shadowRoot) : toTreeScope(document)); | 95 document.styleEngine().removeStyleSheetCandidateNode(element, shadowRoot
? *toTreeScope(shadowRoot) : toTreeScope(document)); |
| 97 m_registeredAsCandidate = false; | 96 m_registeredAsCandidate = false; |
| 98 } | 97 } |
| 99 | 98 |
| 100 StyleSheet* removedSheet = m_sheet.get(); | 99 StyleSheet* removedSheet = m_sheet.get(); |
| 101 | 100 |
| 102 if (m_sheet) | 101 if (m_sheet) |
| 103 clearSheet(element); | 102 clearSheet(element); |
| 104 if (removedSheet) | 103 if (removedSheet) |
| 105 document.styleEngine().setNeedsActiveStyleUpdate(removedSheet, AnalyzedS
tyleUpdate); | 104 document.styleEngine().setNeedsActiveStyleUpdate(removedSheet, AnalyzedS
tyleUpdate); |
| 106 } | 105 } |
| 107 | 106 |
| 108 StyleElement::ProcessingResult StyleElement::childrenChanged(Element* element) | 107 StyleElement::ProcessingResult StyleElement::childrenChanged(Element& element) |
| 109 { | 108 { |
| 110 DCHECK(element); | |
| 111 if (m_createdByParser) | 109 if (m_createdByParser) |
| 112 return ProcessingSuccessful; | 110 return ProcessingSuccessful; |
| 113 | 111 |
| 114 return process(element); | 112 return process(element); |
| 115 } | 113 } |
| 116 | 114 |
| 117 StyleElement::ProcessingResult StyleElement::finishParsingChildren(Element* elem
ent) | 115 StyleElement::ProcessingResult StyleElement::finishParsingChildren(Element& elem
ent) |
| 118 { | 116 { |
| 119 DCHECK(element); | |
| 120 ProcessingResult result = process(element); | 117 ProcessingResult result = process(element); |
| 121 m_createdByParser = false; | 118 m_createdByParser = false; |
| 122 return result; | 119 return result; |
| 123 } | 120 } |
| 124 | 121 |
| 125 StyleElement::ProcessingResult StyleElement::process(Element* element) | 122 StyleElement::ProcessingResult StyleElement::process(Element& element) |
| 126 { | 123 { |
| 127 if (!element || !element->isConnected()) | 124 if (!element.isConnected()) |
| 128 return ProcessingSuccessful; | 125 return ProcessingSuccessful; |
| 129 return createSheet(element, element->textFromChildren()); | 126 return createSheet(element, element.textFromChildren()); |
| 130 } | 127 } |
| 131 | 128 |
| 132 void StyleElement::clearSheet(Element* ownerElement) | 129 void StyleElement::clearSheet(Element& ownerElement) |
| 133 { | 130 { |
| 134 DCHECK(m_sheet); | 131 DCHECK(m_sheet); |
| 135 | 132 |
| 136 if (ownerElement && m_sheet->isLoading()) | 133 if (m_sheet->isLoading()) |
| 137 ownerElement->document().styleEngine().removePendingSheet(ownerElement,
m_styleEngineContext); | 134 ownerElement.document().styleEngine().removePendingSheet(ownerElement, m
_styleEngineContext); |
| 138 | 135 |
| 139 m_sheet.release()->clearOwnerNode(); | 136 m_sheet.release()->clearOwnerNode(); |
| 140 } | 137 } |
| 141 | 138 |
| 142 static bool shouldBypassMainWorldCSP(Element* element) | 139 static bool shouldBypassMainWorldCSP(const Element& element) |
| 143 { | 140 { |
| 144 // Main world CSP is bypassed within an isolated world. | 141 // Main world CSP is bypassed within an isolated world. |
| 145 LocalFrame* frame = element->document().frame(); | 142 LocalFrame* frame = element.document().frame(); |
| 146 if (frame && frame->script().shouldBypassMainWorldCSP()) | 143 if (frame && frame->script().shouldBypassMainWorldCSP()) |
| 147 return true; | 144 return true; |
| 148 | 145 |
| 149 // Main world CSP is bypassed for style elements in user agent shadow DOM. | 146 // Main world CSP is bypassed for style elements in user agent shadow DOM. |
| 150 ShadowRoot* root = element->containingShadowRoot(); | 147 ShadowRoot* root = element.containingShadowRoot(); |
| 151 if (root && root->type() == ShadowRootType::UserAgent) | 148 if (root && root->type() == ShadowRootType::UserAgent) |
| 152 return true; | 149 return true; |
| 153 | 150 |
| 154 return false; | 151 return false; |
| 155 } | 152 } |
| 156 | 153 |
| 157 StyleElement::ProcessingResult StyleElement::createSheet(Element* e, const Strin
g& text) | 154 StyleElement::ProcessingResult StyleElement::createSheet(Element& element, const
String& text) |
| 158 { | 155 { |
| 159 DCHECK(e); | 156 DCHECK(element.isConnected()); |
| 160 DCHECK(e->isConnected()); | 157 Document& document = element.document(); |
| 161 Document& document = e->document(); | |
| 162 | 158 |
| 163 const ContentSecurityPolicy* csp = document.contentSecurityPolicy(); | 159 const ContentSecurityPolicy* csp = document.contentSecurityPolicy(); |
| 164 bool passesContentSecurityPolicyChecks = shouldBypassMainWorldCSP(e) | 160 bool passesContentSecurityPolicyChecks = shouldBypassMainWorldCSP(element) |
| 165 || csp->allowStyleWithHash(text, ContentSecurityPolicy::InlineType::Bloc
k) | 161 || csp->allowStyleWithHash(text, ContentSecurityPolicy::InlineType::Bloc
k) |
| 166 || csp->allowInlineStyle(e->document().url(), e->fastGetAttribute(HTMLNa
mes::nonceAttr), m_startPosition.m_line, text); | 162 || csp->allowInlineStyle(document.url(), element.fastGetAttribute(HTMLNa
mes::nonceAttr), m_startPosition.m_line, text); |
| 167 | 163 |
| 168 // Clearing the current sheet may remove the cache entry so create the new s
heet first | 164 // Clearing the current sheet may remove the cache entry so create the new s
heet first |
| 169 CSSStyleSheet* newSheet = nullptr; | 165 CSSStyleSheet* newSheet = nullptr; |
| 170 | 166 |
| 171 // If type is empty or CSS, this is a CSS style sheet. | 167 // If type is empty or CSS, this is a CSS style sheet. |
| 172 const AtomicString& type = this->type(); | 168 const AtomicString& type = this->type(); |
| 173 if (isCSS(e, type) && passesContentSecurityPolicyChecks) { | 169 if (isCSS(element, type) && passesContentSecurityPolicyChecks) { |
| 174 MediaQuerySet* mediaQueries = MediaQuerySet::create(media()); | 170 MediaQuerySet* mediaQueries = MediaQuerySet::create(media()); |
| 175 | 171 |
| 176 MediaQueryEvaluator screenEval("screen", true); | 172 MediaQueryEvaluator screenEval("screen", true); |
| 177 MediaQueryEvaluator printEval("print", true); | 173 MediaQueryEvaluator printEval("print", true); |
| 178 if (screenEval.eval(mediaQueries) || printEval.eval(mediaQueries)) { | 174 if (screenEval.eval(mediaQueries) || printEval.eval(mediaQueries)) { |
| 179 m_loading = true; | 175 m_loading = true; |
| 180 TextPosition startPosition = m_startPosition == TextPosition::belowR
angePosition() ? TextPosition::minimumPosition() : m_startPosition; | 176 TextPosition startPosition = m_startPosition == TextPosition::belowR
angePosition() ? TextPosition::minimumPosition() : m_startPosition; |
| 181 newSheet = document.styleEngine().createSheet(e, text, startPosition
, m_styleEngineContext); | 177 newSheet = document.styleEngine().createSheet(element, text, startPo
sition, m_styleEngineContext); |
| 182 newSheet->setMediaQueries(mediaQueries); | 178 newSheet->setMediaQueries(mediaQueries); |
| 183 m_loading = false; | 179 m_loading = false; |
| 184 } | 180 } |
| 185 } | 181 } |
| 186 | 182 |
| 187 if (m_sheet) | 183 if (m_sheet) |
| 188 clearSheet(e); | 184 clearSheet(element); |
| 189 | 185 |
| 190 m_sheet = newSheet; | 186 m_sheet = newSheet; |
| 191 if (m_sheet) | 187 if (m_sheet) |
| 192 m_sheet->contents()->checkLoaded(); | 188 m_sheet->contents()->checkLoaded(); |
| 193 | 189 |
| 194 return passesContentSecurityPolicyChecks ? ProcessingSuccessful : Processing
FatalError; | 190 return passesContentSecurityPolicyChecks ? ProcessingSuccessful : Processing
FatalError; |
| 195 } | 191 } |
| 196 | 192 |
| 197 bool StyleElement::isLoading() const | 193 bool StyleElement::isLoading() const |
| 198 { | 194 { |
| 199 if (m_loading) | 195 if (m_loading) |
| 200 return true; | 196 return true; |
| 201 return m_sheet ? m_sheet->isLoading() : false; | 197 return m_sheet ? m_sheet->isLoading() : false; |
| 202 } | 198 } |
| 203 | 199 |
| 204 bool StyleElement::sheetLoaded(Document& document) | 200 bool StyleElement::sheetLoaded(Document& document) |
| 205 { | 201 { |
| 206 if (isLoading()) | 202 if (isLoading()) |
| 207 return false; | 203 return false; |
| 208 | 204 |
| 209 document.styleEngine().removePendingSheet(m_sheet->ownerNode(), m_styleEngin
eContext); | 205 document.styleEngine().removePendingSheet(*m_sheet->ownerNode(), m_styleEngi
neContext); |
| 210 return true; | 206 return true; |
| 211 } | 207 } |
| 212 | 208 |
| 213 void StyleElement::startLoadingDynamicSheet(Document& document) | 209 void StyleElement::startLoadingDynamicSheet(Document& document) |
| 214 { | 210 { |
| 215 document.styleEngine().addPendingSheet(m_styleEngineContext); | 211 document.styleEngine().addPendingSheet(m_styleEngineContext); |
| 216 } | 212 } |
| 217 | 213 |
| 218 DEFINE_TRACE(StyleElement) | 214 DEFINE_TRACE(StyleElement) |
| 219 { | 215 { |
| 220 visitor->trace(m_sheet); | 216 visitor->trace(m_sheet); |
| 221 } | 217 } |
| 222 | 218 |
| 223 } // namespace blink | 219 } // namespace blink |
| OLD | NEW |