Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / imports / HTMLImportChild.cpp
index cabbe0c..4230d3e 100644 (file)
 
 #include "core/dom/Document.h"
 #include "core/dom/custom/CustomElement.h"
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
 #include "core/dom/custom/CustomElementMicrotaskImportStep.h"
 #include "core/html/imports/HTMLImportChildClient.h"
 #include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportsController.h"
 
 namespace WebCore {
 
 HTMLImportChild::HTMLImportChild(Document& master, const KURL& url, SyncMode sync)
     : HTMLImport(sync)
+#if ENABLE(OILPAN)
+    , m_master(&master)
+#else
     , m_master(master)
+#endif
     , m_url(url)
-    , m_customElementMicrotaskStep(0)
+    , m_weakFactory(this)
+    , m_loader(0)
     , m_client(0)
 {
+#if !ENABLE(OILPAN)
     m_master.guardRef();
+#endif
 }
 
 HTMLImportChild::~HTMLImportChild()
@@ -54,22 +63,19 @@ HTMLImportChild::~HTMLImportChild()
     // importDestroyed() should be called before the destruction.
     ASSERT(!m_loader);
 
-    if (m_customElementMicrotaskStep) {
-        // if Custom Elements were blocked, must unblock them before death
-        m_customElementMicrotaskStep->importDidFinish();
-        m_customElementMicrotaskStep = 0;
-    }
-
     if (m_client)
         m_client->importChildWasDestroyed(this);
 
+#if !ENABLE(OILPAN)
     m_master.guardDeref();
+#endif
 }
 
 void HTMLImportChild::wasAlreadyLoaded()
 {
     ASSERT(!m_loader);
     ASSERT(m_client);
+    ensureLoader();
     stateWillChange();
 }
 
@@ -78,21 +84,8 @@ void HTMLImportChild::startLoading(const ResourcePtr<RawResource>& resource)
     ASSERT(!this->resource());
     ASSERT(!m_loader);
 
-    if (isSync()) {
-        ASSERT(!m_customElementMicrotaskStep);
-        m_customElementMicrotaskStep = CustomElement::didCreateImport(this);
-    }
-
     setResource(resource);
 
-    // If the node is "document blocked", it cannot create HTMLImportLoader
-    // even if there is no sharable one found, as there is possibility that
-    // preceding imports load the sharable imports.
-    // In that case preceding one should win because it comes first in the tree order.
-    // See also didUnblockFromCreatingDocument().
-    if (state().shouldBlockDocumentCreation())
-        return;
-
     ensureLoader();
 }
 
@@ -100,17 +93,25 @@ void HTMLImportChild::didFinish()
 {
     if (m_client)
         m_client->didFinish();
-
-    if (m_customElementMicrotaskStep) {
-        m_customElementMicrotaskStep->importDidFinish();
-        m_customElementMicrotaskStep = 0;
-    }
 }
 
 void HTMLImportChild::didFinishLoading()
 {
     clearResource();
     stateWillChange();
+    if (m_customElementMicrotaskStep)
+        CustomElementMicrotaskDispatcher::instance().importDidFinish(m_customElementMicrotaskStep.get());
+}
+
+void HTMLImportChild::didFinishUpgradingCustomElements()
+{
+    stateWillChange();
+    m_customElementMicrotaskStep.clear();
+}
+
+bool HTMLImportChild::isLoaded() const
+{
+    return m_loader && m_loader->isDone();
 }
 
 Document* HTMLImportChild::importedDocument() const
@@ -126,48 +127,25 @@ void HTMLImportChild::importDestroyed()
         parent()->removeChild(this);
     if (m_loader) {
         m_loader->removeImport(this);
-        m_loader.clear();
+        m_loader = 0;
     }
 }
 
