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

Side by Side Diff: Source/core/dom/StyleSheetCollections.cpp

Issue 23516012: Rename StyleSheetCollections to StyleEngine. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 3 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/dom/StyleSheetCollections.h ('k') | Source/core/dom/shadow/ShadowRoot.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r ights reserved.
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public License
23 * along with this library; see the file COPYING.LIB. If not, write to
24 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 * Boston, MA 02110-1301, USA.
26 */
27
28 #include "config.h"
29 #include "core/dom/StyleSheetCollections.h"
30
31 #include "HTMLNames.h"
32 #include "SVGNames.h"
33 #include "core/css/CSSStyleSheet.h"
34 #include "core/css/StyleInvalidationAnalysis.h"
35 #include "core/css/StyleSheetContents.h"
36 #include "core/css/resolver/StyleResolver.h"
37 #include "core/dom/Document.h"
38 #include "core/dom/Element.h"
39 #include "core/dom/ProcessingInstruction.h"
40 #include "core/dom/ShadowTreeStyleSheetCollection.h"
41 #include "core/dom/shadow/ShadowRoot.h"
42 #include "core/html/HTMLIFrameElement.h"
43 #include "core/html/HTMLLinkElement.h"
44 #include "core/html/HTMLStyleElement.h"
45 #include "core/page/Page.h"
46 #include "core/page/PageGroup.h"
47 #include "core/page/Settings.h"
48 #include "core/page/UserContentURLPattern.h"
49 #include "core/svg/SVGStyleElement.h"
50
51 namespace WebCore {
52
53 using namespace HTMLNames;
54
55 StyleSheetCollections::StyleSheetCollections(Document& document)
56 : m_document(document)
57 , m_pendingStylesheets(0)
58 , m_injectedStyleSheetCacheValid(false)
59 , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
60 , m_usesSiblingRules(false)
61 , m_usesSiblingRulesOverride(false)
62 , m_usesFirstLineRules(false)
63 , m_usesFirstLetterRules(false)
64 , m_usesRemUnits(false)
65 , m_documentStyleSheetCollection(document)
66 , m_needsDocumentStyleSheetsUpdate(true)
67 {
68 }
69
70 StyleSheetCollections::~StyleSheetCollections()
71 {
72 if (m_pageUserSheet)
73 m_pageUserSheet->clearOwnerNode();
74 for (unsigned i = 0; i < m_injectedUserStyleSheets.size(); ++i)
75 m_injectedUserStyleSheets[i]->clearOwnerNode();
76 for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i)
77 m_injectedAuthorStyleSheets[i]->clearOwnerNode();
78 for (unsigned i = 0; i < m_userStyleSheets.size(); ++i)
79 m_userStyleSheets[i]->clearOwnerNode();
80 for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
81 m_authorStyleSheets[i]->clearOwnerNode();
82 }
83
84 void StyleSheetCollections::insertTreeScopeInDocumentOrder(TreeScopeSet& treeSco pes, TreeScope* treeScope)
85 {
86 if (treeScopes.isEmpty()) {
87 treeScopes.add(treeScope);
88 return;
89 }
90 if (treeScopes.contains(treeScope))
91 return;
92
93 TreeScopeSet::iterator begin = treeScopes.begin();
94 TreeScopeSet::iterator end = treeScopes.end();
95 TreeScopeSet::iterator it = end;
96 TreeScope* followingTreeScope = 0;
97 do {
98 --it;
99 TreeScope* n = *it;
100 unsigned short position = n->comparePosition(*treeScope);
101 if (position & Node::DOCUMENT_POSITION_FOLLOWING) {
102 treeScopes.insertBefore(followingTreeScope, treeScope);
103 return;
104 }
105 followingTreeScope = n;
106 } while (it != begin);
107
108 treeScopes.insertBefore(followingTreeScope, treeScope);
109 }
110
111 StyleSheetCollection* StyleSheetCollections::ensureStyleSheetCollectionFor(TreeS cope& treeScope)
112 {
113 if (&treeScope == &m_document)
114 return &m_documentStyleSheetCollection;
115
116 HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::AddResult result = m_sty leSheetCollectionMap.add(&treeScope, nullptr);
117 if (result.isNewEntry)
118 result.iterator->value = adoptPtr(new ShadowTreeStyleSheetCollection(toS hadowRoot(treeScope)));
119 return result.iterator->value.get();
120 }
121
122 StyleSheetCollection* StyleSheetCollections::styleSheetCollectionFor(TreeScope& treeScope)
123 {
124 if (&treeScope == &m_document)
125 return &m_documentStyleSheetCollection;
126
127 HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleShe etCollectionMap.find(&treeScope);
128 if (it == m_styleSheetCollectionMap.end())
129 return 0;
130 return it->value.get();
131 }
132
133 const Vector<RefPtr<StyleSheet> >& StyleSheetCollections::styleSheetsForStyleShe etList()
134 {
135 return m_documentStyleSheetCollection.styleSheetsForStyleSheetList();
136 }
137
138 const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::activeAuthorStyleSh eets() const
139 {
140 return m_documentStyleSheetCollection.activeAuthorStyleSheets();
141 }
142
143 void StyleSheetCollections::getActiveAuthorStyleSheets(Vector<const Vector<RefPt r<CSSStyleSheet> >*>& activeAuthorStyleSheets) const
144 {
145 activeAuthorStyleSheets.append(&m_documentStyleSheetCollection.activeAuthorS tyleSheets());
146
147 HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values b egin = m_styleSheetCollectionMap.values().begin();
148 HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values e nd = m_styleSheetCollectionMap.values().end();
149 HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values i t = begin;
150 for (; it != end; ++it) {
151 const StyleSheetCollection* collection = it->get();
152 activeAuthorStyleSheets.append(&collection->activeAuthorStyleSheets());
153 }
154 }
155
156 void StyleSheetCollections::combineCSSFeatureFlags(const RuleFeatureSet& feature s)
157 {
158 // Delay resetting the flags until after next style recalc since unapplying the style may not work without these set (this is true at least with before/afte r).
159 m_usesSiblingRules = m_usesSiblingRules || features.usesSiblingRules();
160 m_usesFirstLineRules = m_usesFirstLineRules || features.usesFirstLineRules() ;
161 }
162
163 void StyleSheetCollections::resetCSSFeatureFlags(const RuleFeatureSet& features)
164 {
165 m_usesSiblingRules = features.usesSiblingRules();
166 m_usesFirstLineRules = features.usesFirstLineRules();
167 }
168
169 CSSStyleSheet* StyleSheetCollections::pageUserSheet()
170 {
171 if (m_pageUserSheet)
172 return m_pageUserSheet.get();
173
174 Page* owningPage = m_document.page();
175 if (!owningPage)
176 return 0;
177
178 String userSheetText = owningPage->userStyleSheet();
179 if (userSheetText.isEmpty())
180 return 0;
181
182 // Parse the sheet and cache it.
183 m_pageUserSheet = CSSStyleSheet::createInline(&m_document, m_document.settin gs()->userStyleSheetLocation());
184 m_pageUserSheet->contents()->setIsUserStyleSheet(true);
185 m_pageUserSheet->contents()->parseString(userSheetText);
186 return m_pageUserSheet.get();
187 }
188
189 void StyleSheetCollections::clearPageUserSheet()
190 {
191 if (m_pageUserSheet) {
192 RefPtr<StyleSheet> removedSheet = m_pageUserSheet;
193 m_pageUserSheet = 0;
194 m_document.removedStyleSheet(removedSheet.get());
195 }
196 }
197
198 void StyleSheetCollections::updatePageUserSheet()
199 {
200 clearPageUserSheet();
201 // FIXME: Why is this immediately and not defer?
202 if (StyleSheet* addedSheet = pageUserSheet())
203 m_document.addedStyleSheet(addedSheet, RecalcStyleImmediately);
204 }
205
206 const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::injectedUserStyleSh eets() const
207 {
208 updateInjectedStyleSheetCache();
209 return m_injectedUserStyleSheets;
210 }
211
212 const Vector<RefPtr<CSSStyleSheet> >& StyleSheetCollections::injectedAuthorStyle Sheets() const
213 {
214 updateInjectedStyleSheetCache();
215 return m_injectedAuthorStyleSheets;
216 }
217
218 void StyleSheetCollections::updateInjectedStyleSheetCache() const
219 {
220 if (m_injectedStyleSheetCacheValid)
221 return;
222 m_injectedStyleSheetCacheValid = true;
223 m_injectedUserStyleSheets.clear();
224 m_injectedAuthorStyleSheets.clear();
225
226 Page* owningPage = m_document.page();
227 if (!owningPage)
228 return;
229
230 const PageGroup& pageGroup = owningPage->group();
231 const UserStyleSheetVector& sheets = pageGroup.userStyleSheets();
232 for (unsigned i = 0; i < sheets.size(); ++i) {
233 const UserStyleSheet* sheet = sheets[i].get();
234 if (sheet->injectedFrames() == InjectInTopFrameOnly && m_document.ownerE lement())
235 continue;
236 if (!UserContentURLPattern::matchesPatterns(m_document.url(), sheet->whi telist(), sheet->blacklist()))
237 continue;
238 RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cas t<Document*>(&m_document), sheet->url());
239 bool isUserStyleSheet = sheet->level() == UserStyleUserLevel;
240 if (isUserStyleSheet)
241 m_injectedUserStyleSheets.append(groupSheet);
242 else
243 m_injectedAuthorStyleSheets.append(groupSheet);
244 groupSheet->contents()->setIsUserStyleSheet(isUserStyleSheet);
245 groupSheet->contents()->parseString(sheet->source());
246 }
247 }
248
249 void StyleSheetCollections::invalidateInjectedStyleSheetCache()
250 {
251 m_injectedStyleSheetCacheValid = false;
252 m_needsDocumentStyleSheetsUpdate = true;
253 // FIXME: updateInjectedStyleSheetCache is called inside StyleSheetCollectio n::updateActiveStyleSheets
254 // and batch updates lots of sheets so we can't call addedStyleSheet() or re movedStyleSheet().
255 m_document.styleResolverChanged(RecalcStyleDeferred);
256 }
257
258 void StyleSheetCollections::addAuthorSheet(PassRefPtr<StyleSheetContents> author Sheet)
259 {
260 ASSERT(!authorSheet->isUserStyleSheet());
261 m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, &m_document));
262 m_document.addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImme diately);
263 m_needsDocumentStyleSheetsUpdate = true;
264 }
265
266 void StyleSheetCollections::addUserSheet(PassRefPtr<StyleSheetContents> userShee t)
267 {
268 ASSERT(userSheet->isUserStyleSheet());
269 m_userStyleSheets.append(CSSStyleSheet::create(userSheet, &m_document));
270 m_document.addedStyleSheet(m_userStyleSheets.last().get(), RecalcStyleImmedi ately);
271 m_needsDocumentStyleSheetsUpdate = true;
272 }
273
274 // This method is called whenever a top-level stylesheet has finished loading.
275 void StyleSheetCollections::removePendingSheet(Node* styleSheetCandidateNode, Re movePendingSheetNotificationType notification)
276 {
277 // Make sure we knew this sheet was pending, and that our count isn't out of sync.
278 ASSERT(m_pendingStylesheets > 0);
279
280 m_pendingStylesheets--;
281
282 TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? &styleS heetCandidateNode->treeScope() : &m_document;
283 if (treeScope == &m_document)
284 m_needsDocumentStyleSheetsUpdate = true;
285 else
286 m_dirtyTreeScopes.add(treeScope);
287
288 if (m_pendingStylesheets)
289 return;
290
291 if (notification == RemovePendingSheetNotifyLater) {
292 m_document.setNeedsNotifyRemoveAllPendingStylesheet();
293 return;
294 }
295
296 // FIXME: We can't call addedStyleSheet or removedStyleSheet here because we don't know
297 // what's new. We should track that to tell the style system what changed.
298 m_document.didRemoveAllPendingStylesheet();
299 }
300
301 void StyleSheetCollections::addStyleSheetCandidateNode(Node* node, bool createdB yParser)
302 {
303 if (!node->inDocument())
304 return;
305
306 TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_docu ment;
307 ASSERT(isHTMLStyleElement(node) || &treeScope == &m_document);
308
309 StyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
310 ASSERT(collection);
311 collection->addStyleSheetCandidateNode(node, createdByParser);
312
313 if (&treeScope == &m_document) {
314 m_needsDocumentStyleSheetsUpdate = true;
315 return;
316 }
317
318 insertTreeScopeInDocumentOrder(m_activeTreeScopes, &treeScope);
319 m_dirtyTreeScopes.add(&treeScope);
320 }
321
322 void StyleSheetCollections::removeStyleSheetCandidateNode(Node* node, ContainerN ode* scopingNode)
323 {
324 TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : m_document;
325 ASSERT(isHTMLStyleElement(node) || &treeScope == &m_document);
326
327 StyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
328 ASSERT(collection);
329 collection->removeStyleSheetCandidateNode(node, scopingNode);
330
331 if (&treeScope == &m_document) {
332 m_needsDocumentStyleSheetsUpdate = true;
333 return;
334 }
335 m_dirtyTreeScopes.add(&treeScope);
336 m_activeTreeScopes.remove(&treeScope);
337 }
338
339 void StyleSheetCollections::modifiedStyleSheetCandidateNode(Node* node)
340 {
341 if (!node->inDocument())
342 return;
343
344 TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_docu ment;
345 ASSERT(isHTMLStyleElement(node) || &treeScope == &m_document);
346 if (&treeScope == &m_document) {
347 m_needsDocumentStyleSheetsUpdate = true;
348 return;
349 }
350 m_dirtyTreeScopes.add(&treeScope);
351 }
352
353 bool StyleSheetCollections::shouldUpdateShadowTreeStyleSheetCollection(StyleReso lverUpdateMode updateMode)
354 {
355 return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate;
356 }
357
358 bool StyleSheetCollections::updateActiveStyleSheets(StyleResolverUpdateMode upda teMode)
359 {
360 if (m_document.inStyleRecalc()) {
361 // SVG <use> element may manage to invalidate style selector in the midd le of a style recalc.
362 // https://bugs.webkit.org/show_bug.cgi?id=54344
363 // FIXME: This should be fixed in SVG and the call site replaced by ASSE RT(!m_inStyleRecalc).
364 m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
365 return false;
366
367 }
368 if (!m_document.renderer() || !m_document.attached())
369 return false;
370
371 bool requiresFullStyleRecalc = false;
372 if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate)
373 requiresFullStyleRecalc = m_documentStyleSheetCollection.updateActiveSty leSheets(this, updateMode);
374
375 if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) {
376 TreeScopeSet treeScopes = updateMode == FullStyleUpdate ? m_activeTreeSc opes : m_dirtyTreeScopes;
377 HashSet<TreeScope*> treeScopesRemoved;
378
379 for (TreeScopeSet::iterator it = treeScopes.begin(); it != treeScopes.en d(); ++it) {
380 TreeScope* treeScope = *it;
381 ASSERT(treeScope != &m_document);
382 ShadowTreeStyleSheetCollection* collection = static_cast<ShadowTreeS tyleSheetCollection*>(styleSheetCollectionFor(*treeScope));
383 ASSERT(collection);
384 collection->updateActiveStyleSheets(this, updateMode);
385 if (!collection->hasStyleSheetCandidateNodes())
386 treeScopesRemoved.add(treeScope);
387 }
388 if (!treeScopesRemoved.isEmpty())
389 for (HashSet<TreeScope*>::iterator it = treeScopesRemoved.begin(); i t != treeScopesRemoved.end(); ++it)
390 m_activeTreeScopes.remove(*it);
391 m_dirtyTreeScopes.clear();
392 }
393
394 if (StyleResolver* styleResolver = m_document.styleResolverIfExists()) {
395 styleResolver->finishAppendAuthorStyleSheets();
396 resetCSSFeatureFlags(styleResolver->ruleFeatureSet());
397 }
398
399 m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
400 activeStyleSheetsUpdatedForInspector();
401 m_usesRemUnits = m_documentStyleSheetCollection.usesRemUnits();
402
403 if (m_needsDocumentStyleSheetsUpdate || updateMode == FullStyleUpdate) {
404 m_document.notifySeamlessChildDocumentsOfStylesheetUpdate();
405 m_needsDocumentStyleSheetsUpdate = false;
406 }
407
408 return requiresFullStyleRecalc;
409 }
410
411 void StyleSheetCollections::activeStyleSheetsUpdatedForInspector()
412 {
413 if (m_activeTreeScopes.isEmpty()) {
414 InspectorInstrumentation::activeStyleSheetsUpdated(&m_document, m_docume ntStyleSheetCollection.styleSheetsForStyleSheetList());
415 return;
416 }
417 Vector<RefPtr<StyleSheet> > activeStyleSheets;
418
419 activeStyleSheets.append(m_documentStyleSheetCollection.styleSheetsForStyleS heetList());
420
421 TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
422 TreeScopeSet::iterator end = m_activeTreeScopes.end();
423 for (TreeScopeSet::iterator it = begin; it != end; ++it) {
424 if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it ))
425 activeStyleSheets.append(collection->styleSheetsForStyleSheetList()) ;
426 }
427
428 // FIXME: Inspector needs a vector which has all active stylesheets.
429 // However, creating such a large vector might cause performance regression.
430 // Need to implement some smarter solution.
431 InspectorInstrumentation::activeStyleSheetsUpdated(&m_document, activeStyleS heets);
432 }
433
434 void StyleSheetCollections::didRemoveShadowRoot(ShadowRoot* shadowRoot)
435 {
436 m_styleSheetCollectionMap.remove(shadowRoot);
437 }
438
439 void StyleSheetCollections::appendActiveAuthorStyleSheets(StyleResolver* styleRe solver)
440 {
441 ASSERT(styleResolver);
442
443 styleResolver->setBuildScopedStyleTreeInDocumentOrder(true);
444 styleResolver->appendAuthorStyleSheets(0, m_documentStyleSheetCollection.act iveAuthorStyleSheets());
445
446 TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
447 TreeScopeSet::iterator end = m_activeTreeScopes.end();
448 for (TreeScopeSet::iterator it = begin; it != end; ++it) {
449 if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it )) {
450 styleResolver->setBuildScopedStyleTreeInDocumentOrder(!collection->s copingNodesForStyleScoped());
451 styleResolver->appendAuthorStyleSheets(0, collection->activeAuthorSt yleSheets());
452 }
453 }
454 styleResolver->finishAppendAuthorStyleSheets();
455 styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
456 }
457
458 }
OLDNEW
« no previous file with comments | « Source/core/dom/StyleSheetCollections.h ('k') | Source/core/dom/shadow/ShadowRoot.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698