From 652633aee283f111c0dec4dac9221d29452c2456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 16 Mar 2018 18:25:55 +0100 Subject: [PATCH 1/4] style: Cleanup @-moz-document parsing a bit. MozReview-Commit-ID: 7vd0BLAqM0v Bug: 1446470 Reviewed-by: xidorn --- components/style/stylesheets/document_rule.rs | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/components/style/stylesheets/document_rule.rs b/components/style/stylesheets/document_rule.rs index 3edfbbb6362..089fa2c6799 100644 --- a/components/style/stylesheets/document_rule.rs +++ b/components/style/stylesheets/document_rule.rs @@ -6,7 +6,7 @@ //! initially in CSS Conditional Rules Module Level 3, @document has been postponed to the level 4. //! We implement the prefixed `@-moz-document`. -use cssparser::{Parser, Token, SourceLocation}; +use cssparser::{Parser, SourceLocation}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; use media_queries::Device; @@ -15,7 +15,7 @@ use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt::{self, Write}; use str::CssStringWriter; -use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; +use style_traits::{CssWriter, ParseError, ToCss}; use stylesheets::CssRules; use values::CssUrl; @@ -103,13 +103,8 @@ macro_rules! parse_quoted_or_unquoted_string { $input.parse_nested_block(|input| { let start = input.position(); input.parse_entirely(|input| { - let location = input.current_source_location(); - match *input.next()? { - Token::QuotedString(ref value) => { - Ok($url_matching_function(value.as_ref().to_owned())) - }, - ref t => Err(location.new_unexpected_token_error(t.clone())), - } + let string = input.expect_string()?; + Ok($url_matching_function(string.as_ref().to_owned())) }).or_else(|_: ParseError| { while let Ok(_) = input.next() {} Ok($url_matching_function(input.slice_from(start).to_string())) @@ -120,21 +115,26 @@ macro_rules! parse_quoted_or_unquoted_string { impl UrlMatchingFunction { /// Parse a URL matching function for a`@document` rule's condition. - pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result> { + pub fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { if input.try(|input| input.expect_function_matching("url-prefix")).is_ok() { - 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)) + return parse_quoted_or_unquoted_string!(input, UrlMatchingFunction::UrlPrefix) } + + 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")] @@ -182,16 +182,18 @@ pub struct DocumentCondition(#[css(iterable)] Vec); impl DocumentCondition { /// Parse a document condition. - pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result> { + pub fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { input.parse_comma_separated(|input| UrlMatchingFunction::parse(context, input)) .map(DocumentCondition) } /// Evaluate a document condition. 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) - ) + }) } } From 9bb4033ec3f52fb5a17b9cd7a5b2f157b895d7db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 16 Mar 2018 18:50:16 +0100 Subject: [PATCH 2/4] style: Allow @-moz-document url-prefix() on content. MozReview-Commit-ID: zaT41fpsDT Bug: 1446470 Reviewed-by: xidorn --- components/style/stylesheets/document_rule.rs | 47 +++++++++++++++++-- components/style/stylesheets/rule_parser.rs | 13 ----- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/components/style/stylesheets/document_rule.rs b/components/style/stylesheets/document_rule.rs index 089fa2c6799..596ea487510 100644 --- a/components/style/stylesheets/document_rule.rs +++ b/components/style/stylesheets/document_rule.rs @@ -15,7 +15,7 @@ use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt::{self, Write}; use str::CssStringWriter; -use style_traits::{CssWriter, ParseError, ToCss}; +use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; use stylesheets::CssRules; use values::CssUrl; @@ -186,8 +186,17 @@ impl DocumentCondition { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - input.parse_comma_separated(|input| UrlMatchingFunction::parse(context, input)) - .map(DocumentCondition) + 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. @@ -196,4 +205,36 @@ impl DocumentCondition { 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; + } + + // 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 + } + } } diff --git a/components/style/stylesheets/rule_parser.rs b/components/style/stylesheets/rule_parser.rs index 5bc3fb8f050..714a0730882 100644 --- a/components/style/stylesheets/rule_parser.rs +++ b/components/style/stylesheets/rule_parser.rs @@ -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)?; Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Document(cond, location))) }, From 322113a393f3a443663c6f208f5ab7cce08b47d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 17 Mar 2018 00:00:36 +0100 Subject: [PATCH 3/4] style: Add another pref to control the url-prefix hack. MozReview-Commit-ID: D4qL0oO69Uh Bug: 1446470 Reviewed-by: xidorn --- components/style/stylesheets/document_rule.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/style/stylesheets/document_rule.rs b/components/style/stylesheets/document_rule.rs index 596ea487510..ad2c9d86219 100644 --- a/components/style/stylesheets/document_rule.rs +++ b/components/style/stylesheets/document_rule.rs @@ -224,6 +224,10 @@ impl DocumentCondition { return true; } + if !unsafe { structs::StylePrefs_sMozDocumentURLPrefixHackEnabled } { + return false; + } + // Allow a single url-prefix() for compatibility. // // See bug 1446470 and dependencies. From c43de8ff29ce7a365405f0d09fc46b61f333dc71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Mar 2018 11:04:31 +0100 Subject: [PATCH 4/4] style: Update bindings. --- components/style/gecko/generated/structs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/style/gecko/generated/structs.rs b/components/style/gecko/generated/structs.rs index 5374f420c7d..38155578238 100644 --- a/components/style/gecko/generated/structs.rs +++ b/components/style/gecko/generated/structs.rs @@ -12244,6 +12244,10 @@ pub mod root { #[link_name = "\u{1}_ZN7mozilla10StylePrefs28sMozDocumentEnabledInContentE"] pub static mut StylePrefs_sMozDocumentEnabledInContent: bool; } + extern "C" { + #[link_name = "\u{1}_ZN7mozilla10StylePrefs28sMozDocumentURLPrefixHackEnabledE"] + pub static mut StylePrefs_sMozDocumentURLPrefixHackEnabled: bool; + } extern "C" { #[link_name = "\u{1}_ZN7mozilla10StylePrefs32sGridTemplateSubgridValueEnabledE"] pub static mut StylePrefs_sGridTemplateSubgridValueEnabled: bool;