-HTMLImportRoot* HTMLImportChild::root()
-{
-    return parent() ? parent()->root() : 0;
-}
-
 Document* HTMLImportChild::document() const
 {
-    return (m_loader && m_loader->isOwnedBy(this)) ? m_loader->document() : 0;
-}
-
-void HTMLImportChild::wasDetachedFromDocument()
-{
-    // For imported documens this shouldn't be called because Document::m_import is
-    // cleared before Document is destroyed by HTMLImportChild::importDestroyed().
-    ASSERT_NOT_REACHED();
-}
-
-void HTMLImportChild::didFinishParsing()
-{
-    ASSERT(m_loader->isOwnedBy(this));
-    m_loader->didFinishParsing();
+    return m_loader ? m_loader->document() : 0;
 }
 
-void HTMLImportChild::didRemoveAllPendingStylesheet()
+void HTMLImportChild::stateWillChange()
 {
-    ASSERT(m_loader->isOwnedBy(this));
-    m_loader->didRemoveAllPendingStylesheet();
+    toHTMLImportsController(root())->scheduleRecalcState();
 }
 
 void HTMLImportChild::stateDidChange()
 {
     HTMLImport::stateDidChange();
 
-    // Once all preceding imports are loaded,
-    // HTMLImportChild can decide whether it should load the import by itself
-    // or it can share existing one.
-    if (!state().shouldBlockDocumentCreation())
-        ensureLoader();
+    ensureLoader();
     if (state().isReady())
         didFinish();
 }
@@ -177,17 +155,21 @@ void HTMLImportChild::ensureLoader()
     if (m_loader)
         return;
 
-    if (HTMLImportChild* found = root()->findLinkFor(m_url, this))
+    if (HTMLImportChild* found = toHTMLImportsController(root())->findLinkFor(m_url, this))
         shareLoader(found);
     else
         createLoader();
+
+    if (!isDone() && !formsCycle()) {
+        ASSERT(!m_customElementMicrotaskStep);
+        m_customElementMicrotaskStep = CustomElement::didCreateImport(this)->weakPtr();
+    }
 }
 
 void HTMLImportChild::createLoader()
 {
-    ASSERT(!state().shouldBlockDocumentCreation());
     ASSERT(!m_loader);
-    m_loader = HTMLImportLoader::create();
+    m_loader = toHTMLImportsController(root())->createLoader();
     m_loader->addImport(this);
     m_loader->startLoading(resource());
 }
@@ -202,17 +184,7 @@ void HTMLImportChild::shareLoader(HTMLImportChild* loader)
 
 bool HTMLImportChild::isDone() const
 {
-    return m_loader && m_loader->isDone();
-}
-
-bool HTMLImportChild::hasLoader() const
-{
-    return m_loader;
-}
-
-bool HTMLImportChild::ownsLoader() const
-{
-    return m_loader && m_loader->isOwnedBy(this);
+    return m_loader && m_loader->isDone() && !m_customElementMicrotaskStep;
 }
 
 bool HTMLImportChild::loaderHasError() const
@@ -242,13 +214,30 @@ HTMLLinkElement* HTMLImportChild::link() const
     return m_client->link();
 }
 
+// Ensuring following invariants against the import tree:
+// - HTMLImportChild::firstImport() is the "first import" of the DFS order of the import tree.
+// - The "first import" manages all the children that is loaded by the document.
+void HTMLImportChild::normalize()
+{
+    if (!loader()->isFirstImport(this) && this->precedes(loader()->firstImport())) {
+        HTMLImportChild* oldFirst = loader()->firstImport();
+        loader()->moveToFirst(this);
+        takeChildrenFrom(oldFirst);
+    }
+
+    for (HTMLImport* child = firstChild(); child; child = child->next())
+        toHTMLImportChild(child)->normalize();
+}
+
 #if !defined(NDEBUG)
 void HTMLImportChild::showThis()
 {
+    bool isFirst = loader() ? loader()->isFirstImport(this) : false;
     HTMLImport::showThis();
-    fprintf(stderr, " loader=%p own=%s async=%s url=%s",
-        m_loader.get(),
-        hasLoader() && ownsLoader() ? "Y" : "N",
+    fprintf(stderr, " loader=%p first=%d, step=%p sync=%s url=%s",
+        m_loader,
+        isFirst,
+        m_customElementMicrotaskStep.get(),
         isSync() ? "Y" : "N",
         url().string().utf8().data());
 }