Changeset 87319 in webkit
- Timestamp:
- May 25, 2011 2:29:32 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 14 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r87318 r87319 1 2011-05-25 Kulanthaivel Palanichamy <kulanthaivel@codeaurora.org> 2 3 Reviewed by David Hyatt. 4 5 Selector matching doesn't update when DOM changes ("[data-a=x] #x") 6 https://bugs.webkit.org/show_bug.cgi?id=60752 7 8 Added test cases for all the attribute selector types (CSS2.1 & CSS3). 9 10 * fast/css/attribute-selector-begin-dynamic-no-elementstyle-expected.txt: Added. 11 * fast/css/attribute-selector-begin-dynamic-no-elementstyle.html: Added. 12 * fast/css/attribute-selector-contain-dynamic-no-elementstyle-expected.txt: Added. 13 * fast/css/attribute-selector-contain-dynamic-no-elementstyle.html: Added. 14 * fast/css/attribute-selector-end-dynamic-no-elementstyle-expected.txt: Added. 15 * fast/css/attribute-selector-end-dynamic-no-elementstyle.html: Added. 16 * fast/css/attribute-selector-exact-dynamic-no-elementstyle-expected.txt: Added. 17 * fast/css/attribute-selector-exact-dynamic-no-elementstyle.html: Added. 18 * fast/css/attribute-selector-hyphen-dynamic-no-elementstyle-expected.txt: Added. 19 * fast/css/attribute-selector-hyphen-dynamic-no-elementstyle.html: Added. 20 * fast/css/attribute-selector-list-dynamic-no-elementstyle-expected.txt: Added. 21 * fast/css/attribute-selector-list-dynamic-no-elementstyle.html: Added. 22 * fast/css/attribute-selector-set-dynamic-no-elementstyle-expected.txt: Added. 23 * fast/css/attribute-selector-set-dynamic-no-elementstyle.html: Added. 24 1 25 2011-05-25 Adam Klein <adamk@chromium.org> 2 26 -
trunk/Source/WebCore/ChangeLog
r87317 r87319 1 2011-05-25 Kulanthaivel Palanichamy <kulanthaivel@codeaurora.org> 2 3 Reviewed by David Hyatt. 4 5 Selector matching doesn't update when DOM changes ("[data-a=x] #x") 6 https://bugs.webkit.org/show_bug.cgi?id=60752 7 8 Currently CSSStyleSelector maintains a HashSet of attributes (m_selectorAttrs) 9 which are used in CSS attribute selectors to determine the need for style 10 recalculation whenever element attributes are manipulated in DOM. 11 In certain conditions (element with no style, element is styled and attribute 12 is not a mapped attribute, attribute is of type 'type' or read-only) 13 even when attribute selector matches for an element, the attribute is not 14 added to m_selectorAttrs. This results in missing style recalculations 15 when a DOM element attribute is changed and is not found in m_selectorAttrs. 16 17 Removing the above said conditions in 18 CSSStyleSelector::SelectorChecker::checkOneSelector() for registering 19 attributes in m_selectorAttrs will solve this issue. But this particular 20 function is called numerous times which triggers adding duplicate attributes 21 again and again. 22 23 This patch follows the approach taken for collecting ids in selectors, where 24 all the attributes in selectors are added to a HashSet at the time of adding 25 style rules to CSSStyleSelector from StyleSheets and when 26 CSSStyleSelector::hasSelectorForAttribute() is called, the attribute is 27 simply looked up in this pre-populated hash set. 28 29 Test: fast/css/attribute-selector-dynamic-no-elementstyle.html 30 31 * css/CSSStyleSelector.cpp: 32 (WebCore::CSSStyleSelector::SelectorChecker::checkSelector): 33 (WebCore::CSSStyleSelector::checkSelector): 34 (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): 35 (WebCore::collectFeaturesFromSelector): 36 (WebCore::CSSStyleSelector::applyProperty): 37 (WebCore::CSSStyleSelector::hasSelectorForAttribute): 38 * css/CSSStyleSelector.h: 39 1 40 2011-05-25 Ryosuke Niwa <rniwa@webkit.org> 2 41 -
trunk/Source/WebCore/css/CSSStyleSelector.cpp
r87317 r87319 962 962 { 963 963 PseudoId dynamicPseudo = NOPSEUDO; 964 return checkSelector(sel, element, 0,dynamicPseudo, false, false) == SelectorMatches;964 return checkSelector(sel, element, dynamicPseudo, false, false) == SelectorMatches; 965 965 } 966 966 … … 2052 2052 2053 2053 // Slow path. 2054 SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, &m_selectorAttrs,m_dynamicPseudo, false, false, style(), m_parentNode ? m_parentNode->renderStyle() : 0);2054 SelectorMatch match = m_checker.checkSelector(ruleData.selector(), m_element, m_dynamicPseudo, false, false, style(), m_parentNode ? m_parentNode->renderStyle() : 0); 2055 2055 if (match != SelectorMatches) 2056 2056 return false; … … 2181 2181 // * SelectorFailsLocally - the selector fails for the element e 2182 2182 // * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e 2183 CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs,PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const2183 CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const 2184 2184 { 2185 2185 #if ENABLE(SVG) … … 2191 2191 2192 2192 // first selector has to match 2193 if (!checkOneSelector(sel, e, selectorAttrs,dynamicPseudo, isSubSelector, encounteredLink, elementStyle, elementParentStyle))2193 if (!checkOneSelector(sel, e, dynamicPseudo, isSubSelector, encounteredLink, elementStyle, elementParentStyle)) 2194 2194 return SelectorFailsLocally; 2195 2195 … … 2225 2225 return SelectorFailsCompletely; 2226 2226 e = static_cast<Element*>(n); 2227 SelectorMatch match = checkSelector(sel, e, selectorAttrs,dynamicPseudo, false, encounteredLink);2227 SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink); 2228 2228 if (match != SelectorFailsLocally) 2229 2229 return match; … … 2236 2236 return SelectorFailsCompletely; 2237 2237 e = static_cast<Element*>(n); 2238 return checkSelector(sel, e, selectorAttrs,dynamicPseudo, false, encounteredLink);2238 return checkSelector(sel, e, dynamicPseudo, false, encounteredLink); 2239 2239 } 2240 2240 case CSSSelector::DirectAdjacent: … … 2252 2252 e = static_cast<Element*>(n); 2253 2253 m_matchVisitedPseudoClass = false; 2254 return checkSelector(sel, e, selectorAttrs, dynamicPseudo, false, encounteredLink);2254 return checkSelector(sel, e, dynamicPseudo, false, encounteredLink); 2255 2255 } 2256 2256 case CSSSelector::IndirectAdjacent: … … 2268 2268 e = static_cast<Element*>(n); 2269 2269 m_matchVisitedPseudoClass = false; 2270 SelectorMatch match = checkSelector(sel, e, selectorAttrs,dynamicPseudo, false, encounteredLink);2270 SelectorMatch match = checkSelector(sel, e, dynamicPseudo, false, encounteredLink); 2271 2271 if (match != SelectorFailsLocally) 2272 2272 return match; … … 2280 2280 !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass)) 2281 2281 return SelectorFailsCompletely; 2282 return checkSelector(sel, e, selectorAttrs,dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle);2282 return checkSelector(sel, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle); 2283 2283 case CSSSelector::ShadowDescendant: 2284 2284 { … … 2287 2287 return SelectorFailsCompletely; 2288 2288 e = static_cast<Element*>(shadowHostNode); 2289 return checkSelector(sel, e, selectorAttrs,dynamicPseudo, false, encounteredLink);2289 return checkSelector(sel, e, dynamicPseudo, false, encounteredLink); 2290 2290 } 2291 2291 } … … 2361 2361 } 2362 2362 2363 bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs,PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const2363 bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const 2364 2364 { 2365 2365 ASSERT(e); … … 2382 2382 if (elementStyle && (!e->isStyledElement() || (!static_cast<StyledElement*>(e)->isMappedAttribute(attr) && attr != typeAttr && attr != readonlyAttr))) { 2383 2383 elementStyle->setAffectedByAttributeSelectors(); // Special-case the "type" and "readonly" attributes so input form controls can share style. 2384 if (selectorAttrs)2385 selectorAttrs->add(attr.localName().impl());2386 2384 } 2387 2385 … … 2457 2455 ASSERT(subSel->pseudoType() != CSSSelector::PseudoNot); 2458 2456 2459 if (!checkOneSelector(subSel, e, selectorAttrs,dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle))2457 if (!checkOneSelector(subSel, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle)) 2460 2458 return true; 2461 2459 } … … 2766 2764 case CSSSelector::PseudoAny: 2767 2765 for (CSSSelector* selector = sel->selectorList()->first(); selector; selector = CSSSelectorList::next(selector)) { 2768 if (checkSelector(selector, e, selectorAttrs,dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle) == SelectorMatches)2766 if (checkSelector(selector, e, dynamicPseudo, true, encounteredLink, elementStyle, elementParentStyle) == SelectorMatches) 2769 2767 return true; 2770 2768 } … … 3235 3233 if (selector->m_match == CSSSelector::Id && !selector->value().isEmpty()) 3236 3234 features.idsInRules.add(selector->value().impl()); 3235 if (selector->hasAttribute()) { 3236 switch (selector->m_match) { 3237 case CSSSelector::Exact: 3238 case CSSSelector::Set: 3239 case CSSSelector::List: 3240 case CSSSelector::Hyphen: 3241 case CSSSelector::Contain: 3242 case CSSSelector::Begin: 3243 case CSSSelector::End: 3244 features.attrsInRules.add(selector->attribute().localName().impl()); 3245 break; 3246 default: 3247 break; 3248 } 3249 } 3237 3250 switch (selector->pseudoType()) { 3238 3251 case CSSSelector::PseudoFirstLine: … … 4223 4236 didSet = true; 4224 4237 // register the fact that the attribute value affects the style 4225 m_ selectorAttrs.add(attr.localName().impl());4238 m_features.attrsInRules.add(attr.localName().impl()); 4226 4239 break; 4227 4240 } … … 6522 6535 bool CSSStyleSelector::hasSelectorForAttribute(const AtomicString &attrname) const 6523 6536 { 6524 return m_ selectorAttrs.contains(attrname.impl());6537 return m_features.attrsInRules.contains(attrname.impl()); 6525 6538 } 6526 6539 -
trunk/Source/WebCore/css/CSSStyleSelector.h
r87317 r87319 192 192 ~Features(); 193 193 HashSet<AtomicStringImpl*> idsInRules; 194 HashSet<AtomicStringImpl*> attrsInRules; 194 195 OwnPtr<RuleSet> siblingRules; 195 196 bool usesFirstLineRules; … … 262 263 263 264 bool checkSelector(CSSSelector*, Element*) const; 264 SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs,PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;265 bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs,PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle*, RenderStyle* elementParentStyle) const;265 SelectorMatch checkSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const; 266 bool checkOneSelector(CSSSelector*, Element*, PseudoId& dynamicPseudo, bool isSubSelector, bool encounteredLink, RenderStyle*, RenderStyle* elementParentStyle) const; 266 267 bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const; 267 268 static bool fastCheckSelector(const CSSSelector*, const Element*); … … 360 361 361 362 RefPtr<CSSFontSelector> m_fontSelector; 362 HashSet<AtomicStringImpl*> m_selectorAttrs;363 363 Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls; 364 364 Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
Note: See TracChangeset
for help on using the changeset viewer.