Index: Source/core/dom/DocumentLifecycle.cpp |
diff --git a/Source/core/dom/DocumentLifecycle.cpp b/Source/core/dom/DocumentLifecycle.cpp |
index d53e0bc9bede645eb3c4b02477a488f283a14232..aa675c1f69708e8cbf7a3b31e3d96e91375eeeb8 100644 |
--- a/Source/core/dom/DocumentLifecycle.cpp |
+++ b/Source/core/dom/DocumentLifecycle.cpp |
@@ -36,6 +36,32 @@ |
namespace WebCore { |
+static DocumentLifecycle::DeprecatedTransition* s_deprecatedTransitionStack = 0; |
+ |
+DocumentLifecycle::Scope::Scope(DocumentLifecycle& lifecycle, State finalState) |
+ : m_lifecycle(lifecycle) |
+ , m_finalState(finalState) |
+{ |
+} |
+ |
+DocumentLifecycle::Scope::~Scope() |
+{ |
+ m_lifecycle.advanceTo(m_finalState); |
+} |
+ |
+DocumentLifecycle::DeprecatedTransition::DeprecatedTransition(State from, State to) |
+ : m_previous(s_deprecatedTransitionStack) |
+ , m_from(from) |
+ , m_to(to) |
+{ |
+ s_deprecatedTransitionStack = this; |
+} |
+ |
+DocumentLifecycle::DeprecatedTransition::~DeprecatedTransition() |
+{ |
+ s_deprecatedTransitionStack = m_previous; |
+} |
+ |
DocumentLifecycle::DocumentLifecycle() |
: m_state(Uninitialized) |
{ |
@@ -45,22 +71,49 @@ DocumentLifecycle::~DocumentLifecycle() |
{ |
} |
+#if !ASSERT_DISABLED |
+ |
+static bool isClean(DocumentLifecycle::State state) |
+{ |
+ return state == DocumentLifecycle::StyleClean || state == DocumentLifecycle::LayoutClean; |
+} |
+ |
bool DocumentLifecycle::canAdvanceTo(State state) const |
{ |
+ // This transition is bogus, but we've whitelisted it anyway. |
+ if (s_deprecatedTransitionStack && m_state == s_deprecatedTransitionStack->from() && state == s_deprecatedTransitionStack->to()) |
+ return true; |
+ |
if (state > m_state) |
return true; |
// FIXME: We can dispose a document multiple times. This seems wrong. |
// See https://code.google.com/p/chromium/issues/detail?id=301668. |
- if (m_state == Disposed) |
+ if (m_state == Disposed) { |
return state == Disposed; |
- if (m_state == Clean) { |
- // We can synchronously enter recalc style without rewinding to |
- // StyleRecalcPending. |
- return state == InStyleRecalc; |
+ } else if (isClean(m_state)) { |
+ if (state == StyleRecalcPending) |
+ return true; |
+ // We can synchronously recalc style. |
+ if (state == InStyleRecalc) |
ojan
2014/02/06 05:11:39
Do we really go from LayoutClean to InStyleRecalc
abarth-chromium
2014/02/06 05:31:15
I'm not sure. We can split out those two states t
ojan
2014/02/06 20:36:10
Yeah, that was what I had in mind. It's was a bit
|
+ return true; |
+ // We can synchronously perform layout. |
+ if (state == InPreLayout) |
+ return true; |
+ if (state == InPerformLayout) |
+ return true; |
+ if (isClean(state)) |
+ return true; |
+ return false; |
+ } else if (m_state == InPreLayout) { |
+ return state == InStyleRecalc || state == StyleClean; |
+ } else if (m_state == AfterPerformLayout) { |
+ return state == InPreLayout; |
ojan
2014/02/06 05:11:39
This is for partialLayout?
abarth-chromium
2014/02/06 05:31:15
This case comes up for scroll bars. After layout,
|
} |
return false; |
} |
+#endif |
+ |
void DocumentLifecycle::advanceTo(State state) |
{ |
ASSERT(canAdvanceTo(state)); |
@@ -69,10 +122,7 @@ void DocumentLifecycle::advanceTo(State state) |
void DocumentLifecycle::rewindTo(State state) |
{ |
- ASSERT(m_state == Clean); |
- ASSERT(state < m_state); |
- m_state = state; |
- ASSERT(isActive()); |
+ advanceTo(state); |
} |
} |