diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index f8e0913ba26..8694a24ceaf 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -2337,9 +2337,10 @@ extern "C" { -> u32; } extern "C" { - pub fn Servo_KeyframesRule_GetKeyframe(rule: - RawServoKeyframesRuleBorrowed, - index: u32) + pub fn Servo_KeyframesRule_GetKeyframeAt(rule: + RawServoKeyframesRuleBorrowed, + index: u32, line: *mut u32, + column: *mut u32) -> RawServoKeyframeStrong; } extern "C" { diff --git a/components/style/stylesheets/keyframes_rule.rs b/components/style/stylesheets/keyframes_rule.rs index 6c860003b7e..ad41aded37a 100644 --- a/components/style/stylesheets/keyframes_rule.rs +++ b/components/style/stylesheets/keyframes_rule.rs @@ -20,7 +20,7 @@ use std::fmt; use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError}; use style_traits::PropertyDeclarationParseError; use stylesheets::{CssRuleType, StylesheetContents}; -use stylesheets::rule_parser::VendorPrefix; +use stylesheets::rule_parser::{VendorPrefix, get_location_with_offset}; use values::{KeyframesName, serialize_percentage}; /// A [`@keyframes`][keyframes] rule. @@ -192,6 +192,9 @@ pub struct Keyframe { /// Note that `!important` rules in keyframes don't apply, but we keep this /// `Arc` just for convenience. pub block: Arc>, + + /// The line and column of the rule's source code. + pub source_location: SourceLocation, } impl ToCssWithGuard for Keyframe { @@ -249,6 +252,7 @@ impl DeepCloneWithLock for Keyframe { Keyframe { selector: self.selector.clone(), block: Arc::new(lock.wrap(self.block.read_with(guard).clone())), + source_location: self.source_location.clone(), } } } @@ -483,16 +487,28 @@ impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> { type Error = SelectorParseError<'i, StyleParseError<'i>>; } +/// A wrapper to wraps the KeyframeSelector with its source location +struct KeyframeSelectorParserPrelude { + selector: KeyframeSelector, + source_location: SourceLocation, +} + impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> { - type Prelude = KeyframeSelector; + type Prelude = KeyframeSelectorParserPrelude; type QualifiedRule = Arc>; type Error = SelectorParseError<'i, StyleParseError<'i>>; fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result> { let start_position = input.position(); let start_location = input.current_source_location(); + let location = get_location_with_offset(start_location); match KeyframeSelector::parse(input) { - Ok(sel) => Ok(sel), + Ok(sel) => { + Ok(KeyframeSelectorParserPrelude { + selector: sel, + source_location: location, + }) + }, Err(e) => { let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone()); self.context.log_css_error(self.error_context, start_location, error); @@ -530,8 +546,9 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars // `parse_important` is not called here, `!important` is not allowed in keyframe blocks. } Ok(Arc::new(self.shared_lock.wrap(Keyframe { - selector: prelude, + selector: prelude.selector, block: Arc::new(self.shared_lock.wrap(block)), + source_location: prelude.source_location, }))) } } diff --git a/components/style/stylesheets/rule_parser.rs b/components/style/stylesheets/rule_parser.rs index a9f9fd13f5d..470acbbc581 100644 --- a/components/style/stylesheets/rule_parser.rs +++ b/components/style/stylesheets/rule_parser.rs @@ -587,7 +587,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRulePa } /// Adjust a location's column to accommodate DevTools. -fn get_location_with_offset(location: SourceLocation) -> SourceLocation { +pub fn get_location_with_offset(location: SourceLocation) -> SourceLocation { SourceLocation { line: location.line, // Column offsets are not yet supported, but Gecko devtools expect 1-based columns. diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index c446a916369..02919da5b9b 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -1509,11 +1509,16 @@ pub extern "C" fn Servo_KeyframesRule_GetCount(rule: RawServoKeyframesRuleBorrow } #[no_mangle] -pub extern "C" fn Servo_KeyframesRule_GetKeyframe(rule: RawServoKeyframesRuleBorrowed, index: u32) - -> RawServoKeyframeStrong { - read_locked_arc(rule, |rule: &KeyframesRule| { - rule.keyframes[index as usize].clone().into_strong() - }) +pub extern "C" fn Servo_KeyframesRule_GetKeyframeAt(rule: RawServoKeyframesRuleBorrowed, index: u32, + line: *mut u32, column: *mut u32) -> RawServoKeyframeStrong { + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let key = Locked::::as_arc(&rule).read_with(&guard) + .keyframes[index as usize].clone(); + let location = key.read_with(&guard).source_location; + *unsafe { line.as_mut().unwrap() } = location.line as u32; + *unsafe { column.as_mut().unwrap() } = location.column as u32; + key.into_strong() } #[no_mangle]