mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #10461 - bholley:per_product, r=SimonSapin
Add some machinery to allow us to disable CSS properties/values per-product Here's an initial stab at solving the issues @SimonSapin brought up in #10408. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10461) <!-- Reviewable:end -->
This commit is contained in:
commit
2491af84fc
6 changed files with 70 additions and 21 deletions
|
@ -10,6 +10,9 @@ build = "build.rs"
|
||||||
name = "style"
|
name = "style"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
gecko = []
|
||||||
|
|
||||||
[dependencies.plugins]
|
[dependencies.plugins]
|
||||||
path = "../plugins"
|
path = "../plugins"
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,11 @@ fn main() {
|
||||||
let style = Path::new(file!()).parent().unwrap();
|
let style = Path::new(file!()).parent().unwrap();
|
||||||
let mako = style.join("Mako-0.9.1.zip");
|
let mako = style.join("Mako-0.9.1.zip");
|
||||||
let template = style.join("properties.mako.rs");
|
let template = style.join("properties.mako.rs");
|
||||||
|
let product = if cfg!(feature = "gecko") { "gecko" } else { "servo" };
|
||||||
let result = Command::new(python)
|
let result = Command::new(python)
|
||||||
.env("PYTHONPATH", &mako)
|
.env("PYTHONPATH", &mako)
|
||||||
.env("TEMPLATE", &template)
|
.env("TEMPLATE", &template)
|
||||||
|
.env("PRODUCT", product)
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
.arg(r#"
|
.arg(r#"
|
||||||
import os
|
import os
|
||||||
|
@ -48,7 +50,8 @@ import sys
|
||||||
from mako.template import Template
|
from mako.template import Template
|
||||||
from mako import exceptions
|
from mako import exceptions
|
||||||
try:
|
try:
|
||||||
print(Template(filename=os.environ['TEMPLATE'], input_encoding='utf8').render().encode('utf8'))
|
print(Template(filename=os.environ['TEMPLATE'], input_encoding='utf8').render(PRODUCT=os.environ['PRODUCT'])
|
||||||
|
.encode('utf8'))
|
||||||
except:
|
except:
|
||||||
sys.stderr.write(exceptions.text_error_template().render().encode('utf8'))
|
sys.stderr.write(exceptions.text_error_template().render().encode('utf8'))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -13,7 +13,7 @@ sys.path.insert(0, os.path.join(style, "Mako-0.9.1.zip"))
|
||||||
from mako.template import Template
|
from mako.template import Template
|
||||||
|
|
||||||
template = Template(filename=os.path.join(style, "properties.mako.rs"), input_encoding='utf8')
|
template = Template(filename=os.path.join(style, "properties.mako.rs"), input_encoding='utf8')
|
||||||
template.render()
|
template.render(PRODUCT='servo')
|
||||||
properties = dict(
|
properties = dict(
|
||||||
(p.name, {
|
(p.name, {
|
||||||
"flag": p.experimental,
|
"flag": p.experimental,
|
||||||
|
|
|
@ -47,10 +47,29 @@ def to_rust_ident(name):
|
||||||
def to_camel_case(ident):
|
def to_camel_case(ident):
|
||||||
return re.sub("_([a-z])", lambda m: m.group(1).upper(), ident.strip("_").capitalize())
|
return re.sub("_([a-z])", lambda m: m.group(1).upper(), ident.strip("_").capitalize())
|
||||||
|
|
||||||
class Longhand(object):
|
class Keyword(object):
|
||||||
def __init__(self, name, derived_from=None, custom_cascade=False, experimental=False,
|
def __init__(self, name, values, extra_gecko_values=None, extra_servo_values=None):
|
||||||
internal=False):
|
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.values = values
|
||||||
|
self.extra_gecko_values = extra_gecko_values or []
|
||||||
|
self.extra_servo_values = extra_servo_values or []
|
||||||
|
def gecko_values(self):
|
||||||
|
return self.values + self.extra_gecko_values
|
||||||
|
def servo_values(self):
|
||||||
|
return self.values + self.extra_servo_values
|
||||||
|
def values_for(self, product):
|
||||||
|
if product == "gecko":
|
||||||
|
return self.gecko_values()
|
||||||
|
elif product == "servo":
|
||||||
|
return self.servo_values()
|
||||||
|
else:
|
||||||
|
raise Exception("Bad product: " + product)
|
||||||
|
|
||||||
|
class Longhand(object):
|
||||||
|
def __init__(self, name, derived_from=None, keyword=None,
|
||||||
|
custom_cascade=False, experimental=False, internal=False):
|
||||||
|
self.name = name
|
||||||
|
self.keyword = keyword
|
||||||
self.ident = to_rust_ident(name)
|
self.ident = to_rust_ident(name)
|
||||||
self.camel_case = to_camel_case(self.ident)
|
self.camel_case = to_camel_case(self.ident)
|
||||||
self.style_struct = THIS_STYLE_STRUCT
|
self.style_struct = THIS_STYLE_STRUCT
|
||||||
|
@ -107,6 +126,11 @@ LONGHANDS = []
|
||||||
LONGHANDS_BY_NAME = {}
|
LONGHANDS_BY_NAME = {}
|
||||||
DERIVED_LONGHANDS = {}
|
DERIVED_LONGHANDS = {}
|
||||||
SHORTHANDS = []
|
SHORTHANDS = []
|
||||||
|
CONFIG = {}
|
||||||
|
|
||||||
|
def set_product(p):
|
||||||
|
global CONFIG
|
||||||
|
CONFIG['product'] = p
|
||||||
|
|
||||||
def new_style_struct(name, is_inherited, gecko_name=None, additional_methods=None):
|
def new_style_struct(name, is_inherited, gecko_name=None, additional_methods=None):
|
||||||
global THIS_STYLE_STRUCT
|
global THIS_STYLE_STRUCT
|
||||||
|
@ -126,19 +150,32 @@ def switch_to_style_struct(name):
|
||||||
fail()
|
fail()
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
// Work around Mako's really annoying namespacing setup.
|
||||||
|
//
|
||||||
|
// The above code runs when the template is loaded, rather than when it's
|
||||||
|
// rendered, so it can create global variables, doesn't have access to
|
||||||
|
// arguments passed to render(). On the flip side, there are various situations,
|
||||||
|
// such as code in the body of a def-used-as-tag, where our python code has
|
||||||
|
// access to global variables but not to render() arguments. Hack around this
|
||||||
|
// by stashing render arguments in a global.
|
||||||
|
<% CONFIG['product'] = PRODUCT %>
|
||||||
|
|
||||||
pub mod longhands {
|
pub mod longhands {
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use values::specified;
|
use values::specified;
|
||||||
|
|
||||||
<%def name="raw_longhand(name, derived_from=None, custom_cascade=False, experimental=False,
|
<%def name="raw_longhand(name, keyword=None, derived_from=None, products='gecko,servo',
|
||||||
internal=False)">
|
custom_cascade=False, experimental=False, internal=False)">
|
||||||
<%
|
<%
|
||||||
|
if not CONFIG['product'] in products:
|
||||||
|
return ""
|
||||||
if derived_from is not None:
|
if derived_from is not None:
|
||||||
derived_from = derived_from.split()
|
derived_from = derived_from.split()
|
||||||
|
|
||||||
property = Longhand(name,
|
property = Longhand(name,
|
||||||
derived_from=derived_from,
|
derived_from=derived_from,
|
||||||
|
keyword=keyword,
|
||||||
custom_cascade=custom_cascade,
|
custom_cascade=custom_cascade,
|
||||||
experimental=experimental,
|
experimental=experimental,
|
||||||
internal=internal)
|
internal=internal)
|
||||||
|
@ -267,11 +304,11 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="longhand(name, derived_from=None, custom_cascade=False, experimental=False,
|
<%def name="longhand(name, derived_from=None, keyword=None, products='gecko,servo',
|
||||||
internal=False)">
|
custom_cascade=False, experimental=False, internal=False)">
|
||||||
<%self:raw_longhand name="${name}" derived_from="${derived_from}"
|
<%self:raw_longhand name="${name}" derived_from="${derived_from}" keyword="${keyword}"
|
||||||
custom_cascade="${custom_cascade}" experimental="${experimental}"
|
products="${products}" custom_cascade="${custom_cascade}"
|
||||||
internal="${internal}">
|
experimental="${experimental}" internal="${internal}">
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
% if derived_from is None:
|
% if derived_from is None:
|
||||||
pub fn parse_specified(context: &ParserContext, input: &mut Parser)
|
pub fn parse_specified(context: &ParserContext, input: &mut Parser)
|
||||||
|
@ -282,15 +319,19 @@ pub mod longhands {
|
||||||
</%self:raw_longhand>
|
</%self:raw_longhand>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="single_keyword_computed(name, values, custom_cascade=False, experimental=False,
|
<%def name="single_keyword_computed(name, values, products='gecko,servo',
|
||||||
internal=False)">
|
extra_gecko_values=None, extra_servo_values=None,
|
||||||
<%self:longhand name="${name}" custom_cascade="${custom_cascade}"
|
custom_cascade=False, experimental=False, internal=False)">
|
||||||
experimental="${experimental}" internal="${internal}">
|
<%self:longhand name="${name}" keyword="${Keyword(name, values.split(),
|
||||||
|
extra_gecko_values,
|
||||||
|
extra_servo_values)}"
|
||||||
|
products="${products}" custom_cascade="${custom_cascade}"
|
||||||
|
experimental="${experimental}" internal="${internal}">
|
||||||
pub use self::computed_value::T as SpecifiedValue;
|
pub use self::computed_value::T as SpecifiedValue;
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
define_css_keyword_enum! { T:
|
define_css_keyword_enum! { T:
|
||||||
% for value in values.split():
|
% for value in LONGHANDS_BY_NAME[name].keyword.values_for(CONFIG['product']):
|
||||||
"${value}" => ${to_rust_ident(value)},
|
"${value}" => ${to_rust_ident(value)},
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
@ -305,9 +346,10 @@ pub mod longhands {
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="single_keyword(name, values, experimental=False, internal=False)">
|
<%def name="single_keyword(name, values, products='gecko,servo', experimental=False, internal=False)">
|
||||||
<%self:single_keyword_computed name="${name}"
|
<%self:single_keyword_computed name="${name}"
|
||||||
values="${values}"
|
values="${values}"
|
||||||
|
products="${products}"
|
||||||
experimental="${experimental}"
|
experimental="${experimental}"
|
||||||
internal="${internal}">
|
internal="${internal}">
|
||||||
use values::computed::ComputedValueAsSpecified;
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
@ -315,8 +357,8 @@ pub mod longhands {
|
||||||
</%self:single_keyword_computed>
|
</%self:single_keyword_computed>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="predefined_type(name, type, initial_value, parse_method='parse')">
|
<%def name="predefined_type(name, type, initial_value, parse_method='parse', products='gecko,servo')">
|
||||||
<%self:longhand name="${name}">
|
<%self:longhand name="${name}" products="${products}">
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
pub type SpecifiedValue = specified::${type};
|
pub type SpecifiedValue = specified::${type};
|
||||||
|
|
|
@ -37,3 +37,4 @@ path = "../../components/util"
|
||||||
|
|
||||||
[dependencies.style]
|
[dependencies.style]
|
||||||
path = "../../components/style"
|
path = "../../components/style"
|
||||||
|
features = ["gecko"]
|
||||||
|
|
|
@ -59,7 +59,7 @@ from mako.template import Template
|
||||||
from mako import exceptions
|
from mako import exceptions
|
||||||
try:
|
try:
|
||||||
style_template = Template(filename=os.environ['STYLE_TEMPLATE'], input_encoding='utf8')
|
style_template = Template(filename=os.environ['STYLE_TEMPLATE'], input_encoding='utf8')
|
||||||
style_template.render()
|
style_template.render(PRODUCT='gecko')
|
||||||
|
|
||||||
geckolib_template = Template(filename=os.environ['GECKOLIB_TEMPLATE'], input_encoding='utf8')
|
geckolib_template = Template(filename=os.environ['GECKOLIB_TEMPLATE'], input_encoding='utf8')
|
||||||
output = geckolib_template.render(STYLE_STRUCTS = style_template.module.STYLE_STRUCTS,
|
output = geckolib_template.render(STYLE_STRUCTS = style_template.module.STYLE_STRUCTS,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue