Source/WebCore/dom/Document.cpp

@@uint64_t Document::s_globalTreeVersion = 0;
428428
429429Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
430430 : ContainerNode(0, CreateDocument)
431  , TreeScope(this)
 431 , TreeScope(this, this)
432432 , m_guardRefCount(0)
433433 , m_contextFeatures(ContextFeatures::defaultSwitch())
434434 , m_compatibilityMode(NoQuirksMode)

@@Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML)
499499 , m_didDispatchViewportPropertiesChanged(false)
500500#endif
501501{
502  m_document = this;
 502 setTreeScope(this);
 503 setRootDocument(this);
503504
504505 m_pageGroupUserSheetCacheValid = false;
505506

@@Document::~Document()
606607 // if the DocumentParser outlives the Document it won't cause badness.
607608 ASSERT(!m_parser || m_parser->refCount() == 1);
608609 detachParser();
609  m_document = 0;
 610 m_treeScope = 0;
610611
611612 m_renderArena.clear();
612613

@@void Document::setContent(const String& content)
13411342
13421343String Document::suggestedMIMEType() const
13431344{
1344  if (m_document->isXHTMLDocument())
 1345 Document* doc = document();
 1346 if (doc->isXHTMLDocument())
13451347 return "application/xhtml+xml";
1346  if (m_document->isSVGDocument())
 1348 if (doc->isSVGDocument())
13471349 return "image/svg+xml";
1348  if (m_document->xmlStandalone())
 1350 if (doc->xmlStandalone())
13491351 return "text/xml";
1350  if (m_document->isHTMLDocument())
 1352 if (doc->isHTMLDocument())
13511353 return "text/html";
13521354
13531355 if (DocumentLoader* documentLoader = loader())

Source/WebCore/dom/Document.h

@@private:
15011501
15021502// Put these methods here, because they require the Document definition, but we really want to inline them.
15031503
 1504inline Document* Node::documentInternal() const
 1505{
 1506 if (!m_treeScope)
 1507 return 0;
 1508 return m_treeScope->rootDocument();
 1509}
 1510
 1511inline Document* Node::document() const
 1512{
 1513 Document* document = documentInternal();
 1514 // FIXME: below ASSERT is useful, but prevents the use of document() in the constructor or destructor
 1515 // due to the virtual function call to nodeType().
 1516 ASSERT(document || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
 1517 return document;
 1518}
 1519
15041520inline bool Node::isDocumentNode() const
15051521{
1506  return this == m_document;
 1522 return this == documentInternal();
15071523}
15081524
15091525inline Node::Node(Document* document, ConstructionType type)
15101526 : m_nodeFlags(type)
1511  , m_document(document)
 1527 , m_treeScope(document)
15121528 , m_previous(0)
15131529 , m_next(0)
15141530 , m_renderer(0)

Source/WebCore/dom/Node.cpp

@@Node::~Node()
406406 if (renderer())
407407 detach();
408408
409  Document* doc = m_document;
 409 Document* doc = documentInternal();
410410 if (AXObjectCache::accessibilityEnabled() && doc && doc->axObjectCacheExists())
411411 doc->axObjectCache()->removeNodeForUse(this);
412412

@@Node::~Node()
421421 InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
422422}
423423
424 void Node::setDocument(Document* document)
 424void Node::setTreeScope(TreeScope* scope)
425425{
426  ASSERT(!inDocument() || m_document == document);
427  if (inDocument() || m_document == document)
428  return;
429 
430  m_document = document;
431 }
432 
433 NodeRareData* Node::setTreeScope(TreeScope* scope)
434 {
435  if (!scope) {
436  if (hasRareData()) {
437  NodeRareData* data = rareData();
438  data->setTreeScope(0);
439  return data;
440  }
441 
442  return 0;
443  }
444 
445  NodeRareData* data = ensureRareData();
446  data->setTreeScope(scope);
447  return data;
 426 m_treeScope = scope;
448427}
449428
450429TreeScope* Node::treeScope() const
451430{
452  // FIXME: Using m_document directly is not good -> see comment with document() in the header file.
453  if (!hasRareData())
454  return m_document;
455  TreeScope* scope = rareData()->treeScope();
456  return scope ? scope : m_document;
 431 return m_treeScope;
457432}
458433
459434NodeRareData* Node::rareData() const

@@void Node::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
28052780 memoryObjectInfo->reportObjectInfo(this, MemoryInstrumentation::DOM);
28062781 TreeShared<Node, ContainerNode>::reportMemoryUsage(memoryObjectInfo);
28072782 ScriptWrappable::reportMemoryUsage(memoryObjectInfo);
2808  memoryObjectInfo->reportPointer(m_document, MemoryInstrumentation::DOM);
 2783 memoryObjectInfo->reportPointer(document(), MemoryInstrumentation::DOM);
28092784 memoryObjectInfo->reportInstrumentedPointer(m_next);
28102785 memoryObjectInfo->reportInstrumentedPointer(m_previous);
28112786}

Source/WebCore/dom/Node.h

@@public:
407407
408408 // Returns the document associated with this node. This method never returns NULL, except in the case
409409 // of a DocumentType node that is not used with any Document yet. A Document node returns itself.
410  Document* document() const
411  {
412  ASSERT(this);
413  // FIXME: below ASSERT is useful, but prevents the use of document() in the constructor or destructor
414  // due to the virtual function call to nodeType().
415  ASSERT(m_document || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
416  return m_document;
417  }
 410 Document* document() const;
418411
419412 TreeScope* treeScope() const;
420413

@@public:
422415 // node tree, false otherwise.
423416 bool inDocument() const
424417 {
425  ASSERT(m_document || !getFlag(InDocumentFlag));
 418 ASSERT(m_treeScope || !getFlag(InDocumentFlag));
426419 return getFlag(InDocumentFlag);
427420 }
428421

@@protected:
733726
734727 void setHasCustomCallbacks() { setFlag(true, HasCustomCallbacksFlag); }
735728
 729 void setTreeScope(TreeScope*);
 730 Document* documentInternal() const;
 731
736732private:
737733 friend class TreeShared<Node, ContainerNode>;
738734
739735 void removedLastRef();
740736
741  // These API should be only used for a tree scope migration.
742  // setTreeScope() returns NodeRareData to save extra nodeRareData() invocations on the caller site.
743  NodeRareData* setTreeScope(TreeScope*);
744  void setDocument(Document*);
745 
746737 enum EditableLevel { Editable, RichlyEditable };
747738 bool rendererIsEditable(EditableLevel) const;
748739 bool isEditableToAccessibility(EditableLevel) const;

@@private:
785776#endif
786777
787778 mutable uint32_t m_nodeFlags;
788  Document* m_document;
 779 TreeScope* m_treeScope;
789780 Node* m_previous;
790781 Node* m_next;
791782 RenderObject* m_renderer;

Source/WebCore/dom/NodeRareData.h

@@class NodeRareData {
180180 WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED;
181181public:
182182 NodeRareData()
183  : m_treeScope(0)
184  , m_childNodeList(0)
 183 : m_childNodeList(0)
185184 , m_tabIndex(0)
186185 , m_tabIndexWasSetExplicitly(false)
187186 , m_isFocused(false)

@@public:
209208 return rareDataMap().get(node);
210209 }
211210
212  TreeScope* treeScope() const { return m_treeScope; }
213  void setTreeScope(TreeScope* treeScope) { m_treeScope = treeScope; }
214 
215211 void clearNodeLists() { m_nodeLists.clear(); }
216212 void setNodeLists(PassOwnPtr<NodeListsNodeData> lists) { m_nodeLists = lists; }
217213 NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); }

