Auto merge of #18365 - chenpighead:stylo-keyframe-location, r=upsuper,emilio

stylo: Store location information for keyframe rules.

So far, we only store location info for the whole Keyframes block, not for each
of the keyframe rule. Without this info, the devtool can't present the rules
on the devtool panel properly.

In this patch, we collect the source location info while parsing keyframe selector.
The binding function, Servo_KeyframesRule_GetKeyframe, is also fixed (and renamed
to Servo_KeyframesRule_GetKeyframeAt to match the fix) to accept line and column
parameters from Gecko, so we can pass/set them with the source location from Servo.

This is the servo part of [Bug 1394994](https://bugzilla.mozilla.org/show_bug.cgi?id=1394994).

- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix [Bug 1394994](https://bugzilla.mozilla.org/show_bug.cgi?id=1394994)

<!-- 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/18365)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-09-05 11:22:20 -05:00 committed by GitHub
commit f648e12935
6 changed files with 59 additions and 16 deletions

View file

@ -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<Locked<PropertyDeclarationBlock>>,
/// 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<Locked<Keyframe>>;
type Error = SelectorParseError<'i, StyleParseError<'i>>;
fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result<Self::Prelude, ParseError<'i>> {
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,
})))
}
}