#include "StyleSheetList.h"
#include "UserContentURLPattern.h"
#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
DocumentStyleSheetCollection::DocumentStyleSheetCollection(Document* document)
: m_document(document)
- , m_authorStyleSheets(StyleSheetList::create(document))
, m_pendingStylesheets(0)
, m_pageGroupUserSheetCacheValid(false)
, m_hadActiveLoadingStylesheet(false)
DocumentStyleSheetCollection::~DocumentStyleSheetCollection()
{
- m_authorStyleSheets->documentDestroyed();
-
if (m_pageUserSheet)
m_pageUserSheet->clearOwnerNode();
if (m_pageGroupUserSheets) {
return false;
}
-void DocumentStyleSheetCollection::analyzeStyleSheetChange(UpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, bool& requiresStyleResolverReset, bool& requiresFullStyleRecalc)
+void DocumentStyleSheetCollection::analyzeStyleSheetChange(UpdateFlag updateFlag, const Vector<RefPtr<StyleSheet> >& newStylesheets, StyleResolverUpdateType& styleResolverUpdateType, bool& requiresFullStyleRecalc)
{
- requiresStyleResolverReset = true;
+ styleResolverUpdateType = Reconstruct;
requiresFullStyleRecalc = true;
// Stylesheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
if (!m_document->styleResolverIfExists())
return;
- // See if we are just adding stylesheets.
- unsigned oldStylesheetCount = m_authorStyleSheets->length();
+ // Find out which stylesheets are new.
+ unsigned oldStylesheetCount = m_authorStyleSheets.size();
if (newStylesheetCount < oldStylesheetCount)
return;
- for (unsigned i = 0; i < oldStylesheetCount; ++i) {
- if (m_authorStyleSheets->item(i) != newStylesheets[i])
+ Vector<StyleSheet*> addedSheets;
+ unsigned newIndex = 0;
+ for (unsigned oldIndex = 0; oldIndex < oldStylesheetCount; ++oldIndex) {
+ if (newIndex >= newStylesheetCount)
return;
+ while (m_authorStyleSheets[oldIndex] != newStylesheets[newIndex]) {
+ addedSheets.append(newStylesheets[newIndex].get());
+ ++newIndex;
+ if (newIndex == newStylesheetCount)
+ return;
+ }
+ ++newIndex;
}
- requiresStyleResolverReset = false;
+ bool hasInsertions = !addedSheets.isEmpty();
+ while (newIndex < newStylesheetCount) {
+ addedSheets.append(newStylesheets[newIndex].get());
+ ++newIndex;
+ }
+ // If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
+ // If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
+ styleResolverUpdateType = hasInsertions ? Reset : Additive;
// If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
if (!m_document->body() || m_document->hasNodesWithPlaceholderStyle())
return;
- for (unsigned i = oldStylesheetCount; i < newStylesheetCount; ++i) {
- if (!newStylesheets[i]->isCSSStyleSheet())
+ for (unsigned i = 0; i < addedSheets.size(); ++i) {
+ if (!addedSheets[i]->isCSSStyleSheet())
return;
- if (newStylesheets[i]->disabled())
+ if (addedSheets[i]->disabled())
continue;
- if (testAddedStyleSheetRequiresStyleRecalc(static_cast<CSSStyleSheet*>(newStylesheets[i].get())->contents()))
+ if (testAddedStyleSheetRequiresStyleRecalc(static_cast<CSSStyleSheet*>(addedSheets[i])->contents()))
return;
}
requiresFullStyleRecalc = false;
if (!m_document->renderer() || !m_document->attached())
return false;
- StyleSheetVector newStylesheets;
+ Vector<RefPtr<StyleSheet> > newStylesheets;
collectActiveStyleSheets(newStylesheets);
- bool requiresStyleResolverReset;
+ StyleResolverUpdateType styleResolverUpdateType;
bool requiresFullStyleRecalc;
- analyzeStyleSheetChange(updateFlag, newStylesheets, requiresStyleResolverReset, requiresFullStyleRecalc);
+ analyzeStyleSheetChange(updateFlag, newStylesheets, styleResolverUpdateType, requiresFullStyleRecalc);
- if (requiresStyleResolverReset)
+ if (styleResolverUpdateType == Reconstruct)
m_document->clearStyleResolver();
else {
- m_document->styleResolver()->appendAuthorStylesheets(m_authorStyleSheets->length(), newStylesheets);
+ StyleResolver* styleResolver = m_document->styleResolver();
+ if (styleResolverUpdateType == Reset) {
+ styleResolver->resetAuthorStyle();
+ styleResolver->appendAuthorStylesheets(0, newStylesheets);
+ } else {
+ ASSERT(styleResolverUpdateType == Additive);
+ styleResolver->appendAuthorStylesheets(m_authorStyleSheets.size(), newStylesheets);
+ }
resetCSSFeatureFlags();
}
- m_authorStyleSheets->swap(newStylesheets);
+ m_authorStyleSheets.swap(newStylesheets);
- m_usesRemUnits = styleSheetsUseRemUnits(m_authorStyleSheets->vector());
+ m_usesRemUnits = styleSheetsUseRemUnits(m_authorStyleSheets);
m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
m_document->notifySeamlessChildDocumentsOfStylesheetUpdate();
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
info.addMember(m_pageUserSheet);
- if (m_pageGroupUserSheets)
- info.addInstrumentedVectorPtr(m_pageGroupUserSheets);
- if (m_userSheets)
- info.addInstrumentedVectorPtr(m_userSheets);
+ info.addMember(m_pageGroupUserSheets);
+ info.addMember(m_userSheets);
+ info.addMember(m_authorStyleSheets);
info.addListHashSet(m_styleSheetCandidateNodes);
info.addMember(m_preferredStylesheetSetName);
info.addMember(m_selectedStylesheetSetName);