style: Add machinery to handle properties enabled in chrome.

This commit is contained in:
Emilio Cobos Álvarez 2017-11-16 03:06:07 +01:00
parent 128bb02e1d
commit bbfb7a47eb
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
2 changed files with 69 additions and 27 deletions

View file

@ -210,6 +210,13 @@ class Longhand(object):
return bool(self.gecko_pref)
return bool(self.servo_pref)
# FIXME(emilio): Shorthand and Longhand should really share a base class.
def explicitly_enabled_in_ua_sheets(self):
return self.internal
# TODO(emilio): Change the `internal` field to something like `enabled_in`.
def explicitly_enabled_in_chrome(self):
return False
class Shorthand(object):
@ -264,6 +271,12 @@ class Shorthand(object):
return bool(self.gecko_pref)
return bool(self.servo_pref)
def explicitly_enabled_in_ua_sheets(self):
return self.internal
def explicitly_enabled_in_chrome(self):
return False
class Alias(object):
def __init__(self, name, original):
@ -276,6 +289,17 @@ class Alias(object):
self.allowed_in_page_rule = original.allowed_in_page_rule
self.allowed_in_keyframe_block = original.allowed_in_keyframe_block
def experimental(self, product):
if product == "gecko":
return bool(self.gecko_pref)
return bool(self.servo_pref)
def explicitly_enabled_in_ua_sheets(self):
return self.internal
def explicitly_enabled_in_chrome(self):
return False
class Method(object):
def __init__(self, name, return_type=None, arg_types=None, is_mut=False):

View file

@ -239,7 +239,7 @@ impl NonCustomPropertyIdSet {
static ${name}: NonCustomPropertyIdSet = NonCustomPropertyIdSet {
<%
storage = [0] * ((len(data.longhands) + len(data.shorthands) + len(data.all_aliases()) - 1 + 32) / 32)
for i, property in enumerate(data.longhands + data.shorthands):
for i, property in enumerate(data.longhands + data.shorthands + data.all_aliases()):
if is_member(property):
storage[i / 32] |= 1 << (i % 32)
%>
@ -1158,6 +1158,7 @@ impl PropertyId {
Some(context) => context,
None => {
default = PropertyParserContext {
in_chrome_stylesheet: false,
stylesheet_origin: Origin::Author,
rule_type: CssRuleType::Style,
};
@ -1287,12 +1288,22 @@ impl PropertyId {
_ => {}
}
// For properties that are experimental but not internal, the pref will
// control its availability in all sheets. For properties that are
// both experimental and internal, the pref only controls its
// availability in non-UA sheets (and in UA sheets it is always available).
${id_set("INTERNAL", lambda p: p.internal)}
// The semantics of these are kinda hard to reason about, what follows
// is a description of the different combinations that can happen with
// these three sets.
//
// Experimental properties are generally controlled by prefs, but an
// experimental property explicitly enabled in certain context (UA or
// chrome sheets) is always usable in the context regardless of the
// pref value.
//
// Non-experimental properties are either normal properties which are
// usable everywhere, or internal-only properties which are only usable
// in certain context they are explicitly enabled in.
${id_set("ENABLED_IN_UA_SHEETS", lambda p: p.explicitly_enabled_in_ua_sheets())}
${id_set("ENABLED_IN_CHROME", lambda p: p.explicitly_enabled_in_chrome())}
${id_set("EXPERIMENTAL", lambda p: p.experimental(product))}
${id_set("ALWAYS_ENABLED", lambda p: not p.experimental(product) and not p.explicitly_enabled_in_ua_sheets())}
let passes_pref_check = || {
% if product == "servo":
@ -1305,42 +1316,48 @@ impl PropertyId {
% endif
% endfor
];
match PREF_NAME[id.0] {
None => true,
Some(pref) => PREFS.get(pref).as_boolean().unwrap_or(false)
}
% endif
% if product == "gecko":
let pref = match PREF_NAME[id.0] {
None => return true,
Some(pref) => pref,
};
PREFS.get(pref).as_boolean().unwrap_or(false)
% else:
let id = match alias {
Some(alias_id) => alias_id.to_nscsspropertyid().unwrap(),
None => self.to_nscsspropertyid().unwrap(),
};
unsafe { structs::nsCSSProps_gPropertyEnabled[id as usize] }
% endif
};
if INTERNAL.contains(id) {
if context.stylesheet_origin != Origin::UserAgent {
if EXPERIMENTAL.contains(id) {
if !passes_pref_check() {
return Err(())
}
} else {
return Err(())
}
}
} else {
if EXPERIMENTAL.contains(id) && !passes_pref_check() {
return Err(());
}
if ALWAYS_ENABLED.contains(id) {
return Ok(())
}
Ok(())
if EXPERIMENTAL.contains(id) && passes_pref_check() {
return Ok(())
}
if context.stylesheet_origin == Origin::UserAgent &&
ENABLED_IN_UA_SHEETS.contains(id)
{
return Ok(())
}
if context.in_chrome_stylesheet && ENABLED_IN_CHROME.contains(id) {
return Ok(())
}
Err(())
}
}
/// Parsing Context for PropertyId.
pub struct PropertyParserContext {
/// Whether the property is parsed in a chrome:// stylesheet.
pub in_chrome_stylesheet: bool,
/// The Origin of the stylesheet, whether it's a user,
/// author or user-agent stylesheet.
pub stylesheet_origin: Origin,
@ -1352,6 +1369,7 @@ impl PropertyParserContext {
/// Creates a PropertyParserContext with given stylesheet origin and rule type.
pub fn new(context: &ParserContext) -> Self {
Self {
in_chrome_stylesheet: context.in_chrome_stylesheet(),
stylesheet_origin: context.stylesheet_origin,
rule_type: context.rule_type(),
}