Bug 1374902 - Check pref when parsing :fullscreen pseudo-class. r?TYLin
MozReview-Commit-ID: 3UHeQ10E48J
--- a/dom/html/test/file_fullscreen-unprefix-disabled-inner.html
+++ b/dom/html/test/file_fullscreen-unprefix-disabled-inner.html
@@ -1,15 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test for Bug 1268749</title>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <style>
+ #fullscreen {
+ color: green;
+ }
+ #fullscreen:fullscreen {
+ color: red;
+ }
+ </style>
</head>
<body>
<div id="fullscreen"></div>
<script>
function ok(condition, msg) {
opener.opener.ok(condition, "[unprefix-disabled] " + msg);
}
@@ -69,16 +77,18 @@ function begin() {
}
document.addEventListener("mozfullscreenchange", enteredFullscreen);
SimpleTest.executeSoon(() => div.mozRequestFullScreen());
}
function enteredFullscreen() {
document.removeEventListener("mozfullscreenchange", enteredFullscreen);
+ is(getComputedStyle(div).color, "rgb(0, 128, 0)",
+ ":fullscreen should not apply");
document.addEventListener("mozfullscreenchange", exitedFullscreen);
SimpleTest.executeSoon(() => document.mozCancelFullScreen());
}
function exitedFullscreen() {
document.removeEventListener("mozfullscreenchange", exitedFullscreen);
document.addEventListener("mozfullscreenerror", errorFullscreen);
SimpleTest.executeSoon(() => unattachedDiv.mozRequestFullScreen());
--- a/layout/style/StylePrefs.cpp
+++ b/layout/style/StylePrefs.cpp
@@ -12,16 +12,17 @@ namespace mozilla {
bool StylePrefs::sFontDisplayEnabled;
bool StylePrefs::sOpentypeSVGEnabled;
bool StylePrefs::sWebkitPrefixedAliasesEnabled;
bool StylePrefs::sWebkitDevicePixelRatioEnabled;
bool StylePrefs::sMozGradientsEnabled;
bool StylePrefs::sControlCharVisibility;
bool StylePrefs::sFramesTimingFunctionEnabled;
+bool StylePrefs::sUnprefixedFullscreenApiEnabled;
/* static */ void
StylePrefs::Init()
{
Preferences::AddBoolVarCache(&sFontDisplayEnabled,
"layout.css.font-display.enabled");
Preferences::AddBoolVarCache(&sOpentypeSVGEnabled,
"gfx.font_rendering.opentype_svg.enabled");
@@ -30,11 +31,13 @@ StylePrefs::Init()
Preferences::AddBoolVarCache(&sWebkitDevicePixelRatioEnabled,
"layout.css.prefixes.device-pixel-ratio-webkit");
Preferences::AddBoolVarCache(&sMozGradientsEnabled,
"layout.css.prefixes.gradients");
Preferences::AddBoolVarCache(&sControlCharVisibility,
"layout.css.control-characters.visible");
Preferences::AddBoolVarCache(&sFramesTimingFunctionEnabled,
"layout.css.frames-timing.enabled");
+ Preferences::AddBoolVarCache(&sUnprefixedFullscreenApiEnabled,
+ "full-screen-api.unprefix.enabled");
}
} // namespace mozilla
--- a/layout/style/StylePrefs.h
+++ b/layout/style/StylePrefs.h
@@ -15,15 +15,16 @@ struct StylePrefs
{
static bool sFontDisplayEnabled;
static bool sOpentypeSVGEnabled;
static bool sWebkitPrefixedAliasesEnabled;
static bool sWebkitDevicePixelRatioEnabled;
static bool sMozGradientsEnabled;
static bool sControlCharVisibility;
static bool sFramesTimingFunctionEnabled;
+ static bool sUnprefixedFullscreenApiEnabled;
static void Init();
};
} // namespace mozilla
#endif // mozilla_StylePrefs_h
--- a/servo/components/style/gecko/non_ts_pseudo_class_list.rs
+++ b/servo/components/style/gecko/non_ts_pseudo_class_list.rs
@@ -56,19 +56,17 @@ macro_rules! apply_non_ts_list {
("focus", Focus, focus, IN_FOCUS_STATE, _),
("focus-within", FocusWithin, focusWithin, IN_FOCUS_WITHIN_STATE, _),
("hover", Hover, hover, IN_HOVER_STATE, _),
("-moz-drag-over", MozDragOver, mozDragOver, IN_DRAGOVER_STATE, _),
("target", Target, target, IN_TARGET_STATE, _),
("indeterminate", Indeterminate, indeterminate, IN_INDETERMINATE_STATE, _),
("-moz-devtools-highlighted", MozDevtoolsHighlighted, mozDevtoolsHighlighted, IN_DEVTOOLS_HIGHLIGHTED_STATE, _),
("-moz-styleeditor-transitioning", MozStyleeditorTransitioning, mozStyleeditorTransitioning, IN_STYLEEDITOR_TRANSITIONING_STATE, _),
- // TODO(emilio): Needs pref check for full-screen-api.unprefix.enabled!
- // TODO(TYLin): Needs to use CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME?
- ("fullscreen", Fullscreen, fullscreen, IN_FULLSCREEN_STATE, _),
+ ("fullscreen", Fullscreen, fullscreen, IN_FULLSCREEN_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
("-moz-full-screen", MozFullScreen, mozFullScreen, IN_FULLSCREEN_STATE, _),
// TODO(emilio): This is inconsistently named (the capital R).
("-moz-focusring", MozFocusRing, mozFocusRing, IN_FOCUSRING_STATE, _),
("-moz-broken", MozBroken, mozBroken, IN_BROKEN_STATE, _),
("-moz-loading", MozLoading, mozLoading, IN_LOADING_STATE, _),
("-moz-suppressed", MozSuppressed, mozSuppressed, IN_SUPPRESSED_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
("-moz-has-dir-attr", MozHasDirAttr, mozHasDirAttr, IN_HAS_DIR_ATTR_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
("-moz-dir-attr-ltr", MozDirAttrLTR, mozDirAttrLTR, IN_HAS_DIR_ATTR_LTR_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS),
--- a/servo/components/style/gecko/selector_parser.rs
+++ b/servo/components/style/gecko/selector_parser.rs
@@ -120,38 +120,51 @@ impl SelectorMethods for NonTSPseudoClas
}
true
}
}
impl NonTSPseudoClass {
- /// Returns true if this pseudo-class is enabled under the context of
- /// the given flag.
- fn is_enabled_in(&self, flag: NonTSPseudoClassFlag) -> bool {
+ /// Returns true if this pseudo-class has any of the given flags set.
+ fn has_any_flag(&self, flags: NonTSPseudoClassFlag) -> bool {
macro_rules! check_flag {
(_) => (false);
- ($flags:expr) => ($flags.contains(flag));
+ ($flags:expr) => ($flags.intersects(flags));
}
macro_rules! pseudo_class_check_is_enabled_in {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*],
keyword: [$(($k_css:expr, $k_name:ident, $k_gecko_type:tt, $k_state:tt, $k_flags:tt),)*]) => {
match *self {
$(NonTSPseudoClass::$name => check_flag!($flags),)*
$(NonTSPseudoClass::$s_name(..) => check_flag!($s_flags),)*
$(NonTSPseudoClass::$k_name(..) => check_flag!($k_flags),)*
NonTSPseudoClass::MozAny(_) => false,
}
}
}
apply_non_ts_list!(pseudo_class_check_is_enabled_in)
}
+ /// Returns whether the pseudo-class is enabled in content sheets.
+ fn is_enabled_in_content(&self) -> bool {
+ use gecko_bindings::structs::mozilla;
+ match self {
+ // For pseudo-classes with pref, the availability in content
+ // depends on the pref.
+ &NonTSPseudoClass::Fullscreen =>
+ unsafe { mozilla::StylePrefs_sUnprefixedFullscreenApiEnabled },
+ // Otherwise, a pseudo-class is enabled in content when it
+ // doesn't have any enabled flag.
+ _ => !self.has_any_flag(PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME),
+ }
+ }
+
/// https://drafts.csswg.org/selectors-4/#useraction-pseudos
///
/// We intentionally skip the link-related ones.
pub fn is_safe_user_action_state(&self) -> bool {
matches!(*self, NonTSPseudoClass::Hover |
NonTSPseudoClass::Active |
NonTSPseudoClass::Focus)
}
@@ -265,24 +278,21 @@ impl ::selectors::SelectorImpl for Selec
NonTSPseudoClass::Hover)
}
}
impl<'a> SelectorParser<'a> {
fn is_pseudo_class_enabled(&self,
pseudo_class: &NonTSPseudoClass)
-> bool {
- let enabled_in_ua = pseudo_class.is_enabled_in(PSEUDO_CLASS_ENABLED_IN_UA_SHEETS);
- let enabled_in_chrome = pseudo_class.is_enabled_in(PSEUDO_CLASS_ENABLED_IN_CHROME);
- if !enabled_in_ua && !enabled_in_chrome {
- true
- } else {
- (enabled_in_ua && self.in_user_agent_stylesheet()) ||
- (enabled_in_chrome && self.in_chrome_stylesheet())
- }
+ pseudo_class.is_enabled_in_content() ||
+ (self.in_user_agent_stylesheet() &&
+ pseudo_class.has_any_flag(PSEUDO_CLASS_ENABLED_IN_UA_SHEETS)) ||
+ (self.in_chrome_stylesheet() &&
+ pseudo_class.has_any_flag(PSEUDO_CLASS_ENABLED_IN_CHROME))
}
}
impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> {
type Impl = SelectorImpl;
type Error = StyleParseError<'i>;
fn is_pseudo_element_allows_single_colon(name: &CowRcStr<'i>) -> bool {