aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-05-15 05:28:50 -0500
committerGitHub <noreply@github.com>2017-05-15 05:28:50 -0500
commit5cd8265f9a279e1cebe84218e691e7f80a541fb9 (patch)
tree4cf4e29f89ce3c5c5dc1f5095602bb15ee15ec2e /components
parent94e977efebb93ef411222edc219bc9f30430a3f9 (diff)
parentbc156cfe1c2f52a6f609f1ad1a28dcbfd36a9d4e (diff)
downloadservo-5cd8265f9a279e1cebe84218e691e7f80a541fb9.tar.gz
servo-5cd8265f9a279e1cebe84218e691e7f80a541fb9.zip
Auto merge of #16835 - ferjm:bug1350175.line.column.css.rules, r=upsuper,SimonSapin
Stylo: Bug 1350175 - Support getting line / column number of CSS rules - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors Bugzilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1350175 <!-- 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/16835) <!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r--components/style/encoding_support.rs3
-rw-r--r--components/style/font_face.rs11
-rw-r--r--components/style/gecko/generated/bindings.rs28
-rw-r--r--components/style/gecko/rules.rs4
-rw-r--r--components/style/stylesheets.rs85
5 files changed, 93 insertions, 38 deletions
diff --git a/components/style/encoding_support.rs b/components/style/encoding_support.rs
index 92620378b30..af37e20889a 100644
--- a/components/style/encoding_support.rs
+++ b/components/style/encoding_support.rs
@@ -88,6 +88,7 @@ impl Stylesheet {
&string,
url_data,
stylesheet_loader,
- error_reporter)
+ error_reporter,
+ 0)
}
}
diff --git a/components/style/font_face.rs b/components/style/font_face.rs
index 94dcc61212d..0bd6640488e 100644
--- a/components/style/font_face.rs
+++ b/components/style/font_face.rs
@@ -12,6 +12,7 @@
use computed_values::{font_style, font_weight, font_stretch};
use computed_values::font_family::FamilyName;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
+use cssparser::SourceLocation;
#[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors;
#[cfg(feature = "gecko")] use cssparser::UnicodeRange;
use parser::{ParserContext, log_css_error, Parse};
@@ -74,8 +75,10 @@ impl ToCss for UrlSource {
/// Parse the block inside a `@font-face` rule.
///
/// Note that the prelude parsing code lives in the `stylesheets` module.
-pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser) -> FontFaceRuleData {
+pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser, location: SourceLocation)
+ -> FontFaceRuleData {
let mut rule = FontFaceRuleData::empty();
+ rule.source_location = location;
{
let parser = FontFaceRuleParser {
context: context,
@@ -186,6 +189,8 @@ macro_rules! font_face_descriptors_common {
#[$doc]
pub $ident: Option<$ty>,
)*
+ /// Line and column of the @font-face rule source code.
+ pub source_location: SourceLocation,
}
impl FontFaceRuleData {
@@ -194,6 +199,10 @@ macro_rules! font_face_descriptors_common {
$(
$ident: None,
)*
+ source_location: SourceLocation {
+ line: 0,
+ column: 0,
+ },
}
}
diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs
index bf386498df9..00e623b931f 100644
--- a/components/style/gecko/generated/bindings.rs
+++ b/components/style/gecko/generated/bindings.rs
@@ -1255,7 +1255,8 @@ extern "C" {
-> *const ::std::os::raw::c_char;
}
extern "C" {
- pub fn Gecko_CSSFontFaceRule_Create() -> *mut nsCSSFontFaceRule;
+ pub fn Gecko_CSSFontFaceRule_Create(line: u32, column: u32)
+ -> *mut nsCSSFontFaceRule;
}
extern "C" {
pub fn Gecko_CSSFontFaceRule_GetCssText(rule: *const nsCSSFontFaceRule,
@@ -1621,7 +1622,8 @@ extern "C" {
media_list:
*const RawServoMediaList,
extra_data:
- *mut RawGeckoURLExtraData)
+ *mut RawGeckoURLExtraData,
+ line_number_offset: u32)
-> RawServoStyleSheetStrong;
}
extern "C" {
@@ -1636,7 +1638,8 @@ extern "C" {
*mut ServoStyleSheet,
data: *const nsACString,
extra_data:
- *mut RawGeckoURLExtraData);
+ *mut RawGeckoURLExtraData,
+ line_number_offset: u32);
}
extern "C" {
pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed)
@@ -1726,7 +1729,8 @@ extern "C" {
}
extern "C" {
pub fn Servo_CssRules_GetStyleRuleAt(rules: ServoCssRulesBorrowed,
- index: u32)
+ index: u32, line: *mut u32,
+ column: *mut u32)
-> RawServoStyleRuleStrong;
}
extern "C" {
@@ -1739,7 +1743,8 @@ extern "C" {
}
extern "C" {
pub fn Servo_CssRules_GetMediaRuleAt(rules: ServoCssRulesBorrowed,
- index: u32)
+ index: u32, line: *mut u32,
+ column: *mut u32)
-> RawServoMediaRuleStrong;
}
extern "C" {
@@ -1756,7 +1761,8 @@ extern "C" {
}
extern "C" {
pub fn Servo_CssRules_GetNamespaceRuleAt(rules: ServoCssRulesBorrowed,
- index: u32)
+ index: u32, line: *mut u32,
+ column: *mut u32)
-> RawServoNamespaceRuleStrong;
}
extern "C" {
@@ -1769,7 +1775,9 @@ extern "C" {
}
extern "C" {
pub fn Servo_CssRules_GetPageRuleAt(rules: ServoCssRulesBorrowed,
- index: u32) -> RawServoPageRuleStrong;
+ index: u32, line: *mut u32,
+ column: *mut u32)
+ -> RawServoPageRuleStrong;
}
extern "C" {
pub fn Servo_PageRule_Debug(rule: RawServoPageRuleBorrowed,
@@ -1781,7 +1789,8 @@ extern "C" {
}
extern "C" {
pub fn Servo_CssRules_GetSupportsRuleAt(rules: ServoCssRulesBorrowed,
- index: u32)
+ index: u32, line: *mut u32,
+ column: *mut u32)
-> RawServoSupportsRuleStrong;
}
extern "C" {
@@ -1798,7 +1807,8 @@ extern "C" {
}
extern "C" {
pub fn Servo_CssRules_GetDocumentRuleAt(rules: ServoCssRulesBorrowed,
- index: u32)
+ index: u32, line: *mut u32,
+ column: *mut u32)
-> RawServoDocumentRuleStrong;
}
extern "C" {
diff --git a/components/style/gecko/rules.rs b/components/style/gecko/rules.rs
index d2d78de238a..7af5fc599b7 100644
--- a/components/style/gecko/rules.rs
+++ b/components/style/gecko/rules.rs
@@ -117,7 +117,9 @@ impl ToNsCssValue for Vec<UnicodeRange> {
impl From<FontFaceRuleData> for FontFaceRule {
fn from(data: FontFaceRuleData) -> FontFaceRule {
let mut result = unsafe {
- UniqueRefPtr::from_addrefed(bindings::Gecko_CSSFontFaceRule_Create())
+ UniqueRefPtr::from_addrefed(bindings::Gecko_CSSFontFaceRule_Create(
+ data.source_location.line as u32, data.source_location.column as u32
+ ))
};
data.set_descriptors(&mut result.mDecl.mDescriptors);
result.get()
diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs
index 84b5753fb9b..98c13948121 100644
--- a/components/style/stylesheets.rs
+++ b/components/style/stylesheets.rs
@@ -10,7 +10,7 @@ use {Atom, Prefix, Namespace};
use context::QuirksMode;
use counter_style::{CounterStyleRule, parse_counter_style_name, parse_counter_style_body};
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser};
-use cssparser::{AtRuleType, RuleListParser, parse_one_rule};
+use cssparser::{AtRuleType, RuleListParser, parse_one_rule, SourceLocation};
use cssparser::ToCss as ParserToCss;
use document_condition::DocumentCondition;
use error_reporting::{ParseErrorReporter, NullReporter};
@@ -489,12 +489,22 @@ impl ToCssWithGuard for CssRule {
}
}
+/// Calculates the location of a rule's source given an offset.
+fn get_location_with_offset(location: SourceLocation, offset: u64)
+ -> SourceLocation {
+ SourceLocation {
+ line: location.line + offset as usize - 1,
+ column: location.column,
+ }
+}
+
#[derive(Debug, PartialEq)]
#[allow(missing_docs)]
pub struct NamespaceRule {
/// `None` for the default Namespace
pub prefix: Option<Prefix>,
pub url: Namespace,
+ pub source_location: SourceLocation,
}
impl ToCssWithGuard for NamespaceRule {
@@ -581,6 +591,7 @@ impl ToCssWithGuard for KeyframesRule {
pub struct MediaRule {
pub media_queries: Arc<Locked<MediaList>>,
pub rules: Arc<Locked<CssRules>>,
+ pub source_location: SourceLocation,
}
impl ToCssWithGuard for MediaRule {
@@ -609,6 +620,8 @@ pub struct SupportsRule {
pub rules: Arc<Locked<CssRules>>,
/// The result of evaluating the condition
pub enabled: bool,
+ /// The line and column of the rule's source code.
+ pub source_location: SourceLocation,
}
impl ToCssWithGuard for SupportsRule {
@@ -630,15 +643,19 @@ impl ToCssWithGuard for SupportsRule {
///
/// [page]: https://drafts.csswg.org/css2/page.html#page-box
/// [page-selectors]: https://drafts.csswg.org/css2/page.html#page-selectors
+#[allow(missing_docs)]
#[derive(Debug)]
-pub struct PageRule(pub Arc<Locked<PropertyDeclarationBlock>>);
+pub struct PageRule {
+ pub block: Arc<Locked<PropertyDeclarationBlock>>,
+ pub source_location: SourceLocation,
+}
impl ToCssWithGuard for PageRule {
// Serialization of PageRule is not specced, adapted from steps for StyleRule.
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write {
dest.write_str("@page { ")?;
- let declaration_block = self.0.read_with(guard);
+ let declaration_block = self.block.read_with(guard);
declaration_block.to_css(dest)?;
if declaration_block.declarations().len() > 0 {
write!(dest, " ")?;
@@ -652,6 +669,7 @@ impl ToCssWithGuard for PageRule {
pub struct StyleRule {
pub selectors: SelectorList<SelectorImpl>,
pub block: Arc<Locked<PropertyDeclarationBlock>>,
+ pub source_location: SourceLocation,
}
impl ToCssWithGuard for StyleRule {
@@ -686,6 +704,8 @@ pub struct DocumentRule {
pub condition: DocumentCondition,
/// Child rules
pub rules: Arc<Locked<CssRules>>,
+ /// The line and column of the rule's source code.
+ pub source_location: SourceLocation,
}
impl ToCssWithGuard for DocumentRule {
@@ -708,15 +728,15 @@ impl Stylesheet {
css: &str,
url_data: &UrlExtraData,
stylesheet_loader: Option<&StylesheetLoader>,
- error_reporter: &ParseErrorReporter) {
+ error_reporter: &ParseErrorReporter,
+ line_number_offset: u64) {
let mut namespaces = Namespaces::default();
// FIXME: we really should update existing.url_data with the given url_data,
// otherwise newly inserted rule may not have the right base url.
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
css, url_data, existing.origin, &mut namespaces,
&existing.shared_lock, stylesheet_loader, error_reporter,
- existing.quirks_mode, 0u64);
-
+ existing.quirks_mode, line_number_offset);
*existing.namespaces.write() = namespaces;
existing.dirty_on_viewport_size_change
.store(dirty_on_viewport_size_change, Ordering::Release);
@@ -996,21 +1016,21 @@ pub enum VendorPrefix {
enum AtRulePrelude {
/// A @font-face rule prelude.
- FontFace,
+ FontFace(SourceLocation),
/// A @counter-style rule prelude, with its counter style name.
CounterStyle(CustomIdent),
/// A @media rule prelude, with its media queries.
- Media(Arc<Locked<MediaList>>),
+ Media(Arc<Locked<MediaList>>, SourceLocation),
/// An @supports rule, with its conditional
- Supports(SupportsCondition),
+ Supports(SupportsCondition, SourceLocation),
/// A @viewport rule prelude.
Viewport,
/// A @keyframes rule, with its animation name and vendor prefix if exists.
Keyframes(KeyframesName, Option<VendorPrefix>),
/// A @page rule prelude.
- Page,
+ Page(SourceLocation),
/// A @document rule, with its conditional.
- Document(DocumentCondition),
+ Document(DocumentCondition, SourceLocation),
}
@@ -1066,6 +1086,9 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
if self.state.get() <= State::Namespaces {
self.state.set(State::Namespaces);
+ let location = get_location_with_offset(input.current_source_location(),
+ self.context.line_number_offset);
+
let prefix_result = input.try(|input| input.expect_ident());
let url = Namespace::from(try!(input.expect_url_or_string()));
@@ -1082,6 +1105,7 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
self.shared_lock.wrap(NamespaceRule {
prefix: opt_prefix,
url: url,
+ source_location: location,
})
))))
} else {
@@ -1176,18 +1200,20 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
fn parse_prelude(&mut self, name: &str, input: &mut Parser)
-> Result<AtRuleType<AtRulePrelude, CssRule>, ()> {
+ let location = get_location_with_offset(input.current_source_location(),
+ self.context.line_number_offset);
match_ignore_ascii_case! { name,
"media" => {
let media_queries = parse_media_query_list(self.context, input);
let arc = Arc::new(self.shared_lock.wrap(media_queries));
- Ok(AtRuleType::WithBlock(AtRulePrelude::Media(arc)))
+ Ok(AtRuleType::WithBlock(AtRulePrelude::Media(arc, location)))
},
"supports" => {
let cond = SupportsCondition::parse(input)?;
- Ok(AtRuleType::WithBlock(AtRulePrelude::Supports(cond)))
+ Ok(AtRuleType::WithBlock(AtRulePrelude::Supports(cond, location)))
},
"font-face" => {
- Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace))
+ Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace(location)))
},
"counter-style" => {
if !cfg!(feature = "gecko") {
@@ -1229,7 +1255,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
},
"page" => {
if cfg!(feature = "gecko") {
- Ok(AtRuleType::WithBlock(AtRulePrelude::Page))
+ Ok(AtRuleType::WithBlock(AtRulePrelude::Page(location)))
} else {
Err(())
}
@@ -1237,7 +1263,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
"-moz-document" => {
if cfg!(feature = "gecko") {
let cond = DocumentCondition::parse(self.context, input)?;
- Ok(AtRuleType::WithBlock(AtRulePrelude::Document(cond)))
+ Ok(AtRuleType::WithBlock(AtRulePrelude::Document(cond, location)))
} else {
Err(())
}
@@ -1248,28 +1274,30 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
fn parse_block(&mut self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CssRule, ()> {
match prelude {
- AtRulePrelude::FontFace => {
+ AtRulePrelude::FontFace(location) => {
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::FontFace));
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap(
- parse_font_face_block(&context, input).into()))))
+ parse_font_face_block(&context, input, location).into()))))
}
AtRulePrelude::CounterStyle(name) => {
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::CounterStyle));
Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap(
parse_counter_style_body(name, &context, input)?))))
}
- AtRulePrelude::Media(media_queries) => {
+ AtRulePrelude::Media(media_queries, location) => {
Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule {
media_queries: media_queries,
rules: self.parse_nested_rules(input, CssRuleType::Media),
+ source_location: location,
}))))
}
- AtRulePrelude::Supports(cond) => {
+ AtRulePrelude::Supports(cond, location) => {
let enabled = cond.eval(self.context);
Ok(CssRule::Supports(Arc::new(self.shared_lock.wrap(SupportsRule {
condition: cond,
rules: self.parse_nested_rules(input, CssRuleType::Supports),
enabled: enabled,
+ source_location: location,
}))))
}
AtRulePrelude::Viewport => {
@@ -1285,18 +1313,20 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
vendor_prefix: prefix,
}))))
}
- AtRulePrelude::Page => {
+ AtRulePrelude::Page(location) => {
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Page));
let declarations = parse_property_declaration_list(&context, input);
- Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule(
- Arc::new(self.shared_lock.wrap(declarations))
- )))))
+ Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule {
+ block: Arc::new(self.shared_lock.wrap(declarations)),
+ source_location: location,
+ }))))
}
- AtRulePrelude::Document(cond) => {
+ AtRulePrelude::Document(cond, location) => {
if cfg!(feature = "gecko") {
Ok(CssRule::Document(Arc::new(self.shared_lock.wrap(DocumentRule {
condition: cond,
rules: self.parse_nested_rules(input, CssRuleType::Document),
+ source_location: location,
}))))
} else {
unreachable!()
@@ -1320,11 +1350,14 @@ impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
fn parse_block(&mut self, prelude: SelectorList<SelectorImpl>, input: &mut Parser)
-> Result<CssRule, ()> {
+ let location = get_location_with_offset(input.current_source_location(),
+ self.context.line_number_offset);
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Style));
let declarations = parse_property_declaration_list(&context, input);
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
selectors: prelude,
- block: Arc::new(self.shared_lock.wrap(declarations))
+ block: Arc::new(self.shared_lock.wrap(declarations)),
+ source_location: location,
}))))
}
}