Bug 1355408 - Part 1: Support @-moz-document rule in stylo. r=xidorn
MozReview-Commit-ID: BMoA7tb7ixj
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -22,16 +22,17 @@
#include "nsIDOMNode.h"
#include "nsIDocument.h"
#include "nsIDocumentInlines.h"
#include "nsIFrame.h"
#include "nsINode.h"
#include "nsIPresShell.h"
#include "nsIPresShellInlines.h"
#include "nsIPrincipal.h"
+#include "nsIURI.h"
#include "nsFontMetrics.h"
#include "nsMappedAttributes.h"
#include "nsMediaFeatures.h"
#include "nsNameSpaceManager.h"
#include "nsNetUtil.h"
#include "nsRuleNode.h"
#include "nsString.h"
#include "nsStyleStruct.h"
@@ -2021,16 +2022,36 @@ Gecko_RegisterProfilerThread(const char*
}
void
Gecko_UnregisterProfilerThread()
{
profiler_unregister_thread();
}
+bool
+Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed aPresContext,
+ const nsACString* aPattern,
+ css::URLMatchingFunction aURLMatchingFunction)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsIDocument *doc = aPresContext->Document();
+ nsIURI *docURI = doc->GetDocumentURI();
+ nsAutoCString docURISpec;
+ if (docURI) {
+ // If GetSpec fails (due to OOM) just skip these URI-specific CSS rules.
+ nsresult rv = docURI->GetSpec(docURISpec);
+ NS_ENSURE_SUCCESS(rv, false);
+ }
+
+ return css::DocumentRule::UseForPresentation(doc, docURI, docURISpec,
+ *aPattern, aURLMatchingFunction);
+}
+
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#ifndef MOZ_STYLO
#define SERVO_BINDING_FUNC(name_, return_, ...) \
return_ name_(__VA_ARGS__) { \
MOZ_CRASH("stylo: shouldn't be calling " #name_ "in a non-stylo build"); \
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -8,16 +8,17 @@
#define mozilla_ServoBindings_h
#include <stdint.h>
#include "mozilla/ServoTypes.h"
#include "mozilla/ServoBindingTypes.h"
#include "mozilla/ServoElementSnapshot.h"
#include "mozilla/css/SheetParsingMode.h"
+#include "mozilla/css/URLMatchingFunction.h"
#include "mozilla/EffectCompositor.h"
#include "mozilla/ComputedTimingFunction.h"
#include "nsChangeHint.h"
#include "nsCSSPseudoClasses.h"
#include "nsStyleStruct.h"
/*
* API for Servo to access Gecko data structures. This file must compile as valid
@@ -488,15 +489,19 @@ bool Gecko_MatchStringArgPseudo(RawGecko
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
void Gecko_Construct_nsStyleVariables(nsStyleVariables* ptr);
void Gecko_RegisterProfilerThread(const char* name);
void Gecko_UnregisterProfilerThread();
+bool Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed,
+ const nsACString* aPattern,
+ mozilla::css::URLMatchingFunction aURLMatchingFunction);
+
#define SERVO_BINDING_FUNC(name_, return_, ...) return_ name_(__VA_ARGS__);
#include "mozilla/ServoBindingList.h"
#undef SERVO_BINDING_FUNC
} // extern "C"
#endif // mozilla_ServoBindings_h
new file mode 100644
--- /dev/null
+++ b/layout/style/URLMatchingFunction.h
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_css_URLMatchingFunction_h
+#define mozilla_css_URLMatchingFunction_h
+
+namespace mozilla {
+namespace css {
+
+/**
+ * Enum defining the type of URL matching function for a @-moz-document rule
+ * condition.
+ */
+enum class URLMatchingFunction {
+ eURL = 0,
+ eURLPrefix,
+ eDomain,
+ eRegExp,
+};
+
+} // namespace css
+} // namespace mozilla
+
+#endif // mozilla_css_URLMatchingFunction_h
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -151,16 +151,17 @@ EXPORTS.mozilla.css += [
'GroupRule.h',
'ImageLoader.h',
'ImportRule.h',
'Loader.h',
'NameSpaceRule.h',
'Rule.h',
'SheetParsingMode.h',
'StyleRule.h',
+ 'URLMatchingFunction.h',
]
UNIFIED_SOURCES += [
'AnimationCollection.cpp',
'BindingStyleRule.cpp',
'CounterStyleManager.cpp',
'CSS.cpp',
'CSSLexer.cpp',
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -23,16 +23,17 @@
#include "nsAlgorithm.h"
#include "nsCSSProps.h"
#include "nsCSSKeywords.h"
#include "nsCSSScanner.h"
#include "mozilla/css/ErrorReporter.h"
#include "mozilla/css/Loader.h"
#include "mozilla/css/StyleRule.h"
#include "mozilla/css/ImportRule.h"
+#include "mozilla/css/URLMatchingFunction.h"
#include "nsCSSRules.h"
#include "nsCSSFontFaceRule.h"
#include "mozilla/css/NameSpaceRule.h"
#include "nsTArray.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/css/Declaration.h"
#include "nsStyleConsts.h"
#include "nsNetUtil.h"
@@ -3895,38 +3896,38 @@ CSSParserImpl::ParseMozDocumentRule(Rule
REPORT_UNEXPECTED_TOKEN(PEMozDocRuleBadFunc2);
UngetToken();
delete urls;
return false;
}
css::DocumentRule::URL *cur = *next = new css::DocumentRule::URL;
next = &cur->next;
if (mToken.mType == eCSSToken_URL) {
- cur->func = css::DocumentRule::eURL;
+ cur->func = URLMatchingFunction::eURL;
CopyUTF16toUTF8(mToken.mIdent, cur->url);
} else if (mToken.mIdent.LowerCaseEqualsLiteral("regexp")) {
// regexp() is different from url-prefix() and domain() (but
// probably the way they *should* have been* in that it requires a
// string argument, and doesn't try to behave like url().
- cur->func = css::DocumentRule::eRegExp;
+ cur->func = URLMatchingFunction::eRegExp;
GetToken(true);
// copy before we know it's valid (but before ExpectSymbol changes
// mToken.mIdent)
CopyUTF16toUTF8(mToken.mIdent, cur->url);
if (eCSSToken_String != mToken.mType || !ExpectSymbol(')', true)) {
REPORT_UNEXPECTED_TOKEN(PEMozDocRuleNotString);
SkipUntil(')');
delete urls;
return false;
}
} else {
if (mToken.mIdent.LowerCaseEqualsLiteral("url-prefix")) {
- cur->func = css::DocumentRule::eURLPrefix;
+ cur->func = URLMatchingFunction::eURLPrefix;
} else if (mToken.mIdent.LowerCaseEqualsLiteral("domain")) {
- cur->func = css::DocumentRule::eDomain;
+ cur->func = URLMatchingFunction::eDomain;
}
NS_ASSERTION(!mHavePushBack, "mustn't have pushback at this point");
mScanner->NextURL(mToken);
if (mToken.mType != eCSSToken_URL) {
REPORT_UNEXPECTED_TOKEN(PEMozDocRuleNotURI);
SkipUntil(')');
delete urls;
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -558,26 +558,26 @@ DocumentRule::List(FILE* out, int32_t aI
for (int32_t indent = aIndent; --indent >= 0; ) {
indentStr.AppendLiteral(" ");
}
nsAutoCString str;
str.AppendLiteral("@-moz-document ");
for (URL *url = mURLs; url; url = url->next) {
switch (url->func) {
- case eURL:
+ case URLMatchingFunction::eURL:
str.AppendLiteral("url(\"");
break;
- case eURLPrefix:
+ case URLMatchingFunction::eURLPrefix:
str.AppendLiteral("url-prefix(\"");
break;
- case eDomain:
+ case URLMatchingFunction::eDomain:
str.AppendLiteral("domain(\"");
break;
- case eRegExp:
+ case URLMatchingFunction::eRegExp:
str.AppendLiteral("regexp(\"");
break;
}
nsAutoCString escapedURL(url->url);
escapedURL.ReplaceSubstring("\"", "\\\""); // escape quotes
str.Append(escapedURL);
str.AppendLiteral("\"), ");
}
@@ -675,47 +675,66 @@ DocumentRule::UseForPresentation(nsPresC
nsAutoCString docURISpec;
if (docURI) {
// If GetSpec fails (due to OOM) just skip these URI-specific CSS rules.
nsresult rv = docURI->GetSpec(docURISpec);
NS_ENSURE_SUCCESS(rv, false);
}
for (URL *url = mURLs; url; url = url->next) {
- switch (url->func) {
- case eURL: {
- if (docURISpec == url->url)
- return true;
- } break;
- case eURLPrefix: {
- if (StringBeginsWith(docURISpec, url->url))
- return true;
- } break;
- case eDomain: {
- nsAutoCString host;
- if (docURI)
- docURI->GetHost(host);
- int32_t lenDiff = host.Length() - url->url.Length();
- if (lenDiff == 0) {
- if (host == url->url)
- return true;
- } else {
- if (StringEndsWith(host, url->url) &&
- host.CharAt(lenDiff - 1) == '.')
- return true;
- }
- } break;
- case eRegExp: {
- NS_ConvertUTF8toUTF16 spec(docURISpec);
- NS_ConvertUTF8toUTF16 regex(url->url);
- if (nsContentUtils::IsPatternMatching(spec, regex, doc)) {
+ if (UseForPresentation(doc, docURI, docURISpec, url->url, url->func)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+DocumentRule::UseForPresentation(nsIDocument* aDoc,
+ nsIURI* aDocURI,
+ const nsACString& aDocURISpec,
+ const nsACString& aPattern,
+ URLMatchingFunction aUrlMatchingFunction)
+{
+ switch (aUrlMatchingFunction) {
+ case URLMatchingFunction::eURL: {
+ if (aDocURISpec == aPattern) {
+ return true;
+ }
+ } break;
+ case URLMatchingFunction::eURLPrefix: {
+ if (StringBeginsWith(aDocURISpec, aPattern)) {
+ return true;
+ }
+ } break;
+ case URLMatchingFunction::eDomain: {
+ nsAutoCString host;
+ if (aDocURI) {
+ aDocURI->GetHost(host);
+ }
+ int32_t lenDiff = host.Length() - aPattern.Length();
+ if (lenDiff == 0) {
+ if (host == aPattern) {
return true;
}
- } break;
- }
+ } else {
+ if (StringEndsWith(host, aPattern) &&
+ host.CharAt(lenDiff - 1) == '.') {
+ return true;
+ }
+ }
+ } break;
+ case URLMatchingFunction::eRegExp: {
+ NS_ConvertUTF8toUTF16 spec(aDocURISpec);
+ NS_ConvertUTF8toUTF16 regex(aPattern);
+ if (nsContentUtils::IsPatternMatching(spec, regex, aDoc)) {
+ return true;
+ }
+ } break;
}
return false;
}
DocumentRule::URL::~URL()
{
NS_CSS_DELETE_LIST_MEMBER(DocumentRule::URL, this, next);
@@ -741,26 +760,26 @@ DocumentRule::WrapObject(JSContext* aCx,
return CSSMozDocumentRuleBinding::Wrap(aCx, this, aGivenProto);
}
void
DocumentRule::AppendConditionText(nsAString& aCssText) const
{
for (URL *url = mURLs; url; url = url->next) {
switch (url->func) {
- case eURL:
+ case URLMatchingFunction::eURL:
aCssText.AppendLiteral("url(");
break;
- case eURLPrefix:
+ case URLMatchingFunction::eURLPrefix:
aCssText.AppendLiteral("url-prefix(");
break;
- case eDomain:
+ case URLMatchingFunction::eDomain:
aCssText.AppendLiteral("domain(");
break;
- case eRegExp:
+ case URLMatchingFunction::eRegExp:
aCssText.AppendLiteral("regexp(");
break;
}
nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url),
aCssText);
aCssText.AppendLiteral("), ");
}
aCssText.Truncate(aCssText.Length() - 2); // remove last ", "
@@ -1164,17 +1183,17 @@ nsCSSFontFaceStyleDecl::GetParentObject(
JSObject*
nsCSSFontFaceStyleDecl::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
{
return mozilla::dom::CSSStyleDeclarationBinding::Wrap(cx, this, aGivenProto);
}
// -------------------------------------------
// nsCSSFontFaceRule
-//
+//
/* virtual */ already_AddRefed<css::Rule>
nsCSSFontFaceRule::Clone() const
{
RefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this);
return clone.forget();
}
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -12,16 +12,17 @@
#include "Declaration.h"
#include "StyleRule.h"
#include "gfxFontFeatures.h"
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Move.h"
#include "mozilla/SheetType.h"
#include "mozilla/css/GroupRule.h"
+#include "mozilla/css/URLMatchingFunction.h"
#include "mozilla/dom/CSSMediaRule.h"
#include "mozilla/dom/CSSPageRule.h"
#include "mozilla/dom/CSSSupportsRule.h"
#include "nsAutoPtr.h"
#include "nsCSSPropertyID.h"
#include "nsCSSValue.h"
#include "nsDOMCSSDeclaration.h"
#include "nsIDOMCSSConditionRule.h"
@@ -119,29 +120,28 @@ public:
// nsIDOMCSSConditionRule interface
NS_DECL_NSIDOMCSSCONDITIONRULE
// nsIDOMCSSMozDocumentRule interface
NS_DECL_NSIDOMCSSMOZDOCUMENTRULE
// rest of GroupRule
virtual bool UseForPresentation(nsPresContext* aPresContext,
- nsMediaQueryResultCacheKey& aKey) override;
+ nsMediaQueryResultCacheKey& aKey) override;
bool UseForPresentation(nsPresContext* aPresContext);
- enum Function {
- eURL,
- eURLPrefix,
- eDomain,
- eRegExp
- };
+ static bool UseForPresentation(nsIDocument* aDoc,
+ nsIURI* aDocURI,
+ const nsACString& aDocURISpec,
+ const nsACString& aPattern,
+ URLMatchingFunction aUrlMatchingFunction);
struct URL {
- Function func;
+ URLMatchingFunction func;
nsCString url;
URL *next;
URL() : next(nullptr) {}
URL(const URL& aOther)
: func(aOther.func)
, url(aOther.url)
, next(aOther.next ? new URL(*aOther.next) : nullptr)
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -309,16 +309,17 @@ dependencies = [
name = "geckoservo"
version = "0.0.1"
dependencies = [
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nsstring_vendor 0.1.0",
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.18.0",
"style 0.0.1",
"style_traits 0.0.1",
]
[[package]]
name = "gkrust-shared"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -307,16 +307,17 @@ dependencies = [
name = "geckoservo"
version = "0.0.1"
dependencies = [
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nsstring_vendor 0.1.0",
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.18.0",
"style 0.0.1",
"style_traits 0.0.1",
]
[[package]]
name = "gkrust-shared"