Commit 81596e47 authored by hayato@chromium.org's avatar hayato@chromium.org

Change class hierarycy so that ShadowRoot can inherit DocumentFragment.

https://bugs.webkit.org/show_bug.cgi?id=76693

Reviewed by Darin Adler.

Make ShadowRoot inherit DocumentFragment so that it matches the class hierarchy of IDL in the spec.
TreeScope becomes a separated class, which is now inherited by Document and ShadowRoot using multiple-inheritance.
This patch is pre-requirement for coming IDL change.

No tests. No change in behavior.

* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::~Document):
(WebCore::Document::buildAccessKeyMap):
(WebCore::Document::childrenChanged):
(WebCore::Document::attach):
(WebCore::Document::detach):
* dom/Document.h:
(Document):
* dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::DocumentFragment):
* dom/DocumentFragment.h:
(DocumentFragment):
* dom/DocumentOrderedMap.cpp:
(WebCore::DocumentOrderedMap::get):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::~ShadowRoot):
(WebCore::ShadowRoot::attach):
* dom/ShadowRoot.h:
* dom/TreeScope.cpp:
(WebCore::TreeScope::TreeScope):
(WebCore::TreeScope::~TreeScope):
(WebCore::TreeScope::setParentTreeScope):
(WebCore::TreeScope::getImageMap):
(WebCore::TreeScope::findAnchor):
* dom/TreeScope.h:
(WebCore):
(WebCore::TreeScope::rootNode):
(TreeScope):
* dom/TreeScopeAdopter.cpp:
(WebCore::TreeScopeAdopter::moveTreeToNewScope):
* page/DragController.cpp:
(WebCore::asFileInput):
* page/FocusController.cpp:
(WebCore::ownerOfTreeScope):
(WebCore::FocusController::nextFocusableNode):
(WebCore::FocusController::previousFocusableNode):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106530 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 621743c1
2012-02-01 Hayato Ito <hayato@chromium.org>
Change class hierarycy so that ShadowRoot can inherit DocumentFragment.
https://bugs.webkit.org/show_bug.cgi?id=76693
Reviewed by Darin Adler.
Make ShadowRoot inherit DocumentFragment so that it matches the class hierarchy of IDL in the spec.
TreeScope becomes a separated class, which is now inherited by Document and ShadowRoot using multiple-inheritance.
This patch is pre-requirement for coming IDL change.
No tests. No change in behavior.
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::~Document):
(WebCore::Document::buildAccessKeyMap):
(WebCore::Document::childrenChanged):
(WebCore::Document::attach):
(WebCore::Document::detach):
* dom/Document.h:
(Document):
* dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::DocumentFragment):
* dom/DocumentFragment.h:
(DocumentFragment):
* dom/DocumentOrderedMap.cpp:
(WebCore::DocumentOrderedMap::get):
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::ShadowRoot):
(WebCore::ShadowRoot::~ShadowRoot):
(WebCore::ShadowRoot::attach):
* dom/ShadowRoot.h:
* dom/TreeScope.cpp:
(WebCore::TreeScope::TreeScope):
(WebCore::TreeScope::~TreeScope):
(WebCore::TreeScope::setParentTreeScope):
(WebCore::TreeScope::getImageMap):
(WebCore::TreeScope::findAnchor):
* dom/TreeScope.h:
(WebCore):
(WebCore::TreeScope::rootNode):
(TreeScope):
* dom/TreeScopeAdopter.cpp:
(WebCore::TreeScopeAdopter::moveTreeToNewScope):
* page/DragController.cpp:
(WebCore::asFileInput):
* page/FocusController.cpp:
(WebCore::ownerOfTreeScope):
(WebCore::FocusController::nextFocusableNode):
(WebCore::FocusController::previousFocusableNode):
2012-02-01 Benjamin Poulain <bpoulain@apple.com>
WorkerScriptController::evaluate() should not return anything
......@@ -373,7 +373,8 @@ private:
uint64_t Document::s_globalTreeVersion = 0;
Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
: TreeScope(0)
: ContainerNode(0)
, TreeScope(this)
, m_guardRefCount(0)
, m_compatibilityMode(NoQuirksMode)
, m_compatibilityModeLocked(false)
......@@ -571,6 +572,11 @@ Document::~Document()
if (m_mediaQueryMatcher)
m_mediaQueryMatcher->documentDestroyed();
// We must call clearRareData() here since a Document class inherits TreeScope
// as well as Node. See a comment on TreeScope.h for the reason.
if (hasRareData())
clearRareData();
}
void Document::removedLastRef()
......@@ -642,16 +648,19 @@ Element* Document::getElementByAccessKey(const String& key)
return m_elementsByAccessKey.get(key.impl());
}
void Document::buildAccessKeyMap(TreeScope* root)
void Document::buildAccessKeyMap(TreeScope* scope)
{
for (Node* n = root; n; n = n->traverseNextNode(root)) {
if (!n->isElementNode())
ASSERT(scope);
Node* rootNode = scope->rootNode();
for (Node* node = rootNode; node; node = node->traverseNextNode(rootNode)) {
if (!node->isElementNode())
continue;
Element* element = static_cast<Element*>(n);
Element* element = static_cast<Element*>(node);
const AtomicString& accessKey = element->getAttribute(accesskeyAttr);
if (!accessKey.isEmpty())
m_elementsByAccessKey.set(accessKey.impl(), element);
buildAccessKeyMap(element->shadowRoot());
if (ShadowRoot* shadowRoot = element->shadowRoot())
buildAccessKeyMap(shadowRoot);
}
}
......@@ -722,7 +731,7 @@ DOMImplementation* Document::implementation()
void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
TreeScope::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
Element* newDocumentElement = firstElementChild(this);
if (newDocumentElement == m_documentElement)
......@@ -1840,7 +1849,7 @@ void Document::attach()
RenderObject* render = renderer();
setRenderer(0);
TreeScope::attach();
ContainerNode::attach();
setRenderer(render);
}
......@@ -1894,7 +1903,7 @@ void Document::detach()
m_focusedNode = 0;
m_activeNode = 0;
TreeScope::detach();
ContainerNode::detach();
unscheduleStyleRecalc();
......
......@@ -31,6 +31,7 @@
#include "CheckedRadioButtons.h"
#include "CollectionType.h"
#include "Color.h"
#include "ContainerNode.h"
#include "DOMTimeStamp.h"
#include "DocumentEventQueue.h"
#include "DocumentTiming.h"
......@@ -213,7 +214,7 @@ enum PageshowEventPersistence {
enum StyleSelectorUpdateFlag { RecalcStyleImmediately, DeferRecalcStyle, RecalcStyleIfNeeded };
class Document : public TreeScope, public ScriptExecutionContext {
class Document : public ContainerNode, public TreeScope, public ScriptExecutionContext {
public:
static PassRefPtr<Document> create(Frame* frame, const KURL& url)
{
......@@ -227,8 +228,8 @@ public:
MediaQueryMatcher* mediaQueryMatcher();
using TreeScope::ref;
using TreeScope::deref;
using ContainerNode::ref;
using ContainerNode::deref;
// Nodes belonging to this document hold guard references -
// these are enough to keep the document from being destroyed, but
......
......@@ -32,8 +32,8 @@
namespace WebCore {
DocumentFragment::DocumentFragment(Document* document)
: ContainerNode(document)
DocumentFragment::DocumentFragment(Document* document, ConstructionType constructionType)
: ContainerNode(document, constructionType)
{
ASSERT(document);
}
......
......@@ -39,7 +39,7 @@ public:
virtual bool canContainRangeEndPoint() const { return true; }
protected:
DocumentFragment(Document*);
DocumentFragment(Document*, ConstructionType = CreateContainer);
virtual String nodeName() const;
private:
......
......@@ -108,6 +108,7 @@ template<bool keyMatches(AtomicStringImpl*, Element*)>
inline Element* DocumentOrderedMap::get(AtomicStringImpl* key, const TreeScope* scope) const
{
ASSERT(key);
ASSERT(scope);
m_map.checkConsistency();
......@@ -117,7 +118,7 @@ inline Element* DocumentOrderedMap::get(AtomicStringImpl* key, const TreeScope*
if (m_duplicateCounts.contains(key)) {
// We know there's at least one node that matches; iterate to find the first one.
for (Node* node = scope->firstChild(); node; node = node->traverseNextNode()) {
for (Node* node = scope->rootNode()->firstChild(); node; node = node->traverseNextNode()) {
if (!node->isElementNode())
continue;
element = static_cast<Element*>(node);
......
......@@ -37,7 +37,8 @@
namespace WebCore {
ShadowRoot::ShadowRoot(Document* document)
: TreeScope(document, CreateShadowRoot)
: DocumentFragment(document, CreateShadowRoot)
, TreeScope(this)
, m_applyAuthorSheets(false)
, m_needsRecalculateContent(false)
{
......@@ -52,6 +53,10 @@ ShadowRoot::ShadowRoot(Document* document)
ShadowRoot::~ShadowRoot()
{
// We must call clearRareData() here since a ShadowRoot class inherits TreeScope
// as well as Node. See a comment on TreeScope.h for the reason.
if (hasRareData())
clearRareData();
}
PassRefPtr<ShadowRoot> ShadowRoot::create(Element* element, ExceptionCode& ec)
......@@ -172,7 +177,7 @@ void ShadowRoot::attach()
// ensureInclusions(), and here we just ensure that
// it is in clean state.
ASSERT(!m_inclusions || !m_inclusions->hasCandidates());
TreeScope::attach();
DocumentFragment::attach();
if (m_inclusions)
m_inclusions->didSelect();
}
......
......@@ -27,6 +27,7 @@
#ifndef ShadowRoot_h
#define ShadowRoot_h
#include "DocumentFragment.h"
#include "ExceptionCode.h"
#include "TreeScope.h"
......@@ -36,7 +37,7 @@ class ContentInclusionSelector;
class Document;
class HTMLContentElement;
class ShadowRoot : public TreeScope {
class ShadowRoot : public DocumentFragment, public TreeScope {
public:
static PassRefPtr<ShadowRoot> create(Document*);
static PassRefPtr<ShadowRoot> create(Element*, ExceptionCode&);
......
......@@ -26,28 +26,30 @@
#include "config.h"
#include "TreeScope.h"
#include "ContainerNode.h"
#include "Document.h"
#include "Element.h"
#include "HTMLAnchorElement.h"
#include "HTMLMapElement.h"
#include "HTMLNames.h"
#include "NodeRareData.h"
#include "TreeScopeAdopter.h"
#include <wtf/text/AtomicString.h>
#include <wtf/text/CString.h>
namespace WebCore {
using namespace HTMLNames;
TreeScope::TreeScope(Document* document, ConstructionType constructionType)
: ContainerNode(document, constructionType)
TreeScope::TreeScope(ContainerNode* rootNode)
: m_rootNode(rootNode)
, m_parentTreeScope(0)
, m_numNodeListCaches(0)
{
ASSERT(rootNode);
}
TreeScope::~TreeScope()
{
if (hasRareData())
clearRareData();
}
void TreeScope::destroyTreeScopeData()
......@@ -59,7 +61,7 @@ void TreeScope::destroyTreeScopeData()
void TreeScope::setParentTreeScope(TreeScope* newParentScope)
{
// A document node cannot be re-parented.
ASSERT(!isDocumentNode());
ASSERT(!rootNode()->isDocumentNode());
// Every scope other than document needs a parent scope.
ASSERT(newParentScope);
......@@ -105,7 +107,7 @@ HTMLMapElement* TreeScope::getImageMap(const String& url) const
return 0;
size_t hashPos = url.find('#');
String name = (hashPos == notFound ? url : url.substring(hashPos + 1)).impl();
if (document()->isHTMLDocument())
if (rootNode()->document()->isHTMLDocument())
return static_cast<HTMLMapElement*>(m_imageMapsByName.getElementByLowercasedMapName(AtomicString(name.lower()).impl(), this));
return static_cast<HTMLMapElement*>(m_imageMapsByName.getElementByMapName(AtomicString(name).impl(), this));
}
......@@ -116,10 +118,10 @@ Element* TreeScope::findAnchor(const String& name)
return 0;
if (Element* element = getElementById(name))
return element;
for (Node* node = this; node; node = node->traverseNextNode()) {
for (Node* node = rootNode(); node; node = node->traverseNextNode()) {
if (node->hasTagName(aTag)) {
HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(node);
if (document()->inQuirksMode()) {
if (rootNode()->document()->inQuirksMode()) {
// Quirks mode, case insensitive comparison of names.
if (equalIgnoringCase(anchor->name(), name))
return anchor;
......
......@@ -26,15 +26,21 @@
#ifndef TreeScope_h
#define TreeScope_h
#include "ContainerNode.h"
#include "DocumentOrderedMap.h"
#include <wtf/Forward.h>
#include <wtf/text/AtomicString.h>
namespace WebCore {
class ContainerNode;
class Element;
class HTMLMapElement;
class Node;
class TreeScope : public ContainerNode {
// A class which inherits both Node and TreeScope must call clearRareData() in its destructor
// so that the Node destructor no longer does problematic NodeList cache manipulation in
// the destructor.
class TreeScope {
friend class Document;
public:
......@@ -67,13 +73,16 @@ public:
// Used by the basic DOM mutation methods (e.g., appendChild()).
void adoptIfNeeded(Node*);
ContainerNode* rootNode() const { return m_rootNode; }
protected:
TreeScope(Document*, ConstructionType = CreateContainer);
TreeScope(ContainerNode*);
virtual ~TreeScope();
void destroyTreeScopeData();
private:
ContainerNode* m_rootNode;
TreeScope* m_parentTreeScope;
DocumentOrderedMap m_elementsById;
......
......@@ -44,8 +44,8 @@ void TreeScopeAdopter::moveTreeToNewScope(Node* root) const
// that element may contain stale data as changes made to it will have updated the DOMTreeVersion
// of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
// we ensure that the collection cache will be invalidated as needed when the element is moved back.
Document* oldDocument = m_oldScope ? m_oldScope->document() : 0;
Document* newDocument = m_newScope->document();
Document* oldDocument = m_oldScope ? m_oldScope->rootNode()->document() : 0;
Document* newDocument = m_newScope->rootNode()->document();
bool willMoveToNewDocument = oldDocument != newDocument;
if (oldDocument && willMoveToNewDocument)
oldDocument->incDOMTreeVersion();
......
......@@ -270,8 +270,8 @@ static HTMLInputElement* asFileInput(Node* node)
HTMLInputElement* inputElement = node->toInputElement();
// If this is a button inside of the a file input, move up to the file input.
if (inputElement && inputElement->isTextButton() && inputElement->treeScope()->isShadowRoot())
inputElement = inputElement->treeScope()->shadowHost()->toInputElement();
if (inputElement && inputElement->isTextButton() && inputElement->treeScope()->rootNode()->isShadowRoot())
inputElement = inputElement->treeScope()->rootNode()->shadowHost()->toInputElement();
return inputElement && inputElement->isFileUpload() ? inputElement : 0;
}
......
......@@ -319,10 +319,10 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, Keyb
static inline Node* ownerOfTreeScope(TreeScope* scope)
{
ASSERT(scope);
if (scope->isShadowRoot())
return scope->shadowHost();
if (scope->document()->frame())
return scope->document()->frame()->ownerElement();
if (scope->rootNode()->isShadowRoot())
return scope->rootNode()->shadowHost();
if (scope->rootNode()->document()->frame())
return scope->rootNode()->document()->frame()->ownerElement();
return 0;
}
......@@ -419,18 +419,18 @@ Node* FocusController::nextFocusableNode(TreeScope* scope, Node* start, Keyboard
// Look for the first node in the scope that:
// 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
// 2) comes first in the scope, if there's a tie.
if (Node* winner = nextNodeWithGreaterTabIndex(scope, start ? start->tabIndex() : 0, event))
if (Node* winner = nextNodeWithGreaterTabIndex(scope->rootNode(), start ? start->tabIndex() : 0, event))
return winner;
// There are no nodes with a tabindex greater than start's tabindex,
// so find the first node with a tabindex of 0.
return nextNodeWithExactTabIndex(scope, 0, event);
return nextNodeWithExactTabIndex(scope->rootNode(), 0, event);
}
Node* FocusController::previousFocusableNode(TreeScope* scope, Node* start, KeyboardEvent* event)
{
Node* last;
for (last = scope; last->lastChild(); last = last->lastChild()) { }
for (last = scope->rootNode(); last->lastChild(); last = last->lastChild()) { }
// First try to find the last node in the scope that comes before start and has the same tabindex as start.
// If start is null, find the last node in the scope with a tabindex of 0.
......
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