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

Unified Diff: Source/core/html/HTMLImport.cpp

Issue 141143006: [import] Cleanup: get rid of ad-hoc state machine. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Updated to ToT Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/html/HTMLImport.h ('k') | Source/core/html/HTMLImportChild.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/html/HTMLImport.cpp
diff --git a/Source/core/html/HTMLImport.cpp b/Source/core/html/HTMLImport.cpp
index abc6da56420b4719149bc322d4037536783c9481..fe07e0f196dde5d27b0d9e88bfa8b9c47aae34d9 100644
--- a/Source/core/html/HTMLImport.cpp
+++ b/Source/core/html/HTMLImport.cpp
@@ -32,6 +32,7 @@
#include "core/html/HTMLImport.h"
#include "core/dom/Document.h"
+#include "core/html/HTMLImportStateResolver.h"
namespace WebCore {
@@ -52,161 +53,102 @@ HTMLImportsController* HTMLImport::controller()
void HTMLImport::appendChild(HTMLImport* child)
{
- if (isBlockedFromRunningScript())
- child->blockFromRunningScript();
TreeNode<HTMLImport>::appendChild(child);
+
+ // This prevents HTML parser from going beyond the
+ // blockage line before the precise state is computed by recalcState().
if (child->isCreatedByParser())
- blockPredecessorsOf(child);
-}
+ forceBlock();
-bool HTMLImport::isBlockedFromCreatingDocument() const
-{
- if (hasLoader())
- return false;
- return previous() && previous()->isBlockingFollowersFromCreatingDocument();
+ stateWillChange();
}
-bool HTMLImport::isBlockedFromRunningScriptByPredecessors() const
+void HTMLImport::stateDidChange()
{
- HTMLImport* parent = this->parent();
- if (!parent)
- return false;
-
- for (HTMLImport* sibling = parent->firstChild(); sibling; sibling = sibling->next()) {
- if (sibling == this)
- break;
- if (sibling->isBlockingFollowersFromRunningScript())
- return true;
+ if (!isStateBlockedFromRunningScript()) {
+ if (Document* document = this->document())
+ document->didLoadAllImports();
}
-
- return false;
-}
-
-void HTMLImport::waitLoaderOrChildren()
-{
- if (WaitingLoaderOrChildren < m_state)
- m_state = WaitingLoaderOrChildren;
}
-void HTMLImport::blockFromRunningScript()
+void HTMLImport::recalcState()
{
- if (BlockedFromRunningScript < m_state)
- m_state = BlockedFromRunningScript;
+ ASSERT(!isStateCacheValid());
+ m_cachedState = HTMLImportStateResolver(this).resolve();
}
-void HTMLImport::becomeReady()
+void HTMLImport::forceBlock()
{
- if (!isBlocked())
- return;
- m_state = Ready;
- didBecomeReady();
+ ASSERT(m_cachedState != Ready);
+ m_cachedState = BlockedFromCreatingDocument;
}
-void HTMLImport::unblockFromRunningScript()
+void HTMLImport::stateWillChange()
{
- if (!isBlockedFromRunningScript())
- return;
- m_state = WaitingLoaderOrChildren;
- didUnblockFromRunningScript();
+ root()->scheduleRecalcState();
}
-void HTMLImport::didUnblockFromRunningScript()
+void HTMLImport::recalcTreeState(HTMLImport* root)
{
- ASSERT(!isBlockedFromCreatingDocument());
- ASSERT(!isBlockedFromRunningScript());
- if (Document* document = this->document())
- document->didLoadAllImports();
-}
+ ASSERT(root == root->root());
-void HTMLImport::didBecomeReady()
-{
- ASSERT(isDone());
-}
+ HashMap<HTMLImport*, State> snapshot;
+ Vector<HTMLImport*> updated;
-void HTMLImport::didUnblockFromCreatingDocument()
-{
- ASSERT(!isBlockedFromCreatingDocument());
-}
+ for (HTMLImport* i = root; i; i = traverseNext(i)) {
+ snapshot.add(i, i->state());
+ i->invalidateCachedState();
+ }
-void HTMLImport::loaderWasResolved()
-{
- unblockFromRunningScript();
-}
+ // The post-visit DFS order matters here because
+ // HTMLImportStateResolver in recalcState() Depends on
+ // |m_cachedState| of its children and precedents of ancestors.
+ // Accidental cycle dependency of state computation is prevented
+ // by invalidateCachedState() and isStateCacheValid() check.
+ for (HTMLImport* i = traverseFirstPostOrder(root); i; i = traverseNextPostOrder(i)) {
+ i->recalcState();
+
+ State newState = i->state();
+ State oldState = snapshot.get(i);
+ // Once the state reaches Ready, it shouldn't go back.
+ ASSERT(oldState != Ready || oldState <= newState);
+ if (newState != oldState)
+ updated.append(i);
+ }
-void HTMLImport::loaderDidFinish()
-{
- if (m_state == WaitingLoaderOrChildren)
- becomeReady();
- root()->blockerGone();
+ for (size_t i = 0; i < updated.size(); ++i)
+ updated[i]->stateDidChange();
}
-inline bool HTMLImport::isBlockingFollowersFromRunningScript() const
+bool HTMLImport::isMaster(Document* document)
{
- if (!isCreatedByParser())
- return false;
- if (isBlockedFromRunningScript())
+ if (!document->import())
return true;
- // Blocking here can result dead lock if the node doesn't own loader and has shared loader.
- // Because the shared loader can point its ascendant and forms a cycle.
- if (!ownsLoader())
- return false;
- return !isDone();
-}
-
-inline bool HTMLImport::isBlockingFollowersFromCreatingDocument() const
-{
- return !isDone();
-}
-
-bool HTMLImport::unblock(HTMLImport* import)
-{
- ASSERT(!import->isBlockedFromRunningScriptByPredecessors());
-
- if (import->isBlockedFromCreatingDocument())
- return false;
- import->didUnblockFromCreatingDocument();
-
- for (HTMLImport* child = import->firstChild(); child; child = child->next()) {
- if (!unblock(child))
- return false;
- }
-
- import->unblockFromRunningScript();
- if (import->isDone())
- import->becomeReady();
-
- return !import->isBlockingFollowersFromRunningScript();
+ return (document->import()->master() == document);
}
-void HTMLImport::block(HTMLImport* import)
+#if !defined(NDEBUG)
+void HTMLImport::show()
{
- for (HTMLImport* child = import; child; child = traverseNext(child, import))
- child->blockFromRunningScript();
+ root()->showTree(this, 0);
}
-void HTMLImport::blockPredecessorsOf(HTMLImport* child)
+void HTMLImport::showTree(HTMLImport* highlight, unsigned depth)
{
- ASSERT(child->parent() == this);
-
- for (HTMLImport* sibling = lastChild(); sibling; sibling = sibling->previous()) {
- if (sibling == child)
- break;
- HTMLImport::block(sibling);
- }
+ for (unsigned i = 0; i < depth*4; ++i)
+ fprintf(stderr, " ");
- this->blockFromRunningScript();
-
- if (HTMLImport* parent = this->parent()) {
- if (isCreatedByParser())
- parent->blockPredecessorsOf(this);
- }
+ fprintf(stderr, "%s", this == highlight ? "*" : " ");
+ showThis();
+ fprintf(stderr, "\n");
+ for (HTMLImport* child = firstChild(); child; child = child->next())
+ child->showTree(highlight, depth + 1);
}
-bool HTMLImport::isMaster(Document* document)
+void HTMLImport::showThis()
{
- if (!document->import())
- return true;
- return (document->import()->master() == document);
+ fprintf(stderr, "%p state=%d", this, m_cachedState);
}
+#endif
} // namespace WebCore
« no previous file with comments | « Source/core/html/HTMLImport.h ('k') | Source/core/html/HTMLImportChild.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698