RESOLVED FIXED 78595
CollectingRules and QueryingRules modes of SelectorChecker miss some complex selectors with pseudo elements
https://bugs.webkit.org/show_bug.cgi?id=78595
Summary CollectingRules and QueryingRules modes of SelectorChecker miss some complex ...
Pavel Feldman
Reported 2012-02-14 02:57:08 PST
Consider the case below: <style> .section .header::before { content: "COLLAPSED" } .section.expanded .header::before { content: "EXPANDED", } </style> <div class="section"> <div class="header">HEADER</div> </div> <div class="section expanded"> <div class="header">HEADER</div> </div> While WebCore renders everything correctly, pseudo element is missing for the second header.
Attachments
[TEST] Test case (266 bytes, text/html)
2012-02-14 06:47 PST, Pavel Feldman
no flags
Patch (11.39 KB, patch)
2012-09-25 09:05 PDT, Alexander Pavlov (apavlov)
no flags
Patch (13.17 KB, patch)
2012-09-26 00:02 PDT, Alexander Pavlov (apavlov)
koivisto: review+
Pavel Feldman
Comment 1 2012-02-14 06:46:59 PST
(ignore the "," - that was a typo, not relevant to the bug described) <style> .section .header::before { content: "COLLAPSED" } .section.expanded .header::before { content: "EXPANDED" } </style> <div class="section"> <div class="header">HEADER</div> </div> <div class="section expanded"> <div class="header">HEADER</div> </div>
Pavel Feldman
Comment 2 2012-02-14 06:47:32 PST
Created attachment 126970 [details] [TEST] Test case
Alexander Pavlov (apavlov)
Comment 3 2012-09-25 08:30:11 PDT
Root cause summary: SelectorChecker::checkSelector() operates on the same dynamicPseudo reference when recursively calling self for non-SubSelector selectors, even though dynamicPseudo passed in from StyleResolver::checkSelector() is intended to get the value of the last selector in the list (describing the element to which the selector is applicable).
Alexander Pavlov (apavlov)
Comment 4 2012-09-25 09:05:11 PDT
WebKit Review Bot
Comment 5 2012-09-25 11:04:27 PDT
Comment on attachment 165622 [details] Patch Attachment 165622 [details] did not pass chromium-ews (chromium-xvfb): Output: http://queues.webkit.org/results/14026168 New failing tests: fast/dom/Window/getMatchedCSSRules-with-pseudo-elements-complex.html
Build Bot
Comment 6 2012-09-25 11:28:48 PDT
Comment on attachment 165622 [details] Patch Attachment 165622 [details] did not pass mac-ews (mac): Output: http://queues.webkit.org/results/14036129 New failing tests: fast/dom/Window/getMatchedCSSRules-with-pseudo-elements-complex.html
Alexander Pavlov (apavlov)
Comment 7 2012-09-26 00:02:05 PDT
Dimitri Glazkov (Google)
Comment 8 2012-09-26 08:50:18 PDT
Comment on attachment 165740 [details] Patch This fix will look slightly nicer after bug 96445 lands.
Alexander Pavlov (apavlov)
Comment 9 2012-09-26 10:49:25 PDT
(In reply to comment #8) > (From update of attachment 165740 [details]) > This fix will look slightly nicer after bug 96445 lands. Indeed! Waiting for it to land.
Antti Koivisto
Comment 10 2012-09-26 20:25:37 PDT
Comment on attachment 165740 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=165740&action=review > Source/WebCore/ChangeLog:8 > + Do not use the same dynamicPseudo reference when recursively invoking checkSelector() for non-SubSelector selectors. Why does this work (or does it?) in ResolvingStyle case? > Source/WebCore/css/SelectorChecker.cpp:476 > + PseudoId nonSubSelectorPseudo(NOPSEUDO); > + PseudoId& currentDynamicPseudo = relation == CSSSelector::SubSelector ? dynamicPseudo : nonSubSelectorPseudo; That looks bit funny but I suppose it is ok.
Alexander Pavlov (apavlov)
Comment 11 2012-09-27 02:29:58 PDT
(In reply to comment #10) > (From update of attachment 165740 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=165740&action=review > > > Source/WebCore/ChangeLog:8 > > + Do not use the same dynamicPseudo reference when recursively invoking checkSelector() for non-SubSelector selectors. > > Why does this work (or does it?) in ResolvingStyle case? It works in the ResolvingStyle case because the only failing code so far is found in "case CSSSelector::SubSelector" inside SelectorChecker::checkSelector(), and the bail-out condition involves the "m_mode == CollectingRules || m_mode == QueryingRules" check. ResolvingStyle case is not in this list, so the code does not bail out during the style resolve. > > Source/WebCore/css/SelectorChecker.cpp:476 > > + PseudoId nonSubSelectorPseudo(NOPSEUDO); > > + PseudoId& currentDynamicPseudo = relation == CSSSelector::SubSelector ? dynamicPseudo : nonSubSelectorPseudo; > > That looks bit funny but I suppose it is ok. I know it's actually ugly :) but I did not want to migrate the entire code to pointers...
Alexander Pavlov (apavlov)
Comment 12 2012-09-27 02:55:39 PDT
Note You need to log in before you can comment on or make changes to this bug.