@@protected:
350346private:
351347 void createNodeLists(Node*);
352348
353  TreeScope* m_treeScope;
354349 OwnPtr<NodeListsNodeData> m_nodeLists;
355350 ChildNodeList* m_childNodeList;
356351 OwnPtr<EventTargetData> m_eventTargetData;

Source/WebCore/dom/ShadowRoot.cpp

@@namespace WebCore {
4646
4747ShadowRoot::ShadowRoot(Document* document)
4848 : DocumentFragment(document, CreateShadowRoot)
49  , TreeScope(this)
 49 , TreeScope(this, document)
5050 , m_prev(0)
5151 , m_next(0)
5252 , m_applyAuthorStyles(false)

@@ShadowRoot::ShadowRoot(Document* document)
5959 setParentTreeScope(document);
6060 // Shadow tree scopes have the scope pointer point to themselves.
6161 // This way, direct children will receive the correct scope pointer.
62  ensureRareData()->setTreeScope(this);
 62 setTreeScope(this);
6363}
6464
6565ShadowRoot::~ShadowRoot()

Source/WebCore/dom/TreeScope.cpp

@@namespace WebCore {
5151
5252using namespace HTMLNames;
5353
54 TreeScope::TreeScope(ContainerNode* rootNode)
 54TreeScope::TreeScope(ContainerNode* rootNode, Document* rootDocument)
5555 : m_rootNode(rootNode)
 56 , m_rootDocument(rootDocument)
5657 , m_parentTreeScope(0)
5758 , m_numNodeListCaches(0)
5859{

@@void TreeScope::setParentTreeScope(TreeScope* newParentScope)
8182 ASSERT(newParentScope);
8283
8384 m_parentTreeScope = newParentScope;
 85 m_rootDocument = newParentScope->rootDocument();
8486}
8587
8688Element* TreeScope::getElementById(const AtomicString& elementId) const

Source/WebCore/dom/TreeScope.h

@@namespace WebCore {
3434
3535class ContainerNode;
3636class DOMSelection;
 37class Document;
3738class Element;
3839class HTMLMapElement;
3940class Node;

@@public:
8182 void adoptIfNeeded(Node*);
8283
8384 ContainerNode* rootNode() const { return m_rootNode; }
 85 Document* rootDocument() const { return m_rootDocument; }
 86 void setRootDocument(Document* document) { m_rootDocument = document; }
8487
8588protected:
86  TreeScope(ContainerNode*);
 89 TreeScope(ContainerNode*, Document*);
8790 virtual ~TreeScope();
8891
8992 void destroyTreeScopeData();
9093
9194private:
9295 ContainerNode* m_rootNode;
 96 Document* m_rootDocument;
9397 TreeScope* m_parentTreeScope;
9498
9599 DocumentOrderedMap m_elementsById;

Source/WebCore/dom/TreeScopeAdopter.cpp

@@void TreeScopeAdopter::moveTreeToNewScope(Node* root) const
4747 oldDocument->incDOMTreeVersion();
4848
4949 for (Node* node = root; node; node = node->traverseNextNode(root)) {
50  NodeRareData* rareData = node->setTreeScope(newDocument == m_newScope ? 0 : m_newScope);
 50 node->setTreeScope(m_newScope);
 51 NodeRareData* rareData = node->hasRareData() ? node->rareData() : 0;
5152 if (rareData && rareData->nodeLists())
5253 rareData->nodeLists()->adoptTreeScope(m_oldScope, m_newScope, oldDocument, newDocument);
5354

@@inline void TreeScopeAdopter::moveNodeToNewDocument(Node* node, Document* oldDoc
9192 if (oldDocument)
9293 oldDocument->moveNodeIteratorsToNewDocument(node, newDocument);
9394
94  node->setDocument(newDocument);
95 
9695#ifndef NDEBUG
9796 didMoveToNewDocumentWasCalled = false;
9897 oldDocumentDidMoveToNewDocumentWasCalledWith = oldDocument;