servo: Merge #16835 - Stylo: Bug 1350175 - Support getting line / column number of CSS rules (from ferjm:bug1350175.line.column.css.rules); r=upsuper,SimonSapin

- [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

Source-Repo: https://github.com/servo/servo
Source-Revision: 5cd8265f9a279e1cebe84218e691e7f80a541fb9

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 4c9d1793c4fd817320f83a695b8701118568d5ef
This commit is contained in:
Fernando Jiménez Moreno 2017-05-15 05:28:50 -05:00
Родитель ab5433c222
Коммит f0cf117809
12 изменённых файлов: 151 добавлений и 56 удалений

1
servo/Cargo.lock сгенерированный
Просмотреть файл

@ -1024,6 +1024,7 @@ dependencies = [
name = "gfx_tests" name = "gfx_tests"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"cssparser 0.13.3 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx 0.0.1", "gfx 0.0.1",
"ipc-channel 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1", "style 0.0.1",

Просмотреть файл

@ -88,6 +88,7 @@ impl Stylesheet {
&string, &string,
url_data, url_data,
stylesheet_loader, stylesheet_loader,
error_reporter) error_reporter,
0)
} }
} }

Просмотреть файл

@ -12,6 +12,7 @@
use computed_values::{font_style, font_weight, font_stretch}; use computed_values::{font_style, font_weight, font_stretch};
use computed_values::font_family::FamilyName; use computed_values::font_family::FamilyName;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::SourceLocation;
#[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors; #[cfg(feature = "gecko")] use gecko_bindings::structs::CSSFontFaceDescriptors;
#[cfg(feature = "gecko")] use cssparser::UnicodeRange; #[cfg(feature = "gecko")] use cssparser::UnicodeRange;
use parser::{ParserContext, log_css_error, Parse}; use parser::{ParserContext, log_css_error, Parse};
@ -74,8 +75,10 @@ impl ToCss for UrlSource {
/// Parse the block inside a `@font-face` rule. /// Parse the block inside a `@font-face` rule.
/// ///
/// Note that the prelude parsing code lives in the `stylesheets` module. /// 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(); let mut rule = FontFaceRuleData::empty();
rule.source_location = location;
{ {
let parser = FontFaceRuleParser { let parser = FontFaceRuleParser {
context: context, context: context,
@ -186,6 +189,8 @@ macro_rules! font_face_descriptors_common {
#[$doc] #[$doc]
pub $ident: Option<$ty>, pub $ident: Option<$ty>,
)* )*
/// Line and column of the @font-face rule source code.
pub source_location: SourceLocation,
} }
impl FontFaceRuleData { impl FontFaceRuleData {
@ -194,6 +199,10 @@ macro_rules! font_face_descriptors_common {
$( $(
$ident: None, $ident: None,
)* )*
source_location: SourceLocation {
line: 0,
column: 0,
},
} }
} }

Просмотреть файл

@ -1255,7 +1255,8 @@ extern "C" {
-> *const ::std::os::raw::c_char; -> *const ::std::os::raw::c_char;
} }
extern "C" { extern "C" {
pub fn Gecko_CSSFontFaceRule_Create() -> *mut nsCSSFontFaceRule; pub fn Gecko_CSSFontFaceRule_Create(line: u32, column: u32)
-> *mut nsCSSFontFaceRule;
} }
extern "C" { extern "C" {
pub fn Gecko_CSSFontFaceRule_GetCssText(rule: *const nsCSSFontFaceRule, pub fn Gecko_CSSFontFaceRule_GetCssText(rule: *const nsCSSFontFaceRule,
@ -1621,7 +1622,8 @@ extern "C" {
media_list: media_list:
*const RawServoMediaList, *const RawServoMediaList,
extra_data: extra_data:
*mut RawGeckoURLExtraData) *mut RawGeckoURLExtraData,
line_number_offset: u32)
-> RawServoStyleSheetStrong; -> RawServoStyleSheetStrong;
} }
extern "C" { extern "C" {
@ -1636,7 +1638,8 @@ extern "C" {
*mut ServoStyleSheet, *mut ServoStyleSheet,
data: *const nsACString, data: *const nsACString,
extra_data: extra_data:
*mut RawGeckoURLExtraData); *mut RawGeckoURLExtraData,
line_number_offset: u32);
} }
extern "C" { extern "C" {
pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed) pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed)
@ -1726,7 +1729,8 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_CssRules_GetStyleRuleAt(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_GetStyleRuleAt(rules: ServoCssRulesBorrowed,
index: u32) index: u32, line: *mut u32,
column: *mut u32)
-> RawServoStyleRuleStrong; -> RawServoStyleRuleStrong;
} }
extern "C" { extern "C" {
@ -1739,7 +1743,8 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_CssRules_GetMediaRuleAt(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_GetMediaRuleAt(rules: ServoCssRulesBorrowed,
index: u32) index: u32, line: *mut u32,
column: *mut u32)
-> RawServoMediaRuleStrong; -> RawServoMediaRuleStrong;
} }
extern "C" { extern "C" {
@ -1756,7 +1761,8 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_CssRules_GetNamespaceRuleAt(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_GetNamespaceRuleAt(rules: ServoCssRulesBorrowed,
index: u32) index: u32, line: *mut u32,
column: *mut u32)
-> RawServoNamespaceRuleStrong; -> RawServoNamespaceRuleStrong;
} }
extern "C" { extern "C" {
@ -1769,7 +1775,9 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_CssRules_GetPageRuleAt(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_GetPageRuleAt(rules: ServoCssRulesBorrowed,
index: u32) -> RawServoPageRuleStrong; index: u32, line: *mut u32,
column: *mut u32)
-> RawServoPageRuleStrong;
} }
extern "C" { extern "C" {
pub fn Servo_PageRule_Debug(rule: RawServoPageRuleBorrowed, pub fn Servo_PageRule_Debug(rule: RawServoPageRuleBorrowed,
@ -1781,7 +1789,8 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_CssRules_GetSupportsRuleAt(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_GetSupportsRuleAt(rules: ServoCssRulesBorrowed,
index: u32) index: u32, line: *mut u32,
column: *mut u32)
-> RawServoSupportsRuleStrong; -> RawServoSupportsRuleStrong;
} }
extern "C" { extern "C" {
@ -1798,7 +1807,8 @@ extern "C" {
} }
extern "C" { extern "C" {
pub fn Servo_CssRules_GetDocumentRuleAt(rules: ServoCssRulesBorrowed, pub fn Servo_CssRules_GetDocumentRuleAt(rules: ServoCssRulesBorrowed,
index: u32) index: u32, line: *mut u32,
column: *mut u32)
-> RawServoDocumentRuleStrong; -> RawServoDocumentRuleStrong;
} }
extern "C" { extern "C" {

Просмотреть файл

@ -117,7 +117,9 @@ impl ToNsCssValue for Vec<UnicodeRange> {
impl From<FontFaceRuleData> for FontFaceRule { impl From<FontFaceRuleData> for FontFaceRule {
fn from(data: FontFaceRuleData) -> FontFaceRule { fn from(data: FontFaceRuleData) -> FontFaceRule {
let mut result = unsafe { 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); data.set_descriptors(&mut result.mDecl.mDescriptors);
result.get() result.get()

Просмотреть файл

@ -10,7 +10,7 @@ use {Atom, Prefix, Namespace};
use context::QuirksMode; use context::QuirksMode;
use counter_style::{CounterStyleRule, parse_counter_style_name, parse_counter_style_body}; use counter_style::{CounterStyleRule, parse_counter_style_name, parse_counter_style_body};
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser}; 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 cssparser::ToCss as ParserToCss;
use document_condition::DocumentCondition; use document_condition::DocumentCondition;
use error_reporting::{ParseErrorReporter, NullReporter}; 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)] #[derive(Debug, PartialEq)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct NamespaceRule { pub struct NamespaceRule {
/// `None` for the default Namespace /// `None` for the default Namespace
pub prefix: Option<Prefix>, pub prefix: Option<Prefix>,
pub url: Namespace, pub url: Namespace,
pub source_location: SourceLocation,
} }
impl ToCssWithGuard for NamespaceRule { impl ToCssWithGuard for NamespaceRule {
@ -581,6 +591,7 @@ impl ToCssWithGuard for KeyframesRule {
pub struct MediaRule { pub struct MediaRule {
pub media_queries: Arc<Locked<MediaList>>, pub media_queries: Arc<Locked<MediaList>>,
pub rules: Arc<Locked<CssRules>>, pub rules: Arc<Locked<CssRules>>,
pub source_location: SourceLocation,
} }
impl ToCssWithGuard for MediaRule { impl ToCssWithGuard for MediaRule {
@ -609,6 +620,8 @@ pub struct SupportsRule {
pub rules: Arc<Locked<CssRules>>, pub rules: Arc<Locked<CssRules>>,
/// The result of evaluating the condition /// The result of evaluating the condition
pub enabled: bool, pub enabled: bool,
/// The line and column of the rule's source code.
pub source_location: SourceLocation,
} }
impl ToCssWithGuard for SupportsRule { impl ToCssWithGuard for SupportsRule {
@ -630,15 +643,19 @@ impl ToCssWithGuard for SupportsRule {
/// ///
/// [page]: https://drafts.csswg.org/css2/page.html#page-box /// [page]: https://drafts.csswg.org/css2/page.html#page-box
/// [page-selectors]: https://drafts.csswg.org/css2/page.html#page-selectors /// [page-selectors]: https://drafts.csswg.org/css2/page.html#page-selectors
#[allow(missing_docs)]
#[derive(Debug)] #[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 { impl ToCssWithGuard for PageRule {
// Serialization of PageRule is not specced, adapted from steps for StyleRule. // Serialization of PageRule is not specced, adapted from steps for StyleRule.
fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
where W: fmt::Write { where W: fmt::Write {
dest.write_str("@page { ")?; 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)?; declaration_block.to_css(dest)?;
if declaration_block.declarations().len() > 0 { if declaration_block.declarations().len() > 0 {
write!(dest, " ")?; write!(dest, " ")?;
@ -652,6 +669,7 @@ impl ToCssWithGuard for PageRule {
pub struct StyleRule { pub struct StyleRule {
pub selectors: SelectorList<SelectorImpl>, pub selectors: SelectorList<SelectorImpl>,
pub block: Arc<Locked<PropertyDeclarationBlock>>, pub block: Arc<Locked<PropertyDeclarationBlock>>,
pub source_location: SourceLocation,
} }
impl ToCssWithGuard for StyleRule { impl ToCssWithGuard for StyleRule {
@ -686,6 +704,8 @@ pub struct DocumentRule {
pub condition: DocumentCondition, pub condition: DocumentCondition,
/// Child rules /// Child rules
pub rules: Arc<Locked<CssRules>>, pub rules: Arc<Locked<CssRules>>,
/// The line and column of the rule's source code.
pub source_location: SourceLocation,
} }
impl ToCssWithGuard for DocumentRule { impl ToCssWithGuard for DocumentRule {
@ -708,15 +728,15 @@ impl Stylesheet {
css: &str, css: &str,
url_data: &UrlExtraData, url_data: &UrlExtraData,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter) { error_reporter: &ParseErrorReporter,
line_number_offset: u64) {
let mut namespaces = Namespaces::default(); let mut namespaces = Namespaces::default();
// FIXME: we really should update existing.url_data with the given url_data, // FIXME: we really should update existing.url_data with the given url_data,
// otherwise newly inserted rule may not have the right base url. // otherwise newly inserted rule may not have the right base url.
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules( let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
css, url_data, existing.origin, &mut namespaces, css, url_data, existing.origin, &mut namespaces,
&existing.shared_lock, stylesheet_loader, error_reporter, &existing.shared_lock, stylesheet_loader, error_reporter,
existing.quirks_mode, 0u64); existing.quirks_mode, line_number_offset);
*existing.namespaces.write() = namespaces; *existing.namespaces.write() = namespaces;
existing.dirty_on_viewport_size_change existing.dirty_on_viewport_size_change
.store(dirty_on_viewport_size_change, Ordering::Release); .store(dirty_on_viewport_size_change, Ordering::Release);
@ -996,21 +1016,21 @@ pub enum VendorPrefix {
enum AtRulePrelude { enum AtRulePrelude {
/// A @font-face rule prelude. /// A @font-face rule prelude.
FontFace, FontFace(SourceLocation),
/// A @counter-style rule prelude, with its counter style name. /// A @counter-style rule prelude, with its counter style name.
CounterStyle(CustomIdent), CounterStyle(CustomIdent),
/// A @media rule prelude, with its media queries. /// A @media rule prelude, with its media queries.
Media(Arc<Locked<MediaList>>), Media(Arc<Locked<MediaList>>, SourceLocation),
/// An @supports rule, with its conditional /// An @supports rule, with its conditional
Supports(SupportsCondition), Supports(SupportsCondition, SourceLocation),
/// A @viewport rule prelude. /// A @viewport rule prelude.
Viewport, Viewport,
/// A @keyframes rule, with its animation name and vendor prefix if exists. /// A @keyframes rule, with its animation name and vendor prefix if exists.
Keyframes(KeyframesName, Option<VendorPrefix>), Keyframes(KeyframesName, Option<VendorPrefix>),
/// A @page rule prelude. /// A @page rule prelude.
Page, Page(SourceLocation),
/// A @document rule, with its conditional. /// 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 { if self.state.get() <= State::Namespaces {
self.state.set(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 prefix_result = input.try(|input| input.expect_ident());
let url = Namespace::from(try!(input.expect_url_or_string())); 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 { self.shared_lock.wrap(NamespaceRule {
prefix: opt_prefix, prefix: opt_prefix,
url: url, url: url,
source_location: location,
}) })
)))) ))))
} else { } else {
@ -1176,18 +1200,20 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
fn parse_prelude(&mut self, name: &str, input: &mut Parser) fn parse_prelude(&mut self, name: &str, input: &mut Parser)
-> Result<AtRuleType<AtRulePrelude, CssRule>, ()> { -> Result<AtRuleType<AtRulePrelude, CssRule>, ()> {
let location = get_location_with_offset(input.current_source_location(),
self.context.line_number_offset);
match_ignore_ascii_case! { name, match_ignore_ascii_case! { name,
"media" => { "media" => {
let media_queries = parse_media_query_list(self.context, input); let media_queries = parse_media_query_list(self.context, input);
let arc = Arc::new(self.shared_lock.wrap(media_queries)); let arc = Arc::new(self.shared_lock.wrap(media_queries));
Ok(AtRuleType::WithBlock(AtRulePrelude::Media(arc))) Ok(AtRuleType::WithBlock(AtRulePrelude::Media(arc, location)))
}, },
"supports" => { "supports" => {
let cond = SupportsCondition::parse(input)?; let cond = SupportsCondition::parse(input)?;
Ok(AtRuleType::WithBlock(AtRulePrelude::Supports(cond))) Ok(AtRuleType::WithBlock(AtRulePrelude::Supports(cond, location)))
}, },
"font-face" => { "font-face" => {
Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace)) Ok(AtRuleType::WithBlock(AtRulePrelude::FontFace(location)))
}, },
"counter-style" => { "counter-style" => {
if !cfg!(feature = "gecko") { if !cfg!(feature = "gecko") {
@ -1229,7 +1255,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
}, },
"page" => { "page" => {
if cfg!(feature = "gecko") { if cfg!(feature = "gecko") {
Ok(AtRuleType::WithBlock(AtRulePrelude::Page)) Ok(AtRuleType::WithBlock(AtRulePrelude::Page(location)))
} else { } else {
Err(()) Err(())
} }
@ -1237,7 +1263,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
"-moz-document" => { "-moz-document" => {
if cfg!(feature = "gecko") { if cfg!(feature = "gecko") {
let cond = DocumentCondition::parse(self.context, input)?; let cond = DocumentCondition::parse(self.context, input)?;
Ok(AtRuleType::WithBlock(AtRulePrelude::Document(cond))) Ok(AtRuleType::WithBlock(AtRulePrelude::Document(cond, location)))
} else { } else {
Err(()) 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, ()> { fn parse_block(&mut self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CssRule, ()> {
match prelude { match prelude {
AtRulePrelude::FontFace => { AtRulePrelude::FontFace(location) => {
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::FontFace)); let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::FontFace));
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap( 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) => { AtRulePrelude::CounterStyle(name) => {
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::CounterStyle)); let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::CounterStyle));
Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap( Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap(
parse_counter_style_body(name, &context, input)?)))) 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 { Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule {
media_queries: media_queries, media_queries: media_queries,
rules: self.parse_nested_rules(input, CssRuleType::Media), rules: self.parse_nested_rules(input, CssRuleType::Media),
source_location: location,
})))) }))))
} }
AtRulePrelude::Supports(cond) => { AtRulePrelude::Supports(cond, location) => {
let enabled = cond.eval(self.context); let enabled = cond.eval(self.context);
Ok(CssRule::Supports(Arc::new(self.shared_lock.wrap(SupportsRule { Ok(CssRule::Supports(Arc::new(self.shared_lock.wrap(SupportsRule {
condition: cond, condition: cond,
rules: self.parse_nested_rules(input, CssRuleType::Supports), rules: self.parse_nested_rules(input, CssRuleType::Supports),
enabled: enabled, enabled: enabled,
source_location: location,
})))) }))))
} }
AtRulePrelude::Viewport => { AtRulePrelude::Viewport => {
@ -1285,18 +1313,20 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
vendor_prefix: prefix, vendor_prefix: prefix,
})))) }))))
} }
AtRulePrelude::Page => { AtRulePrelude::Page(location) => {
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Page)); let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Page));
let declarations = parse_property_declaration_list(&context, input); let declarations = parse_property_declaration_list(&context, input);
Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule( Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule {
Arc::new(self.shared_lock.wrap(declarations)) block: Arc::new(self.shared_lock.wrap(declarations)),
))))) source_location: location,
}))))
} }
AtRulePrelude::Document(cond) => { AtRulePrelude::Document(cond, location) => {
if cfg!(feature = "gecko") { if cfg!(feature = "gecko") {
Ok(CssRule::Document(Arc::new(self.shared_lock.wrap(DocumentRule { Ok(CssRule::Document(Arc::new(self.shared_lock.wrap(DocumentRule {
condition: cond, condition: cond,
rules: self.parse_nested_rules(input, CssRuleType::Document), rules: self.parse_nested_rules(input, CssRuleType::Document),
source_location: location,
})))) }))))
} else { } else {
unreachable!() unreachable!()
@ -1320,11 +1350,14 @@ impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
fn parse_block(&mut self, prelude: SelectorList<SelectorImpl>, input: &mut Parser) fn parse_block(&mut self, prelude: SelectorList<SelectorImpl>, input: &mut Parser)
-> Result<CssRule, ()> { -> 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 context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::Style));
let declarations = parse_property_declaration_list(&context, input); let declarations = parse_property_declaration_list(&context, input);
Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule { Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule {
selectors: prelude, selectors: prelude,
block: Arc::new(self.shared_lock.wrap(declarations)) block: Arc::new(self.shared_lock.wrap(declarations)),
source_location: location,
})))) }))))
} }
} }

