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

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

Issue 310443002: Remove scoped styles. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix layout test 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
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) 52 , m_scoped(false)
53 { 53 {
54 ScriptWrappable::init(this); 54 ScriptWrappable::init(this);
55 } 55 }
56 56
57 HTMLStyleElement::~HTMLStyleElement() 57 HTMLStyleElement::~HTMLStyleElement()
58 { 58 {
59 // During tear-down, willRemove isn't called, so m_scopedStyleRegistrationSt ate may still be RegisteredAsScoped or RegisteredInShadowRoot here. 59 // During tear-down, willRemove isn't called, so m_scoped may still be true here.
60 // Therefore we can't ASSERT(m_scopedStyleRegistrationState == NotRegistered ). 60 // Therefore we can't ASSERT(!m_scoped).
61 #if !ENABLE(OILPAN) 61 #if !ENABLE(OILPAN)
62 StyleElement::clearDocumentData(document(), this); 62 StyleElement::clearDocumentData(document(), this);
63 #endif 63 #endif
64 64
65 styleLoadEventSender().cancelEvent(this); 65 styleLoadEventSender().cancelEvent(this);
66 } 66 }
67 67
68 PassRefPtrWillBeRawPtr<HTMLStyleElement> HTMLStyleElement::create(Document& docu ment, bool createdByParser) 68 PassRefPtrWillBeRawPtr<HTMLStyleElement> HTMLStyleElement::create(Document& docu ment, bool createdByParser)
69 { 69 {
70 return adoptRefWillBeRefCountedGarbageCollected(new HTMLStyleElement(documen t, createdByParser)); 70 return adoptRefWillBeRefCountedGarbageCollected(new HTMLStyleElement(documen t, createdByParser));
71 } 71 }
72 72
73 void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value) 73 void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicStr ing& value)
74 { 74 {
75 if (name == titleAttr && m_sheet) { 75 if (name == titleAttr && m_sheet) {
76 m_sheet->setTitle(value); 76 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) { 77 } else if (name == mediaAttr && inDocument() && document().isActive() && m_s heet) {
80 m_sheet->setMediaQueries(MediaQuerySet::create(value)); 78 m_sheet->setMediaQueries(MediaQuerySet::create(value));
81 document().modifiedStyleSheet(m_sheet.get()); 79 document().modifiedStyleSheet(m_sheet.get());
82 } else { 80 } else {
83 HTMLElement::parseAttribute(name, value); 81 HTMLElement::parseAttribute(name, value);
84 } 82 }
85 } 83 }
86 84
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() 85 void HTMLStyleElement::finishParsingChildren()
134 { 86 {
135 StyleElement::finishParsingChildren(this); 87 StyleElement::finishParsingChildren(this);
136 HTMLElement::finishParsingChildren(); 88 HTMLElement::finishParsingChildren();
137 } 89 }
138 90
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) 91 Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(ContainerNode* insertionPoint)
177 { 92 {
178 HTMLElement::insertedInto(insertionPoint); 93 HTMLElement::insertedInto(insertionPoint);
179 if (insertionPoint->inDocument()) { 94 if (insertionPoint->inDocument() && isInShadowTree() && !m_scoped) {
180 if (m_scopedStyleRegistrationState == NotRegistered && (scoped() || isIn ShadowTree())) 95 if (ShadowRoot* scope = containingShadowRoot()) {
181 registerWithScopingNode(scoped()); 96 scope->registerScopedHTMLStyleChild();
97 m_scoped = true;
98 }
182 } 99 }
183 return InsertionShouldCallDidNotifySubtreeInsertions; 100 return InsertionShouldCallDidNotifySubtreeInsertions;
184 } 101 }
185 102
186 void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint) 103 void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint)
187 { 104 {
188 HTMLElement::removedFrom(insertionPoint); 105 HTMLElement::removedFrom(insertionPoint);
189 106
190 // In the current implementation, <style scoped> is only registered if the n ode is in the document. 107 ShadowRoot* scopingNode = containingShadowRoot();
191 // That is, because willRemove() is also called if an ancestor is removed fr om the document. 108 if (!scopingNode)
192 // Now, if we want to register <style scoped> even if it's not inDocument, 109 scopingNode = insertionPoint->containingShadowRoot();
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 110
204 unregisterWithScopingNode(scopingNode); 111 if (scopingNode && m_scoped) {
112 scopingNode->unregisterScopedHTMLStyleChild();
113 m_scoped = false;
205 } 114 }
206 115
207 if (insertionPoint->inDocument()) { 116 if (!insertionPoint->inDocument())
208 TreeScope* containingScope = containingShadowRoot(); 117 return;
209 StyleElement::removedFromDocument(document(), this, scopingNode, contain ingScope ? *containingScope : insertionPoint->treeScope()); 118
210 } 119 TreeScope* containingScope = containingShadowRoot();
120 StyleElement::removedFromDocument(document(), this, scopingNode, containingS cope ? *containingScope : insertionPoint->treeScope());
211 } 121 }
212 122
213 void HTMLStyleElement::didNotifySubtreeInsertionsToDocument() 123 void HTMLStyleElement::didNotifySubtreeInsertionsToDocument()
214 { 124 {
215 StyleElement::processStyleSheet(document(), this); 125 StyleElement::processStyleSheet(document(), this);
216 } 126 }
217 127
218 void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) 128 void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
219 { 129 {
220 HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, chi ldCountDelta); 130 HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, chi ldCountDelta);
221 StyleElement::childrenChanged(this); 131 StyleElement::childrenChanged(this);
222 } 132 }
223 133
224 const AtomicString& HTMLStyleElement::media() const 134 const AtomicString& HTMLStyleElement::media() const
225 { 135 {
226 return getAttribute(mediaAttr); 136 return getAttribute(mediaAttr);
227 } 137 }
228 138
229 const AtomicString& HTMLStyleElement::type() const 139 const AtomicString& HTMLStyleElement::type() const
230 { 140 {
231 return getAttribute(typeAttr); 141 return getAttribute(typeAttr);
232 } 142 }
233 143
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() 144 ContainerNode* HTMLStyleElement::scopingNode()
245 { 145 {
246 if (!inDocument()) 146 if (!inDocument())
247 return 0; 147 return 0;
248 148
249 if (!isRegisteredAsScoped()) 149 if (isScoped())
250 return &document();
251
252 if (isRegisteredInShadowRoot())
253 return containingShadowRoot(); 150 return containingShadowRoot();
254 151
255 return parentNode(); 152 return &document();
256 } 153 }
257 154
258 void HTMLStyleElement::dispatchPendingLoadEvents() 155 void HTMLStyleElement::dispatchPendingLoadEvents()
259 { 156 {
260 styleLoadEventSender().dispatchPendingEvents(); 157 styleLoadEventSender().dispatchPendingEvents();
261 } 158 }
262 159
263 void HTMLStyleElement::dispatchPendingEvent(StyleEventSender* eventSender) 160 void HTMLStyleElement::dispatchPendingEvent(StyleEventSender* eventSender)
264 { 161 {
265 ASSERT_UNUSED(eventSender, eventSender == &styleLoadEventSender()); 162 ASSERT_UNUSED(eventSender, eventSender == &styleLoadEventSender());
(...skipping 23 matching lines...) Expand all
289 styleSheet->setDisabled(setDisabled); 186 styleSheet->setDisabled(setDisabled);
290 } 187 }
291 188
292 void HTMLStyleElement::trace(Visitor* visitor) 189 void HTMLStyleElement::trace(Visitor* visitor)
293 { 190 {
294 StyleElement::trace(visitor); 191 StyleElement::trace(visitor);
295 HTMLElement::trace(visitor); 192 HTMLElement::trace(visitor);
296 } 193 }
297 194
298 } 195 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698