Web Inspector: Highlighted selectors in Rules sidebar break with selectors that conta...
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Oct 2014 01:55:17 +0000 (01:55 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 7 Oct 2014 01:55:17 +0000 (01:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137378

Patch by Benjamin Poulain <bpoulain@apple.com> on 2014-10-06
Reviewed by Joseph Pecoraro.

We should not update the parser's selectorRange when matching a nested selector list.

To implement this with low risk of unbalanced start+end and good error recovery,
I have wrapped the parsing of selector_list between a start/end function at the grammar
level. Whenever the parser enter a nested selector list, m_nestedSelectorLevel goes up
by one. Any time the parsing is currently in a nested selector list, we never update
the selector ranges.

* css/CSSGrammar.y.in:
* css/CSSParser.cpp:
(WebCore::CSSParser::CSSParser):
(WebCore::CSSParser::markSelectorStart):
(WebCore::CSSParser::markSelectorEnd):
* css/CSSParser.h:
(WebCore::CSSParser::startNestedSelectorList):
(WebCore::CSSParser::endNestedSelectorList):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@174379 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/css/CSSGrammar.y.in
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParser.h

index 2282d93..0f6bb77 100644 (file)
@@ -1,3 +1,27 @@
+2014-10-06  Benjamin Poulain  <bpoulain@apple.com>
+
+        Web Inspector: Highlighted selectors in Rules sidebar break with selectors that contain nested selector lists
+        https://bugs.webkit.org/show_bug.cgi?id=137378
+
+        Reviewed by Joseph Pecoraro.
+
+        We should not update the parser's selectorRange when matching a nested selector list.
+
+        To implement this with low risk of unbalanced start+end and good error recovery,
+        I have wrapped the parsing of selector_list between a start/end function at the grammar
+        level. Whenever the parser enter a nested selector list, m_nestedSelectorLevel goes up
+        by one. Any time the parsing is currently in a nested selector list, we never update
+        the selector ranges.
+
+        * css/CSSGrammar.y.in:
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::CSSParser):
+        (WebCore::CSSParser::markSelectorStart):
+        (WebCore::CSSParser::markSelectorEnd):
+        * css/CSSParser.h:
+        (WebCore::CSSParser::startNestedSelectorList):
+        (WebCore::CSSParser::endNestedSelectorList):
+
 2014-10-06  Roger Fong  <roger_fong@apple.com>
 
         [Windows] Build fix for EWS bots.
index e8256e0..29bb486 100644 (file)
@@ -309,8 +309,8 @@ static bool isValidNthSelectorList(const Vector<std::unique_ptr<CSSParserSelecto
 %destructor { delete $$; } attrib class page_selector pseudo pseudo_page complex_selector complex_selector_with_trailing_whitespace compound_selector specifier specifier_list
 
 %union { Vector<std::unique_ptr<CSSParserSelector>>* selectorList; }
-%type <selectorList> selector_list simple_selector_list nth_selector_ending
-%destructor { delete $$; } selector_list simple_selector_list nth_selector_ending
+%type <selectorList> selector_list nested_selector_list simple_selector_list nth_selector_ending
+%destructor { delete $$; } selector_list nested_selector_list simple_selector_list nth_selector_ending
 
 %union { bool boolean; }
 %type <boolean> declaration declaration_list decl_list priority
@@ -1091,6 +1091,15 @@ selector_list:
     }
    ;
 
+before_nested_selector_list: { parser->startNestedSelectorList(); } ;
+after_nested_selector_list: { parser->endNestedSelectorList(); } ;
+
+nested_selector_list:
+    before_nested_selector_list selector_list after_nested_selector_list {
+        $$ = $2;
+    }
+    ;
+
 complex_selector_with_trailing_whitespace:
     complex_selector WHITESPACE;
 
@@ -1300,7 +1309,7 @@ nth_selector_ending:
     | space ')' {
         $$ = nullptr;
     }
-    | space NTHCHILDSELECTORSEPARATOR space selector_list maybe_space ')' {
+    | space NTHCHILDSELECTORSEPARATOR space nested_selector_list maybe_space ')' {
         if ($4)
             $$ = $4;
         else
@@ -1339,7 +1348,7 @@ pseudo:
     }
 
 #if ENABLE_CSS_SELECTORS_LEVEL4
-    | ':' MATCHESFUNCTION maybe_space selector_list maybe_space ')' {
+    | ':' MATCHESFUNCTION maybe_space nested_selector_list maybe_space ')' {
         $$ = nullptr;
         if ($4) {
             auto selector = std::make_unique<CSSParserSelector>();
index c00f978..960600a 100644 (file)
@@ -317,6 +317,7 @@ CSSParser::CSSParser(const CSSParserContext& context)
     , m_ignoreErrorsInDeclaration(false)
     , m_defaultNamespace(starAtom)
     , m_parsedTextPrefixLength(0)
+    , m_nestedSelectorLevel(0)
     , m_propertyRange(UINT_MAX, UINT_MAX)
     , m_ruleSourceDataResult(0)
     , m_parsingMode(NormalMode)
@@ -12052,7 +12053,7 @@ void CSSParser::markRuleHeaderEnd()
 
 void CSSParser::markSelectorStart()
 {
-    if (!isExtractingSourceData())
+    if (!isExtractingSourceData() || m_nestedSelectorLevel)
         return;
     ASSERT(!m_selectorRange.end);
 
@@ -12061,7 +12062,7 @@ void CSSParser::markSelectorStart()
 
 void CSSParser::markSelectorEnd()
 {
-    if (!isExtractingSourceData())
+    if (!isExtractingSourceData() || m_nestedSelectorLevel)
         return;
     ASSERT(!m_selectorRange.end);
     ASSERT(m_currentRuleDataStack->size());
index 59e1f6e..8167d82 100644 (file)
@@ -375,6 +375,7 @@ public:
 
     // tokenizer methods and data
     size_t m_parsedTextPrefixLength;
+    unsigned m_nestedSelectorLevel;
     SourceRange m_selectorRange;
     SourceRange m_propertyRange;
     std::unique_ptr<RuleSourceDataList> m_currentRuleDataStack;
@@ -384,8 +385,12 @@ public:
     void fixUnparsedPropertyRanges(CSSRuleSourceData*);
     void markRuleHeaderStart(CSSRuleSourceData::Type);
     void markRuleHeaderEnd();
+
+    void startNestedSelectorList() { ++m_nestedSelectorLevel; }
+    void endNestedSelectorList() { --m_nestedSelectorLevel; }
     void markSelectorStart();
     void markSelectorEnd();
+
     void markRuleBodyStart();
     void markRuleBodyEnd();
     void markPropertyStart();