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

Side by Side Diff: Source/core/html/HTMLStyleElement.cpp

Issue 325663003: Remove scoped styles (retry) (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix layout test (and expectation) Created 6 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/html/HTMLStyleElement.h ('k') | Source/core/html/HTMLStyleElement.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2010 Apple Inc. All rights reserved. 5 * Copyright (C) 2003, 2010 Apple Inc. All rights reserved.
6 * (C) 2007 Rob Buis (buis@kde.org) 6 * (C) 2007 Rob Buis (buis@kde.org)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 { 42 {
43 DEFINE_STATIC_LOCAL(StyleEventSender, sharedLoadEventSender, (EventTypeNames ::load)); 43 DEFINE_STATIC_LOCAL(StyleEventSender, sharedLoadEventSender, (EventTypeNames ::load));
44 return sharedLoadEventSender; 44 return sharedLoadEventSender;
45 } 45 }
46 46
47 inline HTMLStyleElement::HTMLStyleElement(Document& document, bool createdByPars er) 47 inline HTMLStyleElement::HTMLStyleElement(Document& document, bool createdByPars er)
48 : HTMLElement(styleTag, document) 48 : HTMLElement(styleTag, document)
49 , StyleElement(&document, createdByParser) 49 , StyleElement(&document, createdByParser)
50 , m_firedLoad(false) 50 , m_firedLoad(false)
51 , m_loadedSheet(false) 51 , m_loadedSheet(false)
52 , m_scopedStyleRegistrationState(NotRegistered)
53 { 52 {
54 ScriptWrappable::init(this); 53 ScriptWrappable::init(this);
55 } 54 }
56 55
57 HTMLStyleElement::~HTMLStyleElement() 56 HTMLStyleElement::~HTMLStyleElement()
58 { 57 {
59 // During tear-down, willRemove isn't called, so m_scopedStyleRegistrationSt ate may still be RegisteredAsScoped or RegisteredInShadowRoot here.
60 // Therefore we can't ASSERT(m_scopedStyleRegistrationState == NotRegistered ).
61 #if !ENABLE(OILPAN) 58 #if !ENABLE(OILPAN)
62 StyleElement::clearDocumentData(document(), this); 59 StyleElement::clearDocumentData(document(), this);
63 #endif 60 #endif
64 61
65 styleLoadEventSender().cancelEvent(this); 62 styleLoadEventSender().cancelEvent(this);
66 } 63 }
67 64
68 PassRefPtrWillBeRawPtr<HTMLStyleElement> HTMLStyleElement::create(Document& docu ment, bool createdByParser) 65 PassRefPtrWillBeRawPtr<HTMLStyleElement> HTMLStyleElement::create(Document& docu ment, bool createdByParser)
69 { 66 {
70 return adoptRefWillBeRefCountedGarbageCollected(new HTMLStyleElement(documen t, createdByParser)); 67 return adoptRefWillBeRefCountedGarbageCollected(new HTMLStyleElement(documen t, createdByParser));
71 } 68 }
72 69
73 void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value) 70 void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value)
74 { 71 {
75 if (name == titleAttr && m_sheet) { 72 if (name == titleAttr && m_sheet) {
76 m_sheet->setTitle(value); 73 m_sheet->setTitle(value);
77 } else if (name == scopedAttr && ContextFeatures::styleScopedEnabled(&docume nt())) {
78 scopedAttributeChanged(!value.isNull());
79 } else if (name == mediaAttr && inDocument() && document().isActive() && m_s heet) { 74 } else if (name == mediaAttr && inDocument() && document().isActive() && m_s heet) {
80 m_sheet->setMediaQueries(MediaQuerySet::create(value)); 75 m_sheet->setMediaQueries(MediaQuerySet::create(value));
81 document().modifiedStyleSheet(m_sheet.get()); 76 document().modifiedStyleSheet(m_sheet.get());
82 } else { 77 } else {
83 HTMLElement::parseAttribute(name, value); 78 HTMLElement::parseAttribute(name, value);
84 } 79 }
85 } 80 }
86 81
87 void HTMLStyleElement::scopedAttributeChanged(bool scoped)
88 {
89 ASSERT(ContextFeatures::styleScopedEnabled(&document()));
90
91 if (!inDocument())
92 return;
93
94 if (scoped) {
95 if (m_scopedStyleRegistrationState == RegisteredAsScoped)
96 return;
97
98 // As any <style> in a shadow tree is treated as "scoped",
99 // need to remove the <style> from its shadow root.
100 ContainerNode* scopingNode = 0;
101 if (m_scopedStyleRegistrationState == RegisteredInShadowRoot) {
102 scopingNode = containingShadowRoot();
103 unregisterWithScopingNode(scopingNode);
104 }
105 document().styleEngine()->removeStyleSheetCandidateNode(this, scopingNod e, treeScope());
106 registerWithScopingNode(true);
107
108 document().styleEngine()->addStyleSheetCandidateNode(this, false);
109 document().modifiedStyleSheet(sheet());
110 return;
111 }
112
113 // If the <style> was scoped, need to remove the <style> from the scoping
114 // element, i.e. the parent node.
115 if (m_scopedStyleRegistrationState != RegisteredAsScoped)
116 return;
117
118 unregisterWithScopingNode(parentNode());
119 document().styleEngine()->removeStyleSheetCandidateNode(this, parentNode(), treeScope());
120
121 // As any <style> in a shadow tree is treated as "scoped",
122 // need to add the <style> to its shadow root.
123 if (isInShadowTree())
124 registerWithScopingNode(false);
125
126 document().styleEngine()->addStyleSheetCandidateNode(this, false);
127 // FIXME: currently need to use FullStyleUpdate here.
128 // Because ShadowTreeStyleSheetCollection doesn't know old scoping node.
129 // So setNeedsStyleRecalc for old scoping node is not invoked.
130 document().modifiedStyleSheet(sheet());
131 }
132
133 void HTMLStyleElement::finishParsingChildren() 82 void HTMLStyleElement::finishParsingChildren()
134 { 83 {
135 StyleElement::finishParsingChildren(this); 84 StyleElement::finishParsingChildren(this);
136 HTMLElement::finishParsingChildren(); 85 HTMLElement::finishParsingChildren();
137 } 86 }
138 87
139 void HTMLStyleElement::registerWithScopingNode(bool scoped)
140 {
141 // Note: We cannot rely on the 'scoped' element already being present when t his method is invoked.
142 // Therefore we cannot rely on scoped()!
143 ASSERT(m_scopedStyleRegistrationState == NotRegistered);
144 ASSERT(inDocument());
145 if (m_scopedStyleRegistrationState != NotRegistered)
146 return;
147
148 ContainerNode* scope = scoped ? parentNode() : containingShadowRoot();
149 if (!scope)
150 return;
151 if (!scope->isElementNode() && !scope->isShadowRoot()) {
152 // DocumentFragment nodes should never be inDocument,
153 // <style> should not be a child of Document, PI or some such.
154 ASSERT_NOT_REACHED();
155 return;
156 }
157 scope->registerScopedHTMLStyleChild();
158 m_scopedStyleRegistrationState = scoped ? RegisteredAsScoped : RegisteredInS hadowRoot;
159 }
160
161 void HTMLStyleElement::unregisterWithScopingNode(ContainerNode* scope)
162 {
163 ASSERT(m_scopedStyleRegistrationState != NotRegistered || !ContextFeatures:: styleScopedEnabled(&document()));
164 if (!isRegisteredAsScoped())
165 return;
166
167 ASSERT(scope);
168 if (scope) {
169 ASSERT(scope->hasScopedHTMLStyleChild());
170 scope->unregisterScopedHTMLStyleChild();
171 }
172
173 m_scopedStyleRegistrationState = NotRegistered;
174 }
175
176 Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(ContainerNode* insertionPoint) 88 Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(ContainerNode* insertionPoint)
177 { 89 {
178 HTMLElement::insertedInto(insertionPoint); 90 HTMLElement::insertedInto(insertionPoint);
179 if (insertionPoint->inDocument()) { 91 if (insertionPoint->inDocument() && isInShadowTree()) {
180 if (m_scopedStyleRegistrationState == NotRegistered && (scoped() || isIn ShadowTree())) 92 if (ShadowRoot* scope = containingShadowRoot())
181 registerWithScopingNode(scoped()); 93 scope->registerScopedHTMLStyleChild();
182 } 94 }
183 return InsertionShouldCallDidNotifySubtreeInsertions; 95 return InsertionShouldCallDidNotifySubtreeInsertions;
184 } 96 }
185 97
186 void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint) 98 void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint)
187 { 99 {
188 HTMLElement::removedFrom(insertionPoint); 100 HTMLElement::removedFrom(insertionPoint);
189 101
190 // In the current implementation, <style scoped> is only registered if the n ode is in the document. 102 if (!insertionPoint->inDocument())
191 // That is, because willRemove() is also called if an ancestor is removed fr om the document. 103 return;
192 // Now, if we want to register <style scoped> even if it's not inDocument,
193 // we'd need to find a way to discern whether that is the case, or whether < style scoped> itself is about to be removed.
194 ContainerNode* scopingNode = 0;
195 if (m_scopedStyleRegistrationState != NotRegistered) {
196 if (m_scopedStyleRegistrationState == RegisteredInShadowRoot) {
197 scopingNode = containingShadowRoot();
198 if (!scopingNode)
199 scopingNode = insertionPoint->containingShadowRoot();
200 } else {
201 scopingNode = parentNode() ? parentNode() : insertionPoint;
202 }
203 104
204 unregisterWithScopingNode(scopingNode); 105 ShadowRoot* scopingNode = containingShadowRoot();
205 } 106 if (!scopingNode)
107 scopingNode = insertionPoint->containingShadowRoot();
206 108
207 if (insertionPoint->inDocument()) { 109 if (scopingNode)
208 TreeScope* containingScope = containingShadowRoot(); 110 scopingNode->unregisterScopedHTMLStyleChild();
209 StyleElement::removedFromDocument(document(), this, scopingNode, contain ingScope ? *containingScope : insertionPoint->treeScope()); 111
210 } 112 TreeScope* containingScope = containingShadowRoot();
113 StyleElement::removedFromDocument(document(), this, scopingNode, containingS cope ? *containingScope : insertionPoint->treeScope());
211 } 114 }
212 115
213 void HTMLStyleElement::didNotifySubtreeInsertionsToDocument() 116 void HTMLStyleElement::didNotifySubtreeInsertionsToDocument()
214 { 117 {
215 StyleElement::processStyleSheet(document(), this); 118 StyleElement::processStyleSheet(document(), this);
216 } 119 }
217 120
218 void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) 121 void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
219 { 122 {
220 HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, chi ldCountDelta); 123 HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, chi ldCountDelta);
221 StyleElement::childrenChanged(this); 124 StyleElement::childrenChanged(this);
222 } 125 }
223 126
224 const AtomicString& HTMLStyleElement::media() const 127 const AtomicString& HTMLStyleElement::media() const
225 { 128 {
226 return getAttribute(mediaAttr); 129 return getAttribute(mediaAttr);
227 } 130 }
228 131
229 const AtomicString& HTMLStyleElement::type() const 132 const AtomicString& HTMLStyleElement::type() const
230 { 133 {
231 return getAttribute(typeAttr); 134 return getAttribute(typeAttr);
232 } 135 }
233 136
234 bool HTMLStyleElement::scoped() const
235 {
236 return fastHasAttribute(scopedAttr) && ContextFeatures::styleScopedEnabled(& document());
237 }
238
239 void HTMLStyleElement::setScoped(bool scopedValue)
240 {
241 setBooleanAttribute(scopedAttr, scopedValue);
242 }
243
244 ContainerNode* HTMLStyleElement::scopingNode() 137 ContainerNode* HTMLStyleElement::scopingNode()
245 { 138 {
246 if (!inDocument()) 139 if (!inDocument())
247 return 0; 140 return 0;
248 141
249 if (!isRegisteredAsScoped()) 142 if (isInShadowTree())
250 return &document();
251
252 if (isRegisteredInShadowRoot())
253 return containingShadowRoot(); 143 return containingShadowRoot();
254 144
255 return parentNode(); 145 return &document();
256 } 146 }
257 147
258 void HTMLStyleElement::dispatchPendingLoadEvents() 148 void HTMLStyleElement::dispatchPendingLoadEvents()
259 { 149 {
260 styleLoadEventSender().dispatchPendingEvents(); 150 styleLoadEventSender().dispatchPendingEvents();
261 } 151 }
262 152
263 void HTMLStyleElement::dispatchPendingEvent(StyleEventSender* eventSender) 153 void HTMLStyleElement::dispatchPendingEvent(StyleEventSender* eventSender)
264 { 154 {
265 ASSERT_UNUSED(eventSender, eventSender == &styleLoadEventSender()); 155 ASSERT_UNUSED(eventSender, eventSender == &styleLoadEventSender());
(...skipping 23 matching lines...) Expand all
289 styleSheet->setDisabled(setDisabled); 179 styleSheet->setDisabled(setDisabled);
290 } 180 }
291 181
292 void HTMLStyleElement::trace(Visitor* visitor) 182 void HTMLStyleElement::trace(Visitor* visitor)
293 { 183 {
294 StyleElement::trace(visitor); 184 StyleElement::trace(visitor);
295 HTMLElement::trace(visitor); 185 HTMLElement::trace(visitor);
296 } 186 }
297 187
298 } 188 }
OLDNEW
« no previous file with comments | « Source/core/html/HTMLStyleElement.h ('k') | Source/core/html/HTMLStyleElement.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698