Changeset 85077 in webkit
- Timestamp:
- Apr 27, 2011 1:32:16 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r85075 r85077 1 2011-04-16 Dimitri Glazkov <dglazkov@chromium.org> 2 3 Reviewed by Antti Koivisto. 4 5 Teach sub-selector chains about shadow descendants 6 https://bugs.webkit.org/show_bug.cgi?id=58342 7 8 * fast/css/unknown-pseudo-element-matching-expected.txt: Updated expectations. 9 * fast/css/unknown-pseudo-element-matching.html: Added new tests. 10 1 11 2011-04-20 Adrienne Walker <enne@google.com> 2 12 -
trunk/LayoutTests/fast/css/unknown-pseudo-element-matching-expected.txt
r75543 r85077 1 1 Tests various selector combinations, containing unknown pseudo element selectors. 2 2 3 Basic selector tests: 3 4 ::-webkit-slider-thumb should match: PASS 4 5 ::-webkit-slider-thumb, where HTML is not default namespace should not match: PASS … … 25 26 input#foo[type=range]::-webkit-slider-thumb should match: PASS 26 27 input.bar[type=range]::-webkit-slider-thumb should match: PASS 28 29 Shouldn't ignore selector after the unknown pseudo element: 30 ::-webkit-slider-thumb:disabled should not match: PASS 31 input::-webkit-slider-thumb:disabled should not match: PASS 32 #foo::-webkit-slider-thumb:disabled should not match: PASS 33 input#foo::-webkit-slider-thumb:disabled should not match: PASS 34 input.bar::-webkit-slider-thumb:disabled should not match: PASS 35 input[type=range]::-webkit-slider-thumb:disabled should not match: PASS 36 37 Should not match disabled input, because the disabled state is on the input, not the thumb: 38 ::-webkit-slider-thumb:disabled should not match: PASS 39 input::-webkit-slider-thumb:disabled should not match: PASS 40 #foo::-webkit-slider-thumb:disabled should not match: PASS 41 input#foo::-webkit-slider-thumb:disabled should not match: PASS 42 input.bar::-webkit-slider-thumb:disabled should not match: PASS 43 input[type=range]::-webkit-slider-thumb:disabled should not match: PASS 44 45 Should match :hover when the mouse is over the slider thumb: 46 ::-webkit-slider-thumb:hover should match: PASS 47 input::-webkit-slider-thumb:hover should match: PASS 48 #foo::-webkit-slider-thumb:hover should match: PASS 49 input#foo::-webkit-slider-thumb:hover should match: PASS 50 input.bar::-webkit-slider-thumb:hover should match: PASS 51 input[type=range]::-webkit-slider-thumb:hover should match: PASS -
trunk/LayoutTests/fast/css/unknown-pseudo-element-matching.html
r75543 r85077 17 17 var NAMESPACE_DECLARATION = '@namespace "http://example.com/foo/namespace";\n@namespace html "http://www.w3.org/1999/xhtml";\n'; 18 18 var SELECTOR_TEST_PROPERTIES = ' { height: 1px; -webkit-appearance: none; }'; 19 var SELECTORS = [ 20 '::-webkit-slider-thumb', 21 'input::-webkit-slider-thumb', 22 '#foo::-webkit-slider-thumb', 23 'input#foo::-webkit-slider-thumb', 24 'input.bar::-webkit-slider-thumb', 25 'input[type=range]::-webkit-slider-thumb' 26 ]; 27 var DISABLED_SELECTORS = SELECTORS.map(function(selector) { return selector + ':disabled'; }); 28 var HOVER_SELECTORS = SELECTORS.map(function(selector) { return selector + ':hover'; }) 19 29 20 30 // convenience constants … … 25 35 function log(msg, success) 26 36 { 27 logDiv.appendChild(document.createElement('div')).innerHTML = msg + ': ' + (success ? 'PASS' : 'FAIL'); 37 logDiv.appendChild(document.createElement('div')).innerHTML = msg + (arguments.length == 1 ? '' : (': ' + (success ? 'PASS' : 'FAIL'))); 38 } 39 40 function hoverOverSliderThumb() 41 { 42 if (!window.eventSender) 43 return false; 44 45 var x = input.offsetLeft + input.offsetWidth / 2; 46 var y = input.offsetTop + input.offsetHeight / 2; 47 eventSender.mouseMoveTo(x, y); 48 return true; 28 49 } 29 50 … … 43 64 input = document.getElementsByTagName('input')[0]; 44 65 logDiv = document.getElementById('log'); 66 log('Basic selector tests:'); 45 67 runSelectorTest(MATCH, '::-webkit-slider-thumb'); 46 68 runSelectorTest(NO_MATCH, '::-webkit-slider-thumb', WITH_NAMESPACES); … … 67 89 runSelectorTest(MATCH, 'input#foo[type=range]::-webkit-slider-thumb'); 68 90 runSelectorTest(MATCH, 'input.bar[type=range]::-webkit-slider-thumb'); 91 log('<br>Shouldn\'t ignore selector after the unknown pseudo element:'); 92 DISABLED_SELECTORS.forEach(expectNoMatch); 93 input.disabled = true; 94 log('<br>Should not match disabled input, because the disabled state is on the input, not the thumb:'); 95 DISABLED_SELECTORS.forEach(expectNoMatch); 96 input.disabled = false; 97 if (!hoverOverSliderThumb()) { 98 log(':hover tests require DRT'); 99 return; 100 } 101 log('<br>Should match :hover when the mouse is over the slider thumb:'); 102 HOVER_SELECTORS.forEach(expectMatch); 69 103 document.body.removeChild(input); 104 } 105 106 function expectNoMatch(selector) { 107 runSelectorTest(NO_MATCH, selector); 108 } 109 110 function expectMatch(selector) { 111 runSelectorTest(MATCH, selector); 70 112 } 71 113 -
trunk/Source/WebCore/ChangeLog
r85075 r85077 1 2011-04-20 Dimitri Glazkov <dglazkov@chromium.org> 2 3 Reviewed by Antti Koivisto. 4 5 Teach sub-selector chains about shadow descendants 6 https://bugs.webkit.org/show_bug.cgi?id=58342 7 8 The primary change is to the logic of parsing specifiers: 9 1) The shadow descendant selectors (those specifiers that are unknown 10 pseudo element selectors) are always kept at the top of the chain. 11 2) The sub-selectors after shadow descendant selectors are stashed right 12 behind the sub-selector, but not at the end of the chain. 13 3) Other sub-selectors are appended at the end of the chain. 14 15 * css/CSSGrammar.y: Changed specifier_list collection to use new 16 CSSParser::updateSpecifier helper. 17 * css/CSSParser.cpp: 18 (WebCore::CSSParser::updateSpecifiersWithElementName): Added logic to 19 look for the last ShadowDescendant relation in the chain of selectors, 20 because the next selector after it is the one that should get the 21 element name. 22 (WebCore::CSSParser::updateSpecifiers): Moved and modified the logic from 23 CSSGrammar.y. The new logic adjusts the selector chain to allow 24 shadow descendant selectors have sub-selectors (and have multiple shadow 25 descendants in the chain). 26 * css/CSSParser.h: Added decl. 27 * css/CSSParserValues.cpp: 28 (WebCore::CSSParserSelector::insertTagHistory): Added. 29 (WebCore::CSSParserSelector::appendTagHistory): Aded. 30 * css/CSSParserValues.h: Added decls. 31 * css/CSSStyleSelector.cpp: 32 (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): Added 33 shadow descendant selector match check, since now there could be many 34 of them in the selector chain. 35 1 36 2011-04-20 Adrienne Walker <enne@google.com> 2 37 -
trunk/Source/WebCore/css/CSSGrammar.y
r83415 r85077 980 980 if (!$2) 981 981 $$ = 0; 982 else if ($1) { 983 CSSParser* p = static_cast<CSSParser*>(parser); 984 CSSParserSelector* end; 985 CSSParserSelector* history; 986 // Ensure that unknown pseudo element always stays at the top of selector chain. 987 if ($2->isUnknownPseudoElement()) { 988 end = $2; 989 history = $1; 990 } else { 991 end = $1; 992 history = $2; 993 } 994 $$ = end; 995 while(end->tagHistory()) 996 end = end->tagHistory(); 997 end->setRelation(CSSSelector::SubSelector); 998 end->setTagHistory(p->sinkFloatingSelector(history)); 999 } 982 else if ($1) 983 $$ = static_cast<CSSParser*>(parser)->updateSpecifiers($1, $2); 1000 984 } 1001 985 | specifier_list error { -
trunk/Source/WebCore/css/CSSParser.cpp
r84836 r85077 6370 6370 } 6371 6371 6372 specifiers->setRelation(CSSSelector::ShadowDescendant); 6373 if (CSSParserSelector* history = specifiers->tagHistory()) { 6374 history->setTag(tag); 6372 CSSParserSelector* lastShadowDescendant = specifiers; 6373 CSSParserSelector* history = specifiers; 6374 while (history->tagHistory()) { 6375 history = history->tagHistory(); 6376 if (history->hasShadowDescendant()) 6377 lastShadowDescendant = history; 6378 } 6379 6380 if (lastShadowDescendant->tagHistory()) { 6381 lastShadowDescendant->tagHistory()->setTag(tag); 6375 6382 return; 6376 6383 } … … 6383 6390 CSSParserSelector* elementNameSelector = new CSSParserSelector; 6384 6391 elementNameSelector->setTag(tag); 6385 specifiers->setTagHistory(elementNameSelector); 6386 } 6387 6392 lastShadowDescendant->setTagHistory(elementNameSelector); 6393 lastShadowDescendant->setRelation(CSSSelector::ShadowDescendant); 6394 } 6395 6396 CSSParserSelector* CSSParser::updateSpecifiers(CSSParserSelector* specifiers, CSSParserSelector* newSpecifier) 6397 { 6398 if (newSpecifier->isUnknownPseudoElement()) { 6399 // Unknown pseudo element always goes at the top of selector chain. 6400 newSpecifier->appendTagHistory(CSSSelector::ShadowDescendant, sinkFloatingSelector(specifiers)); 6401 return newSpecifier; 6402 } 6403 if (specifiers->isUnknownPseudoElement()) { 6404 // Specifiers for unknown pseudo element go right behind it in the chain. 6405 specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::ShadowDescendant); 6406 return specifiers; 6407 } 6408 specifiers->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier)); 6409 return specifiers; 6410 } 6388 6411 6389 6412 CSSRule* CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector) -
trunk/Source/WebCore/css/CSSParser.h
r83122 r85077 221 221 void addNamespace(const AtomicString& prefix, const AtomicString& uri); 222 222 void updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*); 223 CSSParserSelector* updateSpecifiers(CSSParserSelector*, CSSParserSelector*); 223 224 224 225 void invalidBlockHit(); -
trunk/Source/WebCore/css/CSSParserValues.cpp
r83415 r85077 115 115 m_selector->setSelectorList(adoptPtr(selectorList)); 116 116 } 117 118 void CSSParserSelector::insertTagHistory(CSSSelector::Relation before, PassOwnPtr<CSSParserSelector> selector, CSSSelector::Relation after) 119 { 120 if (m_tagHistory) 121 selector->setTagHistory(m_tagHistory.release()); 122 setRelation(before); 123 selector->setRelation(after); 124 m_tagHistory = selector; 117 125 } 118 126 127 void CSSParserSelector::appendTagHistory(CSSSelector::Relation relation, PassOwnPtr<CSSParserSelector> selector) 128 { 129 CSSParserSelector* end = this; 130 while (end->tagHistory()) 131 end = end->tagHistory(); 132 end->setRelation(relation); 133 end->setTagHistory(selector); 134 } 135 136 } 137 -
trunk/Source/WebCore/css/CSSParserValues.h
r83415 r85077 117 117 bool isUnknownPseudoElement() const { return m_selector->isUnknownPseudoElement(); } 118 118 bool isSimple() const { return !m_tagHistory && m_selector->isSimple(); } 119 bool hasShadowDescendant() const; 119 120 120 121 CSSParserSelector* tagHistory() const { return m_tagHistory.get(); } 121 122 void setTagHistory(PassOwnPtr<CSSParserSelector> selector) { m_tagHistory = selector; } 123 void insertTagHistory(CSSSelector::Relation before, PassOwnPtr<CSSParserSelector>, CSSSelector::Relation after); 124 void appendTagHistory(CSSSelector::Relation, PassOwnPtr<CSSParserSelector>); 122 125 123 126 private: … … 126 129 }; 127 130 131 inline bool CSSParserSelector::hasShadowDescendant() const 132 { 133 return m_selector->relation() == CSSSelector::ShadowDescendant; 134 } 135 128 136 } 129 137 -
trunk/Source/WebCore/css/CSSStyleSelector.cpp
r85027 r85077 2967 2967 return false; 2968 2968 2969 if (sel->isUnknownPseudoElement()) 2969 if (sel->isUnknownPseudoElement()) { 2970 2970 m_hasUnknownPseudoElements = true; 2971 return e->shadowPseudoId() == sel->value(); 2972 } 2971 2973 2972 2974 PseudoId pseudoId = CSSSelector::pseudoId(sel->pseudoType());
Note: See TracChangeset
for help on using the changeset viewer.