mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Auto merge of #20338 - emilio:moz-document-haxx, r=xidorn
Add a pref to allow parsing @-moz-document url-prefix in content. Bug: 1446470 Reviewed-by: xidorn <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20338) <!-- Reviewable:end -->
This commit is contained in:
commit
28348ba6b6
3 changed files with 78 additions and 40 deletions
|
@ -12244,6 +12244,10 @@ pub mod root {
|
||||||
#[link_name = "\u{1}_ZN7mozilla10StylePrefs28sMozDocumentEnabledInContentE"]
|
#[link_name = "\u{1}_ZN7mozilla10StylePrefs28sMozDocumentEnabledInContentE"]
|
||||||
pub static mut StylePrefs_sMozDocumentEnabledInContent: bool;
|
pub static mut StylePrefs_sMozDocumentEnabledInContent: bool;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
#[link_name = "\u{1}_ZN7mozilla10StylePrefs28sMozDocumentURLPrefixHackEnabledE"]
|
||||||
|
pub static mut StylePrefs_sMozDocumentURLPrefixHackEnabled: bool;
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#[link_name = "\u{1}_ZN7mozilla10StylePrefs32sGridTemplateSubgridValueEnabledE"]
|
#[link_name = "\u{1}_ZN7mozilla10StylePrefs32sGridTemplateSubgridValueEnabledE"]
|
||||||
pub static mut StylePrefs_sGridTemplateSubgridValueEnabled: bool;
|
pub static mut StylePrefs_sGridTemplateSubgridValueEnabled: bool;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//! initially in CSS Conditional Rules Module Level 3, @document has been postponed to the level 4.
|
//! initially in CSS Conditional Rules Module Level 3, @document has been postponed to the level 4.
|
||||||
//! We implement the prefixed `@-moz-document`.
|
//! We implement the prefixed `@-moz-document`.
|
||||||
|
|
||||||
use cssparser::{Parser, Token, SourceLocation};
|
use cssparser::{Parser, SourceLocation};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||||
use media_queries::Device;
|
use media_queries::Device;
|
||||||
|
@ -103,13 +103,8 @@ macro_rules! parse_quoted_or_unquoted_string {
|
||||||
$input.parse_nested_block(|input| {
|
$input.parse_nested_block(|input| {
|
||||||
let start = input.position();
|
let start = input.position();
|
||||||
input.parse_entirely(|input| {
|
input.parse_entirely(|input| {
|
||||||
let location = input.current_source_location();
|
let string = input.expect_string()?;
|
||||||
match *input.next()? {
|
Ok($url_matching_function(string.as_ref().to_owned()))
|
||||||
Token::QuotedString(ref value) => {
|
|
||||||
Ok($url_matching_function(value.as_ref().to_owned()))
|
|
||||||
},
|
|
||||||
ref t => Err(location.new_unexpected_token_error(t.clone())),
|
|
||||||
}
|
|
||||||
}).or_else(|_: ParseError| {
|
}).or_else(|_: ParseError| {
|
||||||
while let Ok(_) = input.next() {}
|
while let Ok(_) = input.next() {}
|
||||||
Ok($url_matching_function(input.slice_from(start).to_string()))
|
Ok($url_matching_function(input.slice_from(start).to_string()))
|
||||||
|
@ -120,21 +115,26 @@ macro_rules! parse_quoted_or_unquoted_string {
|
||||||
|
|
||||||
impl UrlMatchingFunction {
|
impl UrlMatchingFunction {
|
||||||
/// Parse a URL matching function for a`@document` rule's condition.
|
/// Parse a URL matching function for a`@document` rule's condition.
|
||||||
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
pub fn parse<'i, 't>(
|
||||||
-> Result<UrlMatchingFunction, ParseError<'i>> {
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|input| input.expect_function_matching("url-prefix")).is_ok() {
|
if input.try(|input| input.expect_function_matching("url-prefix")).is_ok() {
|
||||||
parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::UrlPrefix)
|
return parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::UrlPrefix)
|
||||||
} else if input.try(|input| input.expect_function_matching("domain")).is_ok() {
|
|
||||||
parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain)
|
|
||||||
} else if input.try(|input| input.expect_function_matching("regexp")).is_ok() {
|
|
||||||
input.parse_nested_block(|input| {
|
|
||||||
Ok(UrlMatchingFunction::Regexp(input.expect_string()?.as_ref().to_owned()))
|
|
||||||
})
|
|
||||||
} else if let Ok(url) = input.try(|input| CssUrl::parse(context, input)) {
|
|
||||||
Ok(UrlMatchingFunction::Url(url))
|
|
||||||
} else {
|
|
||||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if input.try(|input| input.expect_function_matching("domain")).is_ok() {
|
||||||
|
return parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::Domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.try(|input| input.expect_function_matching("regexp")).is_ok() {
|
||||||
|
return input.parse_nested_block(|input| {
|
||||||
|
Ok(UrlMatchingFunction::Regexp(input.expect_string()?.as_ref().to_owned()))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = CssUrl::parse(context, input)?;
|
||||||
|
Ok(UrlMatchingFunction::Url(url))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -182,16 +182,63 @@ pub struct DocumentCondition(#[css(iterable)] Vec<UrlMatchingFunction>);
|
||||||
|
|
||||||
impl DocumentCondition {
|
impl DocumentCondition {
|
||||||
/// Parse a document condition.
|
/// Parse a document condition.
|
||||||
pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
pub fn parse<'i, 't>(
|
||||||
-> Result<Self, ParseError<'i>> {
|
context: &ParserContext,
|
||||||
input.parse_comma_separated(|input| UrlMatchingFunction::parse(context, input))
|
input: &mut Parser<'i, 't>,
|
||||||
.map(DocumentCondition)
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
let conditions = input.parse_comma_separated(|input| {
|
||||||
|
UrlMatchingFunction::parse(context, input)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let condition = DocumentCondition(conditions);
|
||||||
|
if !condition.allowed_in(context) {
|
||||||
|
return Err(input.new_custom_error(
|
||||||
|
StyleParseErrorKind::UnsupportedAtRule("-moz-document".into())
|
||||||
|
))
|
||||||
|
}
|
||||||
|
Ok(condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a document condition.
|
/// Evaluate a document condition.
|
||||||
pub fn evaluate(&self, device: &Device) -> bool {
|
pub fn evaluate(&self, device: &Device) -> bool {
|
||||||
self.0.iter().any(|ref url_matching_function|
|
self.0.iter().any(|url_matching_function| {
|
||||||
url_matching_function.evaluate(device)
|
url_matching_function.evaluate(device)
|
||||||
)
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
fn allowed_in(&self, _: &ParserContext) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
fn allowed_in(&self, context: &ParserContext) -> bool {
|
||||||
|
use gecko_bindings::structs;
|
||||||
|
use stylesheets::Origin;
|
||||||
|
|
||||||
|
if context.stylesheet_origin != Origin::Author {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if unsafe { structs::StylePrefs_sMozDocumentEnabledInContent } {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !unsafe { structs::StylePrefs_sMozDocumentURLPrefixHackEnabled } {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow a single url-prefix() for compatibility.
|
||||||
|
//
|
||||||
|
// See bug 1446470 and dependencies.
|
||||||
|
if self.0.len() != 1 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(emilio): This technically allows url-prefix("") too, but...
|
||||||
|
match self.0[0] {
|
||||||
|
UrlMatchingFunction::UrlPrefix(ref prefix) => prefix.is_empty(),
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,19 +422,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
{
|
|
||||||
use gecko_bindings::structs;
|
|
||||||
|
|
||||||
if self.stylesheet_origin == Origin::Author &&
|
|
||||||
unsafe { !structs::StylePrefs_sMozDocumentEnabledInContent }
|
|
||||||
{
|
|
||||||
return Err(input.new_custom_error(
|
|
||||||
StyleParseErrorKind::UnsupportedAtRule(name.clone())
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let cond = DocumentCondition::parse(self.context, input)?;
|
let cond = DocumentCondition::parse(self.context, input)?;
|
||||||
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Document(cond, location)))
|
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Document(cond, location)))
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue