Changeset 91453 in webkit
- Timestamp:
- Jul 21, 2011 2:39:37 AM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r91452 r91453 1 2011-07-21 MORITA Hajime <morrita@google.com> 2 3 [Refactoring] Shadow inclusion cache should be managed by ShadowContentSelector 4 https://bugs.webkit.org/show_bug.cgi?id=64849 5 6 Reviewed by Dimitri Glazkov. 7 8 This change is a reorg around Shadow inclusion mechanism. 9 - Moved definition of ShadowInclusion, ShadowInclusionSet and ShadowInclusionList 10 from ShadowContentElement.h to ShadowContentSelector.h, which is included 11 from smaller number of places. 12 - Moved ShadowInclusionSet from ShadowRoot to ShadowContentSelector 13 - Made ShadowContentSelector's lifetime managed by ShadowRoot 14 because ShadowInclusionSet is held by the selector. 15 - Thus, there is no longer "active" selector (ShadowContentSelector::s_currentInstance) 16 Because the selector is associated for each ShadowRoot object. 17 18 No new tests. No behavior change. 19 20 * dom/NodeRenderingContext.cpp: 21 * dom/ShadowContentElement.cpp: 22 (WebCore::ShadowContentElement::ShadowContentElement): 23 (WebCore::ShadowContentElement::attach): 24 (WebCore::ShadowContentElement::detach): 25 * dom/ShadowContentElement.h: 26 (WebCore::ShadowContentElement::inclusions): 27 * dom/ShadowContentSelector.cpp: 28 (WebCore::ShadowInclusion::append): 29 (WebCore::ShadowInclusion::unlink): 30 (WebCore::ShadowInclusionList::ShadowInclusionList): 31 (WebCore::ShadowInclusionList::~ShadowInclusionList): 32 (WebCore::ShadowInclusionList::find): 33 (WebCore::ShadowInclusionList::clear): 34 (WebCore::ShadowInclusionList::append): 35 (WebCore::ShadowContentSelector::ShadowContentSelector): 36 (WebCore::ShadowContentSelector::~ShadowContentSelector): 37 (WebCore::ShadowContentSelector::selectInclusion): 38 (WebCore::ShadowContentSelector::unselectInclusion): 39 (WebCore::ShadowContentSelector::findInclusionFor): 40 (WebCore::ShadowContentSelector::didSelectInclusion): 41 (WebCore::ShadowContentSelector::willSelectInclusionOver): 42 * dom/ShadowContentSelector.h: 43 (WebCore::ShadowInclusion::includer): 44 (WebCore::ShadowInclusion::content): 45 (WebCore::ShadowInclusion::next): 46 (WebCore::ShadowInclusion::previous): 47 (WebCore::ShadowInclusion::ShadowInclusion): 48 (WebCore::ShadowInclusion::create): 49 (WebCore::ShadowInclusionList::first): 50 (WebCore::ShadowInclusionList::last): 51 (WebCore::ShadowInclusionList::isEmpty): 52 (WebCore::ShadowInclusionSet::add): 53 (WebCore::ShadowInclusionSet::remove): 54 (WebCore::ShadowInclusionSet::isEmpty): 55 (WebCore::ShadowInclusionSet::Translator::hash): 56 (WebCore::ShadowInclusionSet::Translator::equal): 57 (WebCore::ShadowInclusionSet::Hash::hash): 58 (WebCore::ShadowInclusionSet::Hash::equal): 59 (WebCore::ShadowInclusionSet::find): 60 (WebCore::ShadowContentSelector::hasChildren): 61 * dom/ShadowRoot.cpp: 62 (WebCore::ShadowRoot::~ShadowRoot): 63 (WebCore::ShadowRoot::includerFor): 64 (WebCore::ShadowRoot::attach): 65 (WebCore::ShadowRoot::inclusions): 66 (WebCore::ShadowRoot::ensureInclusions): 67 * dom/ShadowRoot.h: 68 1 69 2011-07-21 Rohan McGovern <rohan@mcgovern.id.au> 2 70 -
trunk/Source/WebCore/dom/NodeRenderingContext.cpp
r91235 r91453 32 32 #include "RenderObject.h" 33 33 #include "ShadowContentElement.h" 34 #include "ShadowContentSelector.h" 34 35 #include "ShadowRoot.h" 35 36 -
trunk/Source/WebCore/dom/ShadowContentElement.cpp
r91235 r91453 34 34 namespace WebCore { 35 35 36 void ShadowInclusion::append(PassRefPtr<ShadowInclusion> next)37 {38 ASSERT(!m_next);39 ASSERT(!next->previous());40 m_next = next;41 m_next->m_previous = this;42 }43 44 void ShadowInclusion::unlink()45 {46 ASSERT(!m_previous); // Can be called only for a head.47 RefPtr<ShadowInclusion> item = this;48 while (item) {49 ASSERT(!item->previous());50 RefPtr<ShadowInclusion> nextItem = item->m_next;51 item->m_next.clear();52 if (nextItem)53 nextItem->m_previous.clear();54 item = nextItem;55 }56 }57 58 ShadowInclusionList::ShadowInclusionList()59 {60 }61 62 ShadowInclusionList::~ShadowInclusionList()63 {64 ASSERT(isEmpty());65 }66 67 ShadowInclusion* ShadowInclusionList::find(Node* content) const68 {69 for (ShadowInclusion* item = first(); item; item = item->next()) {70 if (content == item->content())71 return item;72 }73 74 return 0;75 }76 77 void ShadowInclusionList::clear()78 {79 if (isEmpty()) {80 ASSERT(!m_last);81 return;82 }83 84 m_first->unlink();85 m_first.clear();86 m_last.clear();87 }88 89 void ShadowInclusionList::append(PassRefPtr<ShadowInclusion> child)90 {91 if (isEmpty()) {92 ASSERT(!m_last);93 m_first = m_last = child;94 return;95 }96 97 m_last->append(child);98 m_last = m_last->next();99 }100 101 36 PassRefPtr<ShadowContentElement> ShadowContentElement::create(Document* document) 102 37 { … … 107 42 ShadowContentElement::ShadowContentElement(const QualifiedName& name, Document* document) 108 43 : StyledElement(name, document, CreateHTMLElement) 44 , m_inclusions(adoptPtr(new ShadowInclusionList())) 109 45 { 110 46 } … … 114 50 } 115 51 116 static void removeFromSet(ShadowInclusionList* list, ShadowInclusionSet* set)117 {118 for (ShadowInclusion* inclusion = list->first(); inclusion; inclusion = inclusion->next())119 set->remove(inclusion);120 }121 122 static void addToSet(ShadowInclusionList* list, ShadowInclusionSet* set)123 {124 for (ShadowInclusion* inclusion = list->first(); inclusion; inclusion = inclusion->next())125 set->add(inclusion);126 }127 128 52 void ShadowContentElement::attach() 129 53 { 130 54 ASSERT(!firstChild()); // Currently doesn't support any light child. 131 55 StyledElement::attach(); 132 if (ShadowContentSelector* selector = ShadowContentSelector::currentInstance()) {133 56 134 removeFromSet(&m_inclusions, selector->shadowRoot()->ensureInclusions()); 135 m_inclusions.clear(); 136 selector->selectInclusion(this, &m_inclusions); 137 addToSet(&m_inclusions, selector->shadowRoot()->ensureInclusions()); 138 139 for (ShadowInclusion* inclusion = m_inclusions.first(); inclusion; inclusion = inclusion->next()) 57 if (ShadowRoot* root = toShadowRoot(shadowTreeRootNode())) { 58 ShadowContentSelector* selector = root->ensureInclusions(); 59 selector->unselectInclusion(m_inclusions.get()); 60 selector->selectInclusion(this, m_inclusions.get()); 61 for (ShadowInclusion* inclusion = m_inclusions->first(); inclusion; inclusion = inclusion->next()) 140 62 inclusion->content()->detach(); 141 for (ShadowInclusion* inclusion = m_inclusions .first(); inclusion; inclusion = inclusion->next())63 for (ShadowInclusion* inclusion = m_inclusions->first(); inclusion; inclusion = inclusion->next()) 142 64 inclusion->content()->attach(); 143 65 } … … 147 69 { 148 70 if (ShadowRoot* root = toShadowRoot(shadowTreeRootNode())) { 149 removeFromSet(&m_inclusions, root->ensureInclusions());150 m_inclusions.clear();71 if (ShadowContentSelector* selector = root->inclusions()) 72 selector->unselectInclusion(m_inclusions.get()); 151 73 } 152 74 153 ASSERT(m_inclusions .isEmpty());75 ASSERT(m_inclusions->isEmpty()); 154 76 StyledElement::detach(); 155 77 } -
trunk/Source/WebCore/dom/ShadowContentElement.h
r91235 r91453 34 34 #include "StyledElement.h" 35 35 #include <wtf/Forward.h> 36 #include <wtf/HashSet.h>37 36 38 37 namespace WebCore { 39 38 40 class ShadowContentElement; 41 42 class ShadowInclusion : public RefCounted<ShadowInclusion> { 43 public: 44 static PassRefPtr<ShadowInclusion> create(ShadowContentElement*, Node*); 45 46 ShadowContentElement* includer() const { return m_includer; } 47 Node* content() const { return m_content.get(); } 48 ShadowInclusion* next() const { return m_next.get(); } 49 ShadowInclusion* previous() const { return m_previous.get(); } 50 51 void append(PassRefPtr<ShadowInclusion>); 52 void unlink(); 53 54 private: 55 explicit ShadowInclusion(ShadowContentElement* includer, Node* content) 56 : m_includer(includer), m_content(content) 57 { } 58 59 ShadowContentElement* m_includer; 60 RefPtr<Node> m_content; 61 RefPtr<ShadowInclusion> m_next; 62 RefPtr<ShadowInclusion> m_previous; 63 }; 64 65 inline PassRefPtr<ShadowInclusion> ShadowInclusion::create(ShadowContentElement* includer, Node* content) 66 { 67 return adoptRef(new ShadowInclusion(includer, content)); 68 } 69 70 class ShadowInclusionList { 71 public: 72 ShadowInclusionList(); 73 ~ShadowInclusionList(); 74 75 ShadowInclusion* first() const { return m_first.get(); } 76 ShadowInclusion* last() const { return m_last.get(); } 77 ShadowInclusion* find(Node*) const; 78 bool isEmpty() const { return !m_first; } 79 80 void clear(); 81 void append(PassRefPtr<ShadowInclusion>); 82 void append(ShadowContentElement*, Node*); 83 84 private: 85 RefPtr<ShadowInclusion> m_first; 86 RefPtr<ShadowInclusion> m_last; 87 }; 88 89 inline void ShadowInclusionList::append(ShadowContentElement* includer, Node* node) 90 { 91 append(ShadowInclusion::create(includer, node)); 92 } 93 94 class ShadowInclusionSet { 95 public: 96 void add(ShadowInclusion* value) { m_set.add(value); } 97 void remove(ShadowInclusion* value) { m_set.remove(value); } 98 bool isEmpty() const { return m_set.isEmpty(); } 99 ShadowInclusion* find(Node* key) const; 100 101 private: 102 struct Translator { 103 public: 104 static unsigned hash(const Node* key) { return PtrHash<const Node*>::hash(key); } 105 static bool equal(const ShadowInclusion* inclusion, const Node* content) { return inclusion->content() == content; } 106 }; 107 108 struct Hash { 109 static unsigned hash(ShadowInclusion* key) { return PtrHash<const Node*>::hash(key->content()); } 110 static bool equal(ShadowInclusion* a, ShadowInclusion* b) { return a->content() == b->content(); } 111 static const bool safeToCompareToEmptyOrDeleted = false; 112 }; 113 114 typedef HashSet<ShadowInclusion*, Hash> PointerSet; 115 116 PointerSet m_set; 117 }; 118 119 inline ShadowInclusion* ShadowInclusionSet::find(Node* key) const 120 { 121 PointerSet::iterator found = m_set.find<Node*, ShadowInclusionSet::Translator>(key); 122 return found != m_set.end() ? *found : 0; 123 } 39 class ShadowInclusionList; 124 40 125 41 // NOTE: Current implementation doesn't support dynamic insertion/deletion of ShadowContentElement. … … 134 50 virtual void detach(); 135 51 136 const ShadowInclusionList* inclusions() const { return &m_inclusions; }52 const ShadowInclusionList* inclusions() const { return m_inclusions.get(); } 137 53 138 54 protected: … … 144 60 virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) { return 0; } 145 61 146 ShadowInclusionListm_inclusions;62 OwnPtr<ShadowInclusionList> m_inclusions; 147 63 }; 148 64 -
trunk/Source/WebCore/dom/ShadowContentSelector.cpp
r91235 r91453 34 34 namespace WebCore { 35 35 36 ShadowContentSelector* ShadowContentSelector::s_currentInstance = 0; 36 void ShadowInclusion::append(PassRefPtr<ShadowInclusion> next) 37 { 38 ASSERT(!m_next); 39 ASSERT(!next->previous()); 40 m_next = next; 41 m_next->m_previous = this; 42 } 37 43 38 ShadowContentSelector::ShadowContentSelector(ShadowRoot* shadowRoot) 39 : m_parent(s_currentInstance) 40 , m_shadowRoot(shadowRoot) 44 void ShadowInclusion::unlink() 41 45 { 42 s_currentInstance = this; 43 for (Node* node = shadowRoot->shadowHost()->firstChild(); node; node = node->nextSibling()) 44 m_children.append(node); 46 ASSERT(!m_previous); // Can be called only for a head. 47 RefPtr<ShadowInclusion> item = this; 48 while (item) { 49 ASSERT(!item->previous()); 50 RefPtr<ShadowInclusion> nextItem = item->m_next; 51 item->m_next.clear(); 52 if (nextItem) 53 nextItem->m_previous.clear(); 54 item = nextItem; 55 } 56 } 57 58 ShadowInclusionList::ShadowInclusionList() 59 { 60 } 61 62 ShadowInclusionList::~ShadowInclusionList() 63 { 64 ASSERT(isEmpty()); 65 } 66 67 ShadowInclusion* ShadowInclusionList::find(Node* content) const 68 { 69 for (ShadowInclusion* item = first(); item; item = item->next()) { 70 if (content == item->content()) 71 return item; 72 } 73 74 return 0; 75 } 76 77 void ShadowInclusionList::clear() 78 { 79 if (isEmpty()) { 80 ASSERT(!m_last); 81 return; 82 } 83 84 m_first->unlink(); 85 m_first.clear(); 86 m_last.clear(); 87 } 88 89 void ShadowInclusionList::append(PassRefPtr<ShadowInclusion> child) 90 { 91 if (isEmpty()) { 92 ASSERT(!m_last); 93 m_first = m_last = child; 94 return; 95 } 96 97 m_last->append(child); 98 m_last = m_last->next(); 99 } 100 101 ShadowContentSelector::ShadowContentSelector() 102 { 45 103 } 46 104 47 105 ShadowContentSelector::~ShadowContentSelector() 48 106 { 49 ASSERT(s_currentInstance == this); 50 s_currentInstance = m_parent; 107 ASSERT(m_children.isEmpty()); 51 108 } 52 109 … … 62 119 continue; 63 120 64 inclusions->append(contentElement, child); 121 RefPtr<ShadowInclusion> inclusion = ShadowInclusion::create(contentElement, child); 122 inclusions->append(inclusion); 123 m_inclusionSet.add(inclusion.get()); 65 124 m_children[i] = 0; 66 125 } 67 126 } 68 127 128 void ShadowContentSelector::unselectInclusion(ShadowInclusionList* list) 129 { 130 for (ShadowInclusion* inclusion = list->first(); inclusion; inclusion = inclusion->next()) 131 m_inclusionSet.remove(inclusion); 132 list->clear(); 69 133 } 134 135 ShadowInclusion* ShadowContentSelector::findInclusionFor(Node* key) const 136 { 137 return m_inclusionSet.find(key); 138 } 139 140 void ShadowContentSelector::didSelectInclusion() 141 { 142 m_children.clear(); 143 } 144 145 void ShadowContentSelector::willSelectInclusionOver(ShadowRoot* scope) 146 { 147 if (!m_children.isEmpty()) 148 return; 149 for (Node* node = scope->shadowHost()->firstChild(); node; node = node->nextSibling()) 150 m_children.append(node); 151 } 152 153 } -
trunk/Source/WebCore/dom/ShadowContentSelector.h
r91235 r91453 33 33 34 34 #include <wtf/Forward.h> 35 #include <wtf/HashSet.h> 36 #include <wtf/RefCounted.h> 35 37 #include <wtf/Vector.h> 36 38 … … 40 42 class Node; 41 43 class ShadowRoot; 42 class ShadowInclusionList;43 44 class ShadowContentElement; 44 class RenderObject; 45 46 class ShadowInclusion : public RefCounted<ShadowInclusion> { 47 public: 48 static PassRefPtr<ShadowInclusion> create(ShadowContentElement*, Node*); 49 50 ShadowContentElement* includer() const { return m_includer; } 51 Node* content() const { return m_content.get(); } 52 ShadowInclusion* next() const { return m_next.get(); } 53 ShadowInclusion* previous() const { return m_previous.get(); } 54 55 void append(PassRefPtr<ShadowInclusion>); 56 void unlink(); 57 58 private: 59 ShadowInclusion(ShadowContentElement*, Node*); 60 61 ShadowContentElement* m_includer; 62 RefPtr<Node> m_content; 63 RefPtr<ShadowInclusion> m_next; 64 RefPtr<ShadowInclusion> m_previous; 65 }; 66 67 inline ShadowInclusion::ShadowInclusion(ShadowContentElement* includer, Node* content) 68 : m_includer(includer), m_content(content) 69 { } 70 71 inline PassRefPtr<ShadowInclusion> ShadowInclusion::create(ShadowContentElement* includer, Node* content) 72 { 73 return adoptRef(new ShadowInclusion(includer, content)); 74 } 75 76 class ShadowInclusionList { 77 public: 78 ShadowInclusionList(); 79 ~ShadowInclusionList(); 80 81 ShadowInclusion* first() const { return m_first.get(); } 82 ShadowInclusion* last() const { return m_last.get(); } 83 ShadowInclusion* find(Node*) const; 84 bool isEmpty() const { return !m_first; } 85 86 void clear(); 87 void append(PassRefPtr<ShadowInclusion>); 88 89 private: 90 RefPtr<ShadowInclusion> m_first; 91 RefPtr<ShadowInclusion> m_last; 92 }; 93 94 95 class ShadowInclusionSet { 96 public: 97 void add(ShadowInclusion* value) { m_set.add(value); } 98 void remove(ShadowInclusion* value) { m_set.remove(value); } 99 bool isEmpty() const { return m_set.isEmpty(); } 100 ShadowInclusion* find(Node* key) const; 101 102 private: 103 struct Translator { 104 public: 105 static unsigned hash(const Node* key) { return PtrHash<const Node*>::hash(key); } 106 static bool equal(const ShadowInclusion* inclusion, const Node* content) { return inclusion->content() == content; } 107 }; 108 109 struct Hash { 110 static unsigned hash(ShadowInclusion* key) { return PtrHash<const Node*>::hash(key->content()); } 111 static bool equal(ShadowInclusion* a, ShadowInclusion* b) { return a->content() == b->content(); } 112 static const bool safeToCompareToEmptyOrDeleted = false; 113 }; 114 115 typedef HashSet<ShadowInclusion*, Hash> PointerSet; 116 117 PointerSet m_set; 118 }; 119 120 inline ShadowInclusion* ShadowInclusionSet::find(Node* key) const 121 { 122 PointerSet::iterator found = m_set.find<Node*, ShadowInclusionSet::Translator>(key); 123 return found != m_set.end() ? *found : 0; 124 } 45 125 46 126 class ShadowContentSelector { 47 127 WTF_MAKE_NONCOPYABLE(ShadowContentSelector); 48 128 public: 49 explicit ShadowContentSelector(ShadowRoot*);129 ShadowContentSelector(); 50 130 ~ShadowContentSelector(); 51 131 52 132 void selectInclusion(ShadowContentElement*, ShadowInclusionList*); 133 void unselectInclusion(ShadowInclusionList*); 134 ShadowInclusion* findInclusionFor(Node* key) const; 53 135 54 ShadowRoot* shadowRoot() const { return m_shadowRoot; } 55 static ShadowContentSelector* currentInstance() { return s_currentInstance; } 136 void willSelectInclusionOver(ShadowRoot*); 137 void didSelectInclusion(); 138 bool hasChildren() const { return !m_children.isEmpty(); } 139 56 140 57 141 private: 58 ShadowContentSelector* m_parent; 59 ShadowRoot* m_shadowRoot; 142 void removeFromSet(ShadowInclusionList*); 143 void addToSet(ShadowInclusionList*); 144 60 145 Vector<RefPtr<Node> > m_children; 61 62 static ShadowContentSelector* s_currentInstance; 146 ShadowInclusionSet m_inclusionSet; 63 147 }; 64 148 -
trunk/Source/WebCore/dom/ShadowRoot.cpp
r91235 r91453 51 51 ShadowRoot::~ShadowRoot() 52 52 { 53 ASSERT(!m_inclusions || m_inclusions->isEmpty());54 53 } 55 54 … … 102 101 if (!m_inclusions) 103 102 return 0; 104 ShadowInclusion* found = m_inclusions->find (node);103 ShadowInclusion* found = m_inclusions->findInclusionFor(node); 105 104 if (!found) 106 105 return 0; … … 138 137 void ShadowRoot::attach() 139 138 { 140 ShadowContentSelector selector(this); 139 // Children of m_inclusions is populated lazily in 140 // ensureInclusions(), and here we just ensure that 141 // it is in clean state. 142 ASSERT(!m_inclusions || !m_inclusions->hasChildren()); 141 143 TreeScope::attach(); 144 if (m_inclusions) 145 m_inclusions->didSelectInclusion(); 142 146 } 143 147 144 Shadow InclusionSet* ShadowRoot::inclusions() const148 ShadowContentSelector* ShadowRoot::inclusions() const 145 149 { 146 150 return m_inclusions.get(); 147 151 } 148 152 149 Shadow InclusionSet* ShadowRoot::ensureInclusions()153 ShadowContentSelector* ShadowRoot::ensureInclusions() 150 154 { 151 155 if (!m_inclusions) 152 m_inclusions = adoptPtr(new ShadowInclusionSet()); 156 m_inclusions = adoptPtr(new ShadowContentSelector()); 157 m_inclusions->willSelectInclusionOver(this); 153 158 return m_inclusions.get(); 154 159 } -
trunk/Source/WebCore/dom/ShadowRoot.h
r91235 r91453 34 34 class Document; 35 35 class ShadowContentElement; 36 class Shadow InclusionSet;36 class ShadowContentSelector; 37 37 38 38 class ShadowRoot : public TreeScope { … … 50 50 void setApplyAuthorSheets(bool); 51 51 52 Shadow InclusionSet* inclusions() const;53 Shadow InclusionSet* ensureInclusions();52 ShadowContentSelector* inclusions() const; 53 ShadowContentSelector* ensureInclusions(); 54 54 55 55 private: … … 65 65 66 66 bool m_applyAuthorSheets; 67 OwnPtr<Shadow InclusionSet> m_inclusions;67 OwnPtr<ShadowContentSelector> m_inclusions; 68 68 }; 69 69
Note: See TracChangeset
for help on using the changeset viewer.