Bug 1365162 - Part 5: Factor out :lang() matching function. r=emilio draft
authorCameron McCormack <cam@mcc.id.au>
Wed, 07 Jun 2017 12:17:31 +0800
changeset 590157 34ecd37a22fc0076193ea8481a3fbd6f006c1667
parent 590156 f8690b1f0638735546fe29fae35d5e08cd08f4a2
child 590158 58c3cc2843849b93561c067190c9c6ed0a3b0791
push id62612
push userbmo:cam@mcc.id.au
push dateWed, 07 Jun 2017 07:54:44 +0000
reviewersemilio
bugs1365162
milestone55.0a1
Bug 1365162 - Part 5: Factor out :lang() matching function. r=emilio MozReview-Commit-ID: KhCd90UPatX
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsCSSRuleProcessor.h
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -1671,16 +1671,81 @@ IsSignificantChildMaybeThreadSafe(const 
                                                      aWhitespaceIsSignificant);
   } else {
     auto content = const_cast<nsIContent*>(aContent);
     return IsSignificantChild(content, aTextIsSignificant, aWhitespaceIsSignificant);
   }
 }
 
 /* static */ bool
+nsCSSRuleProcessor::LangPseudoMatches(const mozilla::dom::Element* aElement,
+                                      const nsAString* aOverrideLang,
+                                      bool aHasOverrideLang,
+                                      const char16_t* aString,
+                                      const nsIDocument* aDocument)
+{
+  NS_ASSERTION(aString, "null lang parameter");
+  if (!aString || !*aString) {
+    return false;
+  }
+
+  // We have to determine the language of the current element.  Since
+  // this is currently no property and since the language is inherited
+  // from the parent we have to be prepared to look at all parent
+  // nodes.  The language itself is encoded in the LANG attribute.
+  bool haveLanguage = false;
+  nsAutoString language;
+  if (aHasOverrideLang) {
+    if (aOverrideLang) {
+      language = *aOverrideLang;
+      haveLanguage = true;
+    }
+  } else {
+    haveLanguage = aElement->GetLang(language);
+  }
+
+  if (haveLanguage) {
+    return nsStyleUtil::DashMatchCompare(language,
+                                         nsDependentString(aString),
+                                         nsASCIICaseInsensitiveStringComparator());
+  }
+
+  if (aDocument) {
+    // Try to get the language from the HTTP header or if this
+    // is missing as well from the preferences.
+    // The content language can be a comma-separated list of
+    // language codes.
+    aDocument->GetContentLanguage(language);
+
+    nsDependentString langString(aString);
+    language.StripWhitespace();
+    int32_t begin = 0;
+    int32_t len = language.Length();
+    while (begin < len) {
+      int32_t end = language.FindChar(char16_t(','), begin);
+      if (end == kNotFound) {
+        end = len;
+      }
+      if (nsStyleUtil::DashMatchCompare(Substring(language, begin,
+                                                  end-begin),
+                                        langString,
+                                        nsASCIICaseInsensitiveStringComparator())) {
+        return true;
+      }
+      begin = end + 1;
+    }
+    if (begin < len) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/* static */ bool
 nsCSSRuleProcessor::StringPseudoMatches(const mozilla::dom::Element* aElement,
                                         CSSPseudoClassType aPseudo,
                                         const char16_t* aString,
                                         const nsIDocument* aDocument,
                                         bool aForStyling,
                                         EventStates aStateMask,
                                         bool* aSetSlowSelectorFlag,
                                         bool* const aDependence)
@@ -1783,66 +1848,18 @@ nsCSSRuleProcessor::StringPseudoMatches(
         } else {
           // Selectors specifying other directions never match.
           return false;
         }
       }
       break;
 
     case CSSPseudoClassType::lang:
-      {
-        NS_ASSERTION(aString, "null lang parameter");
-        if (!aString || !*aString) {
-          return false;
-        }
-
-        // We have to determine the language of the current element.  Since
-        // this is currently no property and since the language is inherited
-        // from the parent we have to be prepared to look at all parent
-        // nodes.  The language itself is encoded in the LANG attribute.
-        nsAutoString language;
-        if (aElement->GetLang(language)) {
-          if (!nsStyleUtil::DashMatchCompare(language,
-                                             nsDependentString(aString),
-                                             nsASCIICaseInsensitiveStringComparator())) {
-            return false;
-          }
-          // This pseudo-class matched; move on to the next thing
-          break;
-        }
-
-        if (aDocument) {
-          // Try to get the language from the HTTP header or if this
-          // is missing as well from the preferences.
-          // The content language can be a comma-separated list of
-          // language codes.
-          aDocument->GetContentLanguage(language);
-
-          nsDependentString langString(aString);
-          language.StripWhitespace();
-          int32_t begin = 0;
-          int32_t len = language.Length();
-          while (begin < len) {
-            int32_t end = language.FindChar(char16_t(','), begin);
-            if (end == kNotFound) {
-              end = len;
-            }
-            if (nsStyleUtil::DashMatchCompare(Substring(language, begin,
-                                                        end-begin),
-                                              langString,
-                                              nsASCIICaseInsensitiveStringComparator())) {
-              break;
-            }
-            begin = end + 1;
-          }
-          if (begin < len) {
-            // This pseudo-class matched
-            break;
-          }
-        }
+      if (LangPseudoMatches(aElement, nullptr, false, aString, aDocument)) {
+        break;
       }
       return false;
 
     default: MOZ_ASSERT_UNREACHABLE("Called StringPseudoMatches() with unknown string-like pseudo");
   }
   return true;
 }
 
--- a/layout/style/nsCSSRuleProcessor.h
+++ b/layout/style/nsCSSRuleProcessor.h
@@ -166,16 +166,22 @@ public:
                                   mozilla::CSSPseudoClassType aPseudo,
                                   const char16_t* aString,
                                   const nsIDocument* aDocument,
                                   bool aForStyling,
                                   mozilla::EventStates aStateMask,
                                   bool* aSetSlowSelectorFlag,
                                   bool* const aDependence = nullptr);
 
+  static bool LangPseudoMatches(const mozilla::dom::Element* aElement,
+                                const nsAString* aOverrideLang,
+                                bool aHasOverrideLang,
+                                const char16_t* aString,
+                                const nsIDocument* aDocument);
+
   // nsIStyleRuleProcessor
   virtual void RulesMatching(ElementRuleProcessorData* aData) override;
 
   virtual void RulesMatching(PseudoElementRuleProcessorData* aData) override;
 
   virtual void RulesMatching(AnonBoxRuleProcessorData* aData) override;
 
 #ifdef MOZ_XUL