Просмотреть файл

@ -571,7 +571,8 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
data: *const nsACString, data: *const nsACString,
mode: SheetParsingMode, mode: SheetParsingMode,
media_list: *const RawServoMediaList, media_list: *const RawServoMediaList,
extra_data: *mut URLExtraData) extra_data: *mut URLExtraData,
line_number_offset: u32)
-> RawServoStyleSheetStrong { -> RawServoStyleSheetStrong {
let global_style_data = &*GLOBAL_STYLE_DATA; let global_style_data = &*GLOBAL_STYLE_DATA;
let input = unsafe { data.as_ref().unwrap().as_str_unchecked() }; let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
@ -605,7 +606,8 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
Arc::new(Stylesheet::from_str( Arc::new(Stylesheet::from_str(
input, url_data.clone(), origin, media, input, url_data.clone(), origin, media,
shared_lock, loader, &RustLogReporter, QuirksMode::NoQuirks, 0u64) shared_lock, loader, &RustLogReporter,
QuirksMode::NoQuirks, line_number_offset as u64)
).into_strong() ).into_strong()
} }
@ -614,7 +616,8 @@ pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheet
loader: *mut Loader, loader: *mut Loader,
gecko_stylesheet: *mut ServoStyleSheet, gecko_stylesheet: *mut ServoStyleSheet,
data: *const nsACString, data: *const nsACString,
extra_data: *mut URLExtraData) extra_data: *mut URLExtraData,
line_number_offset: u32)
{ {
let input = unsafe { data.as_ref().unwrap().as_str_unchecked() }; let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) }; let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) };
@ -632,8 +635,8 @@ pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheet
}; };
let sheet = Stylesheet::as_arc(&stylesheet); let sheet = Stylesheet::as_arc(&stylesheet);
Stylesheet::update_from_str(&sheet, input, url_data, Stylesheet::update_from_str(&sheet, input, url_data, loader,
loader, &RustLogReporter); &RustLogReporter, line_number_offset as u64);
} }
#[no_mangle] #[no_mangle]
@ -782,16 +785,24 @@ macro_rules! impl_basic_rule_funcs {
to_css: $to_css:ident, to_css: $to_css:ident,
} => { } => {
#[no_mangle] #[no_mangle]
pub extern "C" fn $getter(rules: ServoCssRulesBorrowed, index: u32) -> Strong<$raw_type> { pub extern "C" fn $getter(rules: ServoCssRulesBorrowed, index: u32,
read_locked_arc(rules, |rules: &CssRules| { line: *mut u32, column: *mut u32)
match rules.0[index as usize] { -> Strong<$raw_type> {
CssRule::$name(ref rule) => rule.clone().into_strong(), let global_style_data = &*GLOBAL_STYLE_DATA;
_ => { let guard = global_style_data.shared_lock.read();
unreachable!(concat!(stringify!($getter), "should only be called ", let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
"on a ", stringify!($name), " rule")); match rules.0[index as usize] {
} CssRule::$name(ref rule) => {
let location = rule.read_with(&guard).source_location;
*unsafe { line.as_mut().unwrap() } = location.line as u32;
*unsafe { column.as_mut().unwrap() } = location.column as u32;
rule.clone().into_strong()
},
_ => {
unreachable!(concat!(stringify!($getter), "should only be called ",
"on a ", stringify!($name), " rule"));
} }
}) }
} }
#[no_mangle] #[no_mangle]
@ -924,7 +935,7 @@ pub extern "C" fn Servo_NamespaceRule_GetURI(rule: RawServoNamespaceRuleBorrowed
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_PageRule_GetStyle(rule: RawServoPageRuleBorrowed) -> RawServoDeclarationBlockStrong { pub extern "C" fn Servo_PageRule_GetStyle(rule: RawServoPageRuleBorrowed) -> RawServoDeclarationBlockStrong {
read_locked_arc(rule, |rule: &PageRule| { read_locked_arc(rule, |rule: &PageRule| {
rule.0.clone().into_strong() rule.block.clone().into_strong()
}) })
} }
@ -933,7 +944,7 @@ pub extern "C" fn Servo_PageRule_SetStyle(rule: RawServoPageRuleBorrowed,
declarations: RawServoDeclarationBlockBorrowed) { declarations: RawServoDeclarationBlockBorrowed) {
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations); let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
write_locked_arc(rule, |rule: &mut PageRule| { write_locked_arc(rule, |rule: &mut PageRule| {
rule.0 = declarations.clone(); rule.block = declarations.clone();
}) })
} }

