Commit 91e53b7e authored by dglazkov@chromium.org's avatar dglazkov@chromium.org

Extract tree root responsibility out of HTMLImportsController.

The HTMLImportsController wishes to become more of an Actor-style object,
and it being a root of the import tree leads to ambiguities in responsibilities.
So we should split these responsibilities cleanly.

R=morrita
BUG=

Review URL: https://codereview.chromium.org/301803002

git-svn-id: svn://svn.chromium.org/blink/trunk@175108 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d6767b62
...@@ -2685,6 +2685,8 @@ ...@@ -2685,6 +2685,8 @@
'html/imports/HTMLImportState.h', 'html/imports/HTMLImportState.h',
'html/imports/HTMLImportStateResolver.cpp', 'html/imports/HTMLImportStateResolver.cpp',
'html/imports/HTMLImportStateResolver.h', 'html/imports/HTMLImportStateResolver.h',
'html/imports/HTMLImportTreeRoot.cpp',
'html/imports/HTMLImportTreeRoot.h',
'html/imports/HTMLImportsController.cpp', 'html/imports/HTMLImportsController.cpp',
'html/imports/HTMLImportsController.h', 'html/imports/HTMLImportsController.h',
'html/imports/LinkImport.cpp', 'html/imports/LinkImport.cpp',
......
...@@ -51,13 +51,15 @@ class KURL; ...@@ -51,13 +51,15 @@ class KURL;
// //
// HTML Imports form a tree: // HTML Imports form a tree:
// //
// * The root of the tree is HTMLImportsController, which is owned by the master // * The root of the tree is HTMLImportTreeRoot.
//
// * The HTMLImportTreeRoot is owned HTMLImportsController, which is owned by the master
// document as a DocumentSupplement. // document as a DocumentSupplement.
// //
// * The non-root nodes are HTMLImportChild, which is owned by LinkStyle, that is owned by HTMLLinkElement. // * The non-root nodes are HTMLImportChild. They are also owned by HTMLImportsController.
// LinkStyle is wired into HTMLImportChild by implementing HTMLImportChildClient interface // LinkStyle is wired into HTMLImportChild by implementing HTMLImportChildClient interface
// //
// * Both HTMLImportsController and HTMLImportChild are derived from HTMLImport superclass // * Both HTMLImportTreeRoot and HTMLImportChild are derived from HTMLImport superclass
// that models the tree data structure using WTF::TreeNode and provides a set of // that models the tree data structure using WTF::TreeNode and provides a set of
// virtual functions. // virtual functions.
// //
...@@ -65,12 +67,6 @@ class KURL; ...@@ -65,12 +67,6 @@ class KURL;
// One assumption is that the tree is append-only and nodes are never inserted in the middle of the tree nor removed. // One assumption is that the tree is append-only and nodes are never inserted in the middle of the tree nor removed.
// //
// //
// HTMLImport <|- HTMLImportsController <- Document
// *
// |
// <|- HTMLImportChild <- LinkStyle <- HTMLLinkElement
//
//
// # Import Sharing and HTMLImportLoader // # Import Sharing and HTMLImportLoader
// //
// The HTML Imports spec calls for de-dup mechanism to share already loaded imports. // The HTML Imports spec calls for de-dup mechanism to share already loaded imports.
...@@ -94,7 +90,7 @@ class KURL; ...@@ -94,7 +90,7 @@ class KURL;
// In such case, the preceding import should be loaded and following ones should be de-duped. // In such case, the preceding import should be loaded and following ones should be de-duped.
// //
// The superclass of HTMLImportsController and HTMLImportChild // The superclass of HTMLImportTreeRoot and HTMLImportChild
// This represents the import tree data structure. // This represents the import tree data structure.
class HTMLImport : public TreeNode<HTMLImport> { class HTMLImport : public TreeNode<HTMLImport> {
public: public:
...@@ -105,6 +101,7 @@ public: ...@@ -105,6 +101,7 @@ public:
virtual ~HTMLImport() { } virtual ~HTMLImport() { }
// FIXME: Consider returning HTMLImportTreeRoot.
HTMLImport* root(); HTMLImport* root();
bool precedes(HTMLImport*); bool precedes(HTMLImport*);
bool isRoot() const { return !isChild(); } bool isRoot() const { return !isChild(); }
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "core/dom/custom/CustomElementMicrotaskQueue.h" #include "core/dom/custom/CustomElementMicrotaskQueue.h"
#include "core/html/imports/HTMLImportChildClient.h" #include "core/html/imports/HTMLImportChildClient.h"
#include "core/html/imports/HTMLImportLoader.h" #include "core/html/imports/HTMLImportLoader.h"
#include "core/html/imports/HTMLImportTreeRoot.h"
#include "core/html/imports/HTMLImportsController.h" #include "core/html/imports/HTMLImportsController.h"
namespace WebCore { namespace WebCore {
...@@ -124,7 +125,7 @@ Document* HTMLImportChild::document() const ...@@ -124,7 +125,7 @@ Document* HTMLImportChild::document() const
void HTMLImportChild::stateWillChange() void HTMLImportChild::stateWillChange()
{ {
toHTMLImportsController(root())->scheduleRecalcState(); toHTMLImportTreeRoot(root())->scheduleRecalcState();
} }
void HTMLImportChild::stateDidChange() void HTMLImportChild::stateDidChange()
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/html/imports/HTMLImportTreeRoot.h"
#include "core/dom/Document.h"
#include "core/dom/StyleEngine.h"
#include "core/frame/LocalFrame.h"
namespace WebCore {
PassOwnPtr<HTMLImportTreeRoot> HTMLImportTreeRoot::create(Document* document)
{
return adoptPtr(new HTMLImportTreeRoot(document));
}
HTMLImportTreeRoot::HTMLImportTreeRoot(Document* document)
: HTMLImport(HTMLImport::Sync)
, m_document(document)
, m_recalcTimer(this, &HTMLImportTreeRoot::recalcTimerFired)
{
recalcTreeState(this); // This recomputes initial state.
}
Document* HTMLImportTreeRoot::document() const
{
return m_document;
}
bool HTMLImportTreeRoot::isDone() const
{
return !m_document->parsing() && m_document->styleEngine()->haveStylesheetsLoaded();
}
void HTMLImportTreeRoot::stateWillChange()
{
scheduleRecalcState();
}
void HTMLImportTreeRoot::stateDidChange()
{
HTMLImport::stateDidChange();
if (!state().isReady())
return;
if (LocalFrame* frame = m_document->frame())
frame->loader().checkCompleted();
}
void HTMLImportTreeRoot::scheduleRecalcState()
{
if (m_recalcTimer.isActive() || !m_document)
return;
m_recalcTimer.startOneShot(0, FROM_HERE);
}
void HTMLImportTreeRoot::recalcTimerFired(Timer<HTMLImportTreeRoot>*)
{
ASSERT(m_document);
do {
m_recalcTimer.stop();
HTMLImport::recalcTreeState(this);
} while (m_recalcTimer.isActive());
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef HTMLImportTreeRoot_h
#define HTMLImportTreeRoot_h
#include "core/html/imports/HTMLImport.h"
#include "platform/Timer.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
class HTMLImportTreeRoot : public HTMLImport {
public:
static PassOwnPtr<HTMLImportTreeRoot> create(Document*);
// HTMLImport
virtual Document* document() const OVERRIDE;
virtual bool isDone() const OVERRIDE;
virtual void stateWillChange() OVERRIDE;
virtual void stateDidChange() OVERRIDE;
void scheduleRecalcState();
private:
explicit HTMLImportTreeRoot(Document*);
void recalcTimerFired(Timer<HTMLImportTreeRoot>*);
Document* m_document;
Timer<HTMLImportTreeRoot> m_recalcTimer;
};
DEFINE_TYPE_CASTS(HTMLImportTreeRoot, HTMLImport, import, import->isRoot(), import.isRoot());
}
#endif
...@@ -32,12 +32,12 @@ ...@@ -32,12 +32,12 @@
#include "core/html/imports/HTMLImportsController.h" #include "core/html/imports/HTMLImportsController.h"
#include "core/dom/Document.h" #include "core/dom/Document.h"
#include "core/dom/StyleEngine.h"
#include "core/fetch/ResourceFetcher.h" #include "core/fetch/ResourceFetcher.h"
#include "core/frame/LocalFrame.h" #include "core/frame/LocalFrame.h"
#include "core/html/imports/HTMLImportChild.h" #include "core/html/imports/HTMLImportChild.h"
#include "core/html/imports/HTMLImportChildClient.h" #include "core/html/imports/HTMLImportChildClient.h"
#include "core/html/imports/HTMLImportLoader.h" #include "core/html/imports/HTMLImportLoader.h"
#include "core/html/imports/HTMLImportTreeRoot.h"
namespace WebCore { namespace WebCore {
...@@ -50,11 +50,9 @@ void HTMLImportsController::provideTo(Document& master) ...@@ -50,11 +50,9 @@ void HTMLImportsController::provideTo(Document& master)
} }
HTMLImportsController::HTMLImportsController(Document& master) HTMLImportsController::HTMLImportsController(Document& master)
: HTMLImport(HTMLImport::Sync) : m_master(&master)
, m_master(&master) , m_root(HTMLImportTreeRoot::create(&master))
, m_recalcTimer(this, &HTMLImportsController::recalcTimerFired)
{ {
recalcTreeState(this); // This recomputes initial state.
} }
HTMLImportsController::~HTMLImportsController() HTMLImportsController::~HTMLImportsController()
...@@ -76,7 +74,7 @@ void HTMLImportsController::clear() ...@@ -76,7 +74,7 @@ void HTMLImportsController::clear()
m_master->setImportsController(0); m_master->setImportsController(0);
m_master = 0; m_master = 0;
m_recalcTimer.stop(); m_root.clear();
} }
static bool makesCycle(HTMLImport* parent, const KURL& url) static bool makesCycle(HTMLImport* parent, const KURL& url)
...@@ -103,7 +101,7 @@ HTMLImportChild* HTMLImportsController::createChild(const KURL& url, HTMLImportL ...@@ -103,7 +101,7 @@ HTMLImportChild* HTMLImportsController::createChild(const KURL& url, HTMLImportL
HTMLImportChild* HTMLImportsController::load(HTMLImport* parent, HTMLImportChildClient* client, FetchRequest request) HTMLImportChild* HTMLImportsController::load(HTMLImport* parent, HTMLImportChildClient* client, FetchRequest request)
{ {
ASSERT(!request.url().isEmpty() && request.url().isValid()); ASSERT(!request.url().isEmpty() && request.url().isValid());
ASSERT(parent == this || toHTMLImportChild(parent)->loader()->isFirstImport(toHTMLImportChild(parent))); ASSERT(parent == root() || toHTMLImportChild(parent)->loader()->isFirstImport(toHTMLImportChild(parent)));
if (HTMLImportChild* childToShareWith = findLinkFor(request.url())) { if (HTMLImportChild* childToShareWith = findLinkFor(request.url())) {
HTMLImportLoader* loader = childToShareWith->loader(); HTMLImportLoader* loader = childToShareWith->loader();
...@@ -162,17 +160,12 @@ LocalFrame* HTMLImportsController::frame() const ...@@ -162,17 +160,12 @@ LocalFrame* HTMLImportsController::frame() const
return m_master->frame(); return m_master->frame();
} }
Document* HTMLImportsController::document() const
{
return m_master;
}
bool HTMLImportsController::shouldBlockScriptExecution(const Document& document) const bool HTMLImportsController::shouldBlockScriptExecution(const Document& document) const
{ {
ASSERT(document.importsController() == this); ASSERT(document.importsController() == this);
if (HTMLImportLoader* loader = loaderFor(document)) if (HTMLImportLoader* loader = loaderFor(document))
return loader->shouldBlockScriptExecution(); return loader->shouldBlockScriptExecution();
return state().shouldBlockScriptExecution(); return root()->state().shouldBlockScriptExecution();
} }
void HTMLImportsController::wasDetachedFrom(const Document& document) void HTMLImportsController::wasDetachedFrom(const Document& document)
...@@ -182,43 +175,6 @@ void HTMLImportsController::wasDetachedFrom(const Document& document) ...@@ -182,43 +175,6 @@ void HTMLImportsController::wasDetachedFrom(const Document& document)
clear(); clear();
} }
bool HTMLImportsController::isDone() const
{
return !m_master->parsing() && m_master->styleEngine()->haveStylesheetsLoaded();
}
void HTMLImportsController::stateWillChange()
{
scheduleRecalcState();
}
void HTMLImportsController::stateDidChange()
{
HTMLImport::stateDidChange();
if (!state().isReady())
return;
if (LocalFrame* frame = m_master->frame())
frame->loader().checkCompleted();
}
void HTMLImportsController::scheduleRecalcState()
{
if (m_recalcTimer.isActive() || !m_master)
return;
m_recalcTimer.startOneShot(0, FROM_HERE);
}
void HTMLImportsController::recalcTimerFired(Timer<HTMLImportsController>*)
{
ASSERT(m_master);
do {
m_recalcTimer.stop();
HTMLImport::recalcTreeState(this);
} while (m_recalcTimer.isActive());
}
HTMLImportLoader* HTMLImportsController::createLoader() HTMLImportLoader* HTMLImportsController::createLoader()
{ {
m_loaders.append(HTMLImportLoader::create(this)); m_loaders.append(HTMLImportLoader::create(this));
......
...@@ -48,8 +48,9 @@ class ResourceFetcher; ...@@ -48,8 +48,9 @@ class ResourceFetcher;
class HTMLImportChild; class HTMLImportChild;
class HTMLImportChildClient; class HTMLImportChildClient;
class HTMLImportLoader; class HTMLImportLoader;
class HTMLImportTreeRoot;
class HTMLImportsController FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLImportsController>, public HTMLImport, public DocumentSupplement { class HTMLImportsController FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLImportsController>, public DocumentSupplement {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLImportsController); WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLImportsController);
WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public: public:
...@@ -58,16 +59,12 @@ public: ...@@ -58,16 +59,12 @@ public:
explicit HTMLImportsController(Document&); explicit HTMLImportsController(Document&);
virtual ~HTMLImportsController(); virtual ~HTMLImportsController();
HTMLImportTreeRoot* root() const { return m_root.get(); }
bool isMaster(const Document& document) const { return m_master == &document; } bool isMaster(const Document& document) const { return m_master == &document; }
bool shouldBlockScriptExecution(const Document&) const; bool shouldBlockScriptExecution(const Document&) const;
void wasDetachedFrom(const Document&); void wasDetachedFrom(const Document&);
// HTMLImport
virtual Document* document() const OVERRIDE;
virtual bool isDone() const OVERRIDE;
virtual void stateWillChange() OVERRIDE;
virtual void stateDidChange() OVERRIDE;
HTMLImportChild* load(HTMLImport* parent, HTMLImportChildClient*, FetchRequest); HTMLImportChild* load(HTMLImport* parent, HTMLImportChildClient*, FetchRequest);
void showSecurityErrorMessage(const String&); void showSecurityErrorMessage(const String&);
...@@ -76,7 +73,6 @@ public: ...@@ -76,7 +73,6 @@ public:
LocalFrame* frame() const; LocalFrame* frame() const;
Document* master() const { return m_master; } Document* master() const { return m_master; }
void recalcTimerFired(Timer<HTMLImportsController>*);
HTMLImportLoader* createLoader(); HTMLImportLoader* createLoader();
...@@ -84,7 +80,6 @@ public: ...@@ -84,7 +80,6 @@ public:
HTMLImportLoader* loaderAt(size_t i) const { return m_loaders[i].get(); } HTMLImportLoader* loaderAt(size_t i) const { return m_loaders[i].get(); }
HTMLImportLoader* loaderFor(const Document&) const; HTMLImportLoader* loaderFor(const Document&) const;
void scheduleRecalcState();
HTMLImportChild* findLinkFor(const KURL&) const; HTMLImportChild* findLinkFor(const KURL&) const;
private: private:
...@@ -92,7 +87,8 @@ private: ...@@ -92,7 +87,8 @@ private:
void clear(); void clear();
Document* m_master; Document* m_master;
Timer<HTMLImportsController> m_recalcTimer;
OwnPtr<HTMLImportTreeRoot> m_root;
// List of import which has been loaded or being loaded. // List of import which has been loaded or being loaded.
typedef Vector<OwnPtr<HTMLImportChild> > ImportList; typedef Vector<OwnPtr<HTMLImportChild> > ImportList;
...@@ -102,8 +98,6 @@ private: ...@@ -102,8 +98,6 @@ private:
LoaderList m_loaders; LoaderList m_loaders;
}; };
DEFINE_TYPE_CASTS(HTMLImportsController, HTMLImport, import, import->isRoot(), import.isRoot());
} // namespace WebCore } // namespace WebCore
#endif // HTMLImportsController_h #endif // HTMLImportsController_h
...@@ -36,9 +36,9 @@ ...@@ -36,9 +36,9 @@
#include "core/html/HTMLLinkElement.h" #include "core/html/HTMLLinkElement.h"
#include "core/html/imports/HTMLImportChild.h" #include "core/html/imports/HTMLImportChild.h"
#include "core/html/imports/HTMLImportLoader.h" #include "core/html/imports/HTMLImportLoader.h"
#include "core/html/imports/HTMLImportTreeRoot.h"
#include "core/html/imports/HTMLImportsController.h" #include "core/html/imports/HTMLImportsController.h"
namespace WebCore { namespace WebCore {
PassOwnPtrWillBeRawPtr<LinkImport> LinkImport::create(HTMLLinkElement* owner) PassOwnPtrWillBeRawPtr<LinkImport> LinkImport::create(HTMLLinkElement* owner)
...@@ -89,7 +89,7 @@ void LinkImport::process() ...@@ -89,7 +89,7 @@ void LinkImport::process()
HTMLImportsController* controller = m_owner->document().importsController(); HTMLImportsController* controller = m_owner->document().importsController();
HTMLImportLoader* loader = m_owner->document().importLoader(); HTMLImportLoader* loader = m_owner->document().importLoader();
HTMLImport* parent = loader ? static_cast<HTMLImport*>(loader->firstImport()) : static_cast<HTMLImport*>(controller); HTMLImport* parent = loader ? static_cast<HTMLImport*>(loader->firstImport()) : static_cast<HTMLImport*>(controller->root());
m_child = controller->load(parent, this, builder.build(true)); m_child = controller->load(parent, this, builder.build(true));
if (!m_child) { if (!m_child) {
didFinish(); didFinish();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment