Changeset 110935 in webkit
- Timestamp:
- Mar 15, 2012 8:20:26 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r110934 r110935 1 2012-03-15 Shinya Kawanaka <shinyak@chromium.org> 2 3 [Crash] Adding <content> into a ShadowRoot causes crash. 4 https://bugs.webkit.org/show_bug.cgi?id=80020 5 6 Reviewed by Hajime Morita. 7 8 * fast/dom/shadow/shadow-content-crash-expected.html: Added. 9 * fast/dom/shadow/shadow-content-crash.html: Added. 10 1 11 2012-03-15 Mike Lawther <mikelawther@chromium.org> 2 12 -
trunk/Source/WebCore/ChangeLog
r110934 r110935 1 2012-03-15 Shinya Kawanaka <shinyak@chromium.org> 2 3 [Crash] Adding <content> into a ShadowRoot causes crash. 4 https://bugs.webkit.org/show_bug.cgi?id=80020 5 6 Reviewed by Hajime Morita. 7 8 The problem is <content> tries to select host children though it is not prepared. 9 Since populating host children for insertion points is performed just before 10 attaching a shadow tree, we should recalculate whole shadow tree if <content> is 11 appended as a child. 12 13 However, element->appendChild() does not know the element is in a shadow tree or not. 14 We have to ensure reattaching whole shadow tree here. 15 16 So this patch adds some phases to HTMLContentSelector so that we can check node 17 distribution algorihm is begin processed or not. If not we cannot select anything, 18 but we have to enable a flag to reattach whole shadow tree. 19 20 Tests: fast/dom/shadow/shadow-content-crash-expected.html 21 fast/dom/shadow/shadow-content-crash.html 22 23 * dom/ShadowTree.cpp: 24 (WebCore::ShadowTree::attach): 25 (WebCore::ShadowTree::insertionPointFor): 26 * dom/ShadowTree.h: 27 (WebCore): 28 (ShadowTree): 29 (WebCore::ShadowTree::selector): 30 * html/shadow/HTMLContentSelector.cpp: 31 (WebCore::HTMLContentSelector::HTMLContentSelector): 32 (WebCore::HTMLContentSelector::select): 33 (WebCore::HTMLContentSelector::willSelect): 34 (WebCore): 35 (WebCore::HTMLContentSelector::didSelect): 36 (WebCore::HTMLContentSelector::populateIfNecessary): 37 * html/shadow/HTMLContentSelector.h: 38 (HTMLContentSelector): 39 (WebCore::HTMLContentSelector::isSelecting): 40 (WebCore): 41 (WebCore::HTMLContentSelector::hasPopulated): 42 * html/shadow/InsertionPoint.cpp: 43 (WebCore::InsertionPoint::distributeHostChildren): 44 (WebCore::InsertionPoint::clearDistribution): 45 1 46 2012-03-15 Mike Lawther <mikelawther@chromium.org> 2 47 -
trunk/Source/WebCore/dom/ShadowTree.cpp
r110374 r110935 31 31 #include "Document.h" 32 32 #include "Element.h" 33 #include "HTMLContentSelector.h"34 33 #include "HTMLShadowElement.h" 35 34 #include "InspectorInstrumentation.h" … … 179 178 // Children of m_selector is populated lazily in 180 179 // ensureSelector(), and here we just ensure that it is in clean state. 181 ASSERT(!selector() || !selector()->hasCandidates()); 182 180 ASSERT(!selector().hasPopulated()); 181 182 selector().willSelect(); 183 183 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) { 184 184 if (!root->attached()) 185 185 root->attach(); 186 186 } 187 188 if (HTMLContentSelector* contentSelector = selector()) 189 contentSelector->didSelect(); 187 selector().didSelect(); 190 188 } 191 189 … … 223 221 } 224 222 225 if (!m_selector) 226 return 0; 227 HTMLContentSelection* found = m_selector->findFor(node); 223 HTMLContentSelection* found = selector().findFor(node); 228 224 if (!found) 229 225 return 0; … … 318 314 } 319 315 320 HTMLContentSelector* ShadowTree::ensureSelector()321 {322 if (!m_selector)323 m_selector = adoptPtr(new HTMLContentSelector());324 m_selector->willSelectOver(host());325 return m_selector.get();326 }327 328 316 } // namespace -
trunk/Source/WebCore/dom/ShadowTree.h
r110161 r110935 29 29 30 30 #include "ExceptionCode.h" 31 #include "HTMLContentSelector.h" 31 32 #include "ShadowRoot.h" 32 33 #include <wtf/DoublyLinkedList.h> … … 39 40 class Node; 40 41 class Element; 41 class HTMLContentSelector;42 42 class InsertionPoint; 43 43 class TreeScope; … … 47 47 ShadowTree(); 48 48 ~ShadowTree(); 49 50 Element* host() const; 49 51 50 52 bool hasShadowRoot() const; … … 80 82 InsertionPoint* insertionPointFor(Node*) const; 81 83 82 HTMLContentSelector * selector() const;83 HTMLContentSelector* ensureSelector();84 HTMLContentSelector& selector(); 85 const HTMLContentSelector& selector() const; 84 86 85 87 private: 86 Element* host() const;87 88 88 89 DoublyLinkedList<ShadowRoot> m_shadowRoots; 89 OwnPtr<HTMLContentSelector>m_selector;90 HTMLContentSelector m_selector; 90 91 bool m_needsRecalculateContent : 1; 91 92 WTF_MAKE_NONCOPYABLE(ShadowTree); … … 107 108 } 108 109 109 inline HTMLContentSelector * ShadowTree::selector() const110 inline HTMLContentSelector& ShadowTree::selector() 110 111 { 111 return m_selector.get(); 112 return m_selector; 113 } 114 115 inline const HTMLContentSelector& ShadowTree::selector() const 116 { 117 return m_selector; 112 118 } 113 119 -
trunk/Source/WebCore/html/shadow/HTMLContentSelector.cpp
r109313 r110935 101 101 102 102 HTMLContentSelector::HTMLContentSelector() 103 : m_phase(SelectionPrevented) 103 104 { 104 105 } … … 111 112 void HTMLContentSelector::select(InsertionPoint* insertionPoint, HTMLContentSelectionList* selections) 112 113 { 114 ASSERT(m_phase == HostChildrenPopulated); 113 115 ASSERT(selections->isEmpty()); 114 116 … … 142 144 } 143 145 146 void HTMLContentSelector::willSelect() 147 { 148 m_phase = SelectionStarted; 149 } 150 144 151 void HTMLContentSelector::didSelect() 145 152 { 153 ASSERT(m_phase != SelectionPrevented); 154 m_phase = SelectionPrevented; 146 155 m_candidates.clear(); 147 156 } 148 157 149 void HTMLContentSelector:: willSelectOver(Element* shadowHost)158 void HTMLContentSelector::populateIfNecessary(Element* shadowHost) 150 159 { 151 if ( !m_candidates.isEmpty())160 if (hasPopulated()) 152 161 return; 162 163 ASSERT(m_candidates.isEmpty()); 153 164 ASSERT(shadowHost); 165 ASSERT(m_phase == SelectionStarted); 166 167 m_phase = HostChildrenPopulated; 154 168 for (Node* node = shadowHost->firstChild(); node; node = node->nextSibling()) 155 169 m_candidates.append(node); -
trunk/Source/WebCore/html/shadow/HTMLContentSelector.h
r109313 r110935 135 135 HTMLContentSelection* findFor(Node* key) const; 136 136 137 void willSelectOver(Element* shadowHost); 137 void willSelect(); 138 bool isSelecting() const; 138 139 void didSelect(); 139 bool hasCandidates() const { return !m_candidates.isEmpty(); } 140 141 void populateIfNecessary(Element* shadowHost); 142 bool hasPopulated() const; 140 143 141 144 private: 145 enum SelectingPhase { 146 SelectionPrevented, 147 SelectionStarted, 148 HostChildrenPopulated, 149 }; 150 142 151 void removeFromSet(HTMLContentSelectionList*); 143 152 void addToSet(HTMLContentSelectionList*); … … 145 154 Vector<RefPtr<Node> > m_candidates; 146 155 HTMLContentSelectionSet m_selectionSet; 156 SelectingPhase m_phase; 147 157 }; 158 159 inline bool HTMLContentSelector::isSelecting() const 160 { 161 return m_phase != SelectionPrevented; 162 } 163 164 inline bool HTMLContentSelector::hasPopulated() const 165 { 166 return m_phase == HostChildrenPopulated; 167 } 148 168 149 169 } -
trunk/Source/WebCore/html/shadow/InsertionPoint.cpp
r110161 r110935 110 110 inline void InsertionPoint::distributeHostChildren(ShadowTree* tree) 111 111 { 112 HTMLContentSelector* selector = tree->ensureSelector(); 113 selector->unselect(&m_selections); 114 selector->select(this, &m_selections); 112 if (!tree->selector().isSelecting()) { 113 // If HTMLContentSelector is not int selecting phase, it means InsertionPoint is attached from 114 // non-ShadowTree node. To run distribute algorithm, we have to reattach ShadowTree. 115 tree->setNeedsReattachHostChildrenAndShadow(); 116 return; 117 } 118 119 tree->selector().populateIfNecessary(tree->host()); 120 tree->selector().unselect(&m_selections); 121 tree->selector().select(this, &m_selections); 115 122 } 116 123 117 124 inline void InsertionPoint::clearDistribution(ShadowTree* tree) 118 125 { 119 if (HTMLContentSelector* selector = tree->selector()) 120 selector->unselect(&m_selections); 126 tree->selector().unselect(&m_selections); 121 127 } 122 128
Note: See TracChangeset
for help on using the changeset viewer.