Просмотреть файл

@ -10,6 +10,7 @@ path = "lib.rs"
doctest = false doctest = false
[dependencies] [dependencies]
cssparser = "0.13.3"
gfx = {path = "../../../components/gfx"} gfx = {path = "../../../components/gfx"}
ipc-channel = "0.7" ipc-channel = "0.7"
style = {path = "../../../components/style"} style = {path = "../../../components/style"}

Просмотреть файл

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::SourceLocation;
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use ipc_channel::ipc; use ipc_channel::ipc;
use style::computed_values::font_family::FamilyName; use style::computed_values::font_family::FamilyName;
@ -23,6 +24,10 @@ fn test_local_web_font() {
let font_face_rule = FontFaceRuleData { let font_face_rule = FontFaceRuleData {
family: Some(family_name.clone()), family: Some(family_name.clone()),
sources: Some(vec![Source::Local(variant_name)]), sources: Some(vec![Source::Local(variant_name)]),
source_location: SourceLocation {
line: 0,
column: 0,
},
}; };
font_cache_thread.add_web_font( font_cache_thread.add_web_font(

Просмотреть файл

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern crate cssparser;
extern crate gfx; extern crate gfx;
extern crate ipc_channel; extern crate ipc_channel;
extern crate style; extern crate style;

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::{self, Parser as CssParser, SourcePosition}; use cssparser::{self, Parser as CssParser, SourcePosition, SourceLocation};
use html5ever::{Namespace as NsAtom}; use html5ever::{Namespace as NsAtom};
use media_queries::CSSErrorReporterTest; use media_queries::CSSErrorReporterTest;
use parking_lot::RwLock; use parking_lot::RwLock;
@ -82,7 +82,11 @@ fn test_parse_stylesheet() {
rules: CssRules::new(vec![ rules: CssRules::new(vec![
CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule { CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule {
prefix: None, prefix: None,
url: NsAtom::from("http://www.w3.org/1999/xhtml") url: NsAtom::from("http://www.w3.org/1999/xhtml"),
source_location: SourceLocation {
line: 1,
column: 19,
},
}))), }))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule { CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList(vec![ selectors: SelectorList(vec![
@ -116,6 +120,10 @@ fn test_parse_stylesheet() {
DeclaredValueOwned::CSSWideKeyword(CSSWideKeyword::Inherit)), DeclaredValueOwned::CSSWideKeyword(CSSWideKeyword::Inherit)),
Importance::Important), Importance::Important),
]))), ]))),
source_location: SourceLocation {
line: 3,
column: 31,
},
}))), }))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule { CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList(vec![ selectors: SelectorList(vec![
@ -152,6 +160,10 @@ fn test_parse_stylesheet() {
(PropertyDeclaration::Display(longhands::display::SpecifiedValue::block), (PropertyDeclaration::Display(longhands::display::SpecifiedValue::block),
Importance::Normal), Importance::Normal),
]))), ]))),
source_location: SourceLocation {
line: 11,
column: 27,
},
}))), }))),
CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule { CssRule::Style(Arc::new(stylesheet.shared_lock.wrap(StyleRule {
selectors: SelectorList(vec![ selectors: SelectorList(vec![
@ -220,6 +232,10 @@ fn test_parse_stylesheet() {
::get_initial_specified_value()])), ::get_initial_specified_value()])),
Importance::Normal), Importance::Normal),
]))), ]))),
source_location: SourceLocation {
line: 15,
column: 20,
},
}))), }))),
CssRule::Keyframes(Arc::new(stylesheet.shared_lock.wrap(KeyframesRule { CssRule::Keyframes(Arc::new(stylesheet.shared_lock.wrap(KeyframesRule {
name: KeyframesName::Ident(CustomIdent("foo".into())), name: KeyframesName::Ident(CustomIdent("foo".into())),

Просмотреть файл

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use cssparser::SourceLocation;
use html5ever::LocalName; use html5ever::LocalName;
use selectors::parser::LocalName as LocalNameSelector; use selectors::parser::LocalName as LocalNameSelector;
use selectors::parser::Selector; use selectors::parser::Selector;
@ -32,6 +33,10 @@ fn get_mock_rules(css_selectors: &[&str]) -> (Vec<Vec<Rule>>, SharedRwLock) {
longhands::display::SpecifiedValue::block), longhands::display::SpecifiedValue::block),
Importance::Normal Importance::Normal
))), ))),
source_location: SourceLocation {
line: 0,
column: 0,
},
})); }));
let guard = shared_lock.read(); let guard = shared_lock.read();