mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
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 commit is contained in:
parent
e5efbeea6e
commit
28d48242d3
4 changed files with 36 additions and 13 deletions
|
@ -2337,9 +2337,10 @@ extern "C" {
|
||||||
-> u32;
|
-> u32;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_KeyframesRule_GetKeyframe(rule:
|
pub fn Servo_KeyframesRule_GetKeyframeAt(rule:
|
||||||
RawServoKeyframesRuleBorrowed,
|
RawServoKeyframesRuleBorrowed,
|
||||||
index: u32)
|
index: u32, line: *mut u32,
|
||||||
|
column: *mut u32)
|
||||||
-> RawServoKeyframeStrong;
|
-> RawServoKeyframeStrong;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -20,7 +20,7 @@ use std::fmt;
|
||||||
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError};
|
use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError};
|
||||||
use style_traits::PropertyDeclarationParseError;
|
use style_traits::PropertyDeclarationParseError;
|
||||||
use stylesheets::{CssRuleType, StylesheetContents};
|
use stylesheets::{CssRuleType, StylesheetContents};
|
||||||
use stylesheets::rule_parser::VendorPrefix;
|
use stylesheets::rule_parser::{VendorPrefix, get_location_with_offset};
|
||||||
use values::{KeyframesName, serialize_percentage};
|
use values::{KeyframesName, serialize_percentage};
|
||||||
|
|
||||||
/// A [`@keyframes`][keyframes] rule.
|
/// A [`@keyframes`][keyframes] rule.
|
||||||
|
@ -192,6 +192,9 @@ pub struct Keyframe {
|
||||||
/// Note that `!important` rules in keyframes don't apply, but we keep this
|
/// Note that `!important` rules in keyframes don't apply, but we keep this
|
||||||
/// `Arc` just for convenience.
|
/// `Arc` just for convenience.
|
||||||
pub block: Arc<Locked<PropertyDeclarationBlock>>,
|
pub block: Arc<Locked<PropertyDeclarationBlock>>,
|
||||||
|
|
||||||
|
/// The line and column of the rule's source code.
|
||||||
|
pub source_location: SourceLocation,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCssWithGuard for Keyframe {
|
impl ToCssWithGuard for Keyframe {
|
||||||
|
@ -249,6 +252,7 @@ impl DeepCloneWithLock for Keyframe {
|
||||||
Keyframe {
|
Keyframe {
|
||||||
selector: self.selector.clone(),
|
selector: self.selector.clone(),
|
||||||
block: Arc::new(lock.wrap(self.block.read_with(guard).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>>;
|
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> {
|
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> {
|
||||||
type Prelude = KeyframeSelector;
|
type Prelude = KeyframeSelectorParserPrelude;
|
||||||
type QualifiedRule = Arc<Locked<Keyframe>>;
|
type QualifiedRule = Arc<Locked<Keyframe>>;
|
||||||
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
type Error = SelectorParseError<'i, StyleParseError<'i>>;
|
||||||
|
|
||||||
fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result<Self::Prelude, ParseError<'i>> {
|
fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result<Self::Prelude, ParseError<'i>> {
|
||||||
let start_position = input.position();
|
let start_position = input.position();
|
||||||
let start_location = input.current_source_location();
|
let start_location = input.current_source_location();
|
||||||
|
let location = get_location_with_offset(start_location);
|
||||||
match KeyframeSelector::parse(input) {
|
match KeyframeSelector::parse(input) {
|
||||||
Ok(sel) => Ok(sel),
|
Ok(sel) => {
|
||||||
|
Ok(KeyframeSelectorParserPrelude {
|
||||||
|
selector: sel,
|
||||||
|
source_location: location,
|
||||||
|
})
|
||||||
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone());
|
let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone());
|
||||||
self.context.log_css_error(self.error_context, start_location, error);
|
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.
|
// `parse_important` is not called here, `!important` is not allowed in keyframe blocks.
|
||||||
}
|
}
|
||||||
Ok(Arc::new(self.shared_lock.wrap(Keyframe {
|
Ok(Arc::new(self.shared_lock.wrap(Keyframe {
|
||||||
selector: prelude,
|
selector: prelude.selector,
|
||||||
block: Arc::new(self.shared_lock.wrap(block)),
|
block: Arc::new(self.shared_lock.wrap(block)),
|
||||||
|
source_location: prelude.source_location,
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -587,7 +587,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRulePa
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adjust a location's column to accommodate DevTools.
|
/// 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 {
|
SourceLocation {
|
||||||
line: location.line,
|
line: location.line,
|
||||||
// Column offsets are not yet supported, but Gecko devtools expect 1-based columns.
|
// Column offsets are not yet supported, but Gecko devtools expect 1-based columns.
|
||||||
|
|
|
@ -1509,11 +1509,16 @@ pub extern "C" fn Servo_KeyframesRule_GetCount(rule: RawServoKeyframesRuleBorrow
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_KeyframesRule_GetKeyframe(rule: RawServoKeyframesRuleBorrowed, index: u32)
|
pub extern "C" fn Servo_KeyframesRule_GetKeyframeAt(rule: RawServoKeyframesRuleBorrowed, index: u32,
|
||||||
-> RawServoKeyframeStrong {
|
line: *mut u32, column: *mut u32) -> RawServoKeyframeStrong {
|
||||||
read_locked_arc(rule, |rule: &KeyframesRule| {
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
rule.keyframes[index as usize].clone().into_strong()
|
let guard = global_style_data.shared_lock.read();
|
||||||
})
|
let key = Locked::<KeyframesRule>::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]
|
#[no_mangle]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue