Bug 1365162 - Part 5: Factor out :lang() matching function. r=emilio
MozReview-Commit-ID: KhCd90UPatX
--- 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