Auto merge of #21088 - emilio:gecko-sync, r=emilio

style: Import changes from mozilla-central.

See each individual commit for details.
This commit is contained in:
bors-servo 2018-06-23 14:43:07 -04:00 committed by GitHub
commit 16bdf9225d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
101 changed files with 645 additions and 640 deletions

View file

@ -1417,7 +1417,7 @@ impl BlockFlow {
// Per CSS 2.1 § 16.3.1, text alignment propagates to all children in flow. // Per CSS 2.1 § 16.3.1, text alignment propagates to all children in flow.
// //
// TODO(#2265, pcwalton): Do this in the cascade instead. // TODO(#2265, pcwalton): Do this in the cascade instead.
let containing_block_text_align = self.fragment.style().get_inheritedtext().text_align; let containing_block_text_align = self.fragment.style().get_inherited_text().text_align;
kid.mut_base().flags.set_text_align(containing_block_text_align); kid.mut_base().flags.set_text_align(containing_block_text_align);
// Handle `text-indent` on behalf of any inline children that we have. This is // Handle `text-indent` on behalf of any inline children that we have. This is
@ -1425,7 +1425,7 @@ impl BlockFlow {
// we know. // we know.
if kid.is_inline_flow() { if kid.is_inline_flow() {
kid.as_mut_inline().first_line_indentation = kid.as_mut_inline().first_line_indentation =
self.fragment.style().get_inheritedtext().text_indent self.fragment.style().get_inherited_text().text_indent
.to_used_value(containing_block_size); .to_used_value(containing_block_size);
} }
} }
@ -2340,7 +2340,7 @@ pub trait ISizeAndMarginsComputer {
containing_block_inline_size), containing_block_inline_size),
MaybeAuto::from_style(position.inline_end, MaybeAuto::from_style(position.inline_end,
containing_block_inline_size), containing_block_inline_size),
style.get_inheritedtext().text_align, style.get_inherited_text().text_align,
available_inline_size) available_inline_size)
} }

View file

@ -1095,7 +1095,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
kid_flow.as_block() kid_flow.as_block()
.fragment .fragment
.style() .style()
.get_inheritedtable() .get_inherited_table()
.caption_side == side { .caption_side == side {
table_wrapper_flow.add_new_child(kid_flow); table_wrapper_flow.add_new_child(kid_flow);
} }
@ -1256,7 +1256,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
// Determine if the table cell should be hidden. Per CSS 2.1 § 17.6.1.1, this will be true // Determine if the table cell should be hidden. Per CSS 2.1 § 17.6.1.1, this will be true
// if the cell has any in-flow elements (even empty ones!) and has `empty-cells` set to // if the cell has any in-flow elements (even empty ones!) and has `empty-cells` set to
// `hide`. // `hide`.
let hide = node.style(self.style_context()).get_inheritedtable().empty_cells == EmptyCells::Hide && let hide = node.style(self.style_context()).get_inherited_table().empty_cells == EmptyCells::Hide &&
node.children().all(|kid| { node.children().all(|kid| {
let position = kid.style(self.style_context()).get_box().position; let position = kid.style(self.style_context()).get_box().position;
!kid.is_content() || !kid.is_content() ||
@ -1871,7 +1871,7 @@ fn bidi_control_chars(style: &ServoArc<ComputedValues>) -> Option<(&'static str,
use style::computed_values::unicode_bidi::T::*; use style::computed_values::unicode_bidi::T::*;
let unicode_bidi = style.get_text().unicode_bidi; let unicode_bidi = style.get_text().unicode_bidi;
let direction = style.get_inheritedbox().direction; let direction = style.get_inherited_box().direction;
// See the table in http://dev.w3.org/csswg/css-writing-modes/#unicode-bidi // See the table in http://dev.w3.org/csswg/css-writing-modes/#unicode-bidi
match (unicode_bidi, direction) { match (unicode_bidi, direction) {

View file

@ -1013,7 +1013,7 @@ impl FragmentDisplayListBuilding for Fragment {
id: webrender_image.key.unwrap(), id: webrender_image.key.unwrap(),
stretch_size: placement.tile_size.to_layout(), stretch_size: placement.tile_size.to_layout(),
tile_spacing: placement.tile_spacing.to_layout(), tile_spacing: placement.tile_spacing.to_layout(),
image_rendering: style.get_inheritedbox().image_rendering.to_layout(), image_rendering: style.get_inherited_box().image_rendering.to_layout(),
}))); })));
}); });
} }
@ -1581,7 +1581,7 @@ impl FragmentDisplayListBuilding for Fragment {
display_list_section: DisplayListSection, display_list_section: DisplayListSection,
clip: Rect<Au>, clip: Rect<Au>,
) { ) {
if self.style().get_inheritedbox().visibility != Visibility::Visible { if self.style().get_inherited_box().visibility != Visibility::Visible {
return; return;
} }
@ -1744,7 +1744,7 @@ impl FragmentDisplayListBuilding for Fragment {
state, state,
&text_fragment, &text_fragment,
stacking_relative_content_box, stacking_relative_content_box,
&self.style.get_inheritedtext().text_shadow.0, &self.style.get_inherited_text().text_shadow.0,
clip, clip,
); );
@ -1765,7 +1765,7 @@ impl FragmentDisplayListBuilding for Fragment {
state, state,
&text_fragment, &text_fragment,
stacking_relative_content_box, stacking_relative_content_box,
&self.style.get_inheritedtext().text_shadow.0, &self.style.get_inherited_text().text_shadow.0,
clip, clip,
); );
@ -1837,7 +1837,7 @@ impl FragmentDisplayListBuilding for Fragment {
stretch_size: stacking_relative_content_box.size.to_layout(), stretch_size: stacking_relative_content_box.size.to_layout(),
tile_spacing: LayoutSize::zero(), tile_spacing: LayoutSize::zero(),
image_rendering: self.style image_rendering: self.style
.get_inheritedbox() .get_inherited_box()
.image_rendering .image_rendering
.to_layout(), .to_layout(),
}))); })));
@ -2005,7 +2005,7 @@ impl FragmentDisplayListBuilding for Fragment {
} }
// Create display items for text decorations. // Create display items for text decorations.
let text_decorations = self.style().get_inheritedtext().text_decorations_in_effect; let text_decorations = self.style().get_inherited_text().text_decorations_in_effect;
let logical_stacking_relative_content_box = LogicalRect::from_physical( let logical_stacking_relative_content_box = LogicalRect::from_physical(
self.style.writing_mode, self.style.writing_mode,
@ -3048,8 +3048,8 @@ impl ComputedValuesCursorUtility for ComputedValues {
#[inline] #[inline]
fn get_cursor(&self, default_cursor: CursorKind) -> Option<CursorKind> { fn get_cursor(&self, default_cursor: CursorKind) -> Option<CursorKind> {
match ( match (
self.get_inheritedui().pointer_events, self.get_inherited_ui().pointer_events,
&self.get_inheritedui().cursor, &self.get_inherited_ui().cursor,
) { ) {
(PointerEvents::None, _) => None, (PointerEvents::None, _) => None,
( (

View file

@ -561,7 +561,7 @@ impl FlexFlow {
.explicit_block_size(parent_container_size) .explicit_block_size(parent_container_size)
.map(|x| max(x - box_border, Au(0))); .map(|x| max(x - box_border, Au(0)));
let containing_block_text_align = let containing_block_text_align =
self.block_flow.fragment.style().get_inheritedtext().text_align; self.block_flow.fragment.style().get_inherited_text().text_align;
while let Some(mut line) = self.get_flex_line(inline_size) { while let Some(mut line) = self.get_flex_line(inline_size) {
let items = &mut self.items[line.range.clone()]; let items = &mut self.items[line.range.clone()];

View file

@ -818,7 +818,7 @@ impl Fragment {
SpecificFragmentInfo::TableCell => { SpecificFragmentInfo::TableCell => {
let base_quantities = QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_PADDING | let base_quantities = QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED; QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse == if self.style.get_inherited_table().border_collapse ==
BorderCollapse::Separate { BorderCollapse::Separate {
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else { } else {
@ -828,7 +828,7 @@ impl Fragment {
SpecificFragmentInfo::TableWrapper => { SpecificFragmentInfo::TableWrapper => {
let base_quantities = QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS | let base_quantities = QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED; QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse == if self.style.get_inherited_table().border_collapse ==
BorderCollapse::Separate { BorderCollapse::Separate {
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else { } else {
@ -838,7 +838,7 @@ impl Fragment {
SpecificFragmentInfo::TableRow => { SpecificFragmentInfo::TableRow => {
let base_quantities = let base_quantities =
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED; QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse == if self.style.get_inherited_table().border_collapse ==
BorderCollapse::Separate { BorderCollapse::Separate {
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else { } else {
@ -1272,7 +1272,7 @@ impl Fragment {
pub fn compute_border_and_padding(&mut self, pub fn compute_border_and_padding(&mut self,
containing_block_inline_size: Au) { containing_block_inline_size: Au) {
// Compute border. // Compute border.
let border = match self.style.get_inheritedtable().border_collapse { let border = match self.style.get_inherited_table().border_collapse {
BorderCollapse::Separate => self.border_width(), BorderCollapse::Separate => self.border_width(),
BorderCollapse::Collapse => LogicalMargin::zero(self.style.writing_mode), BorderCollapse::Collapse => LogicalMargin::zero(self.style.writing_mode),
}; };
@ -1377,7 +1377,7 @@ impl Fragment {
} }
pub fn white_space(&self) -> WhiteSpace { pub fn white_space(&self) -> WhiteSpace {
self.style().get_inheritedtext().white_space self.style().get_inherited_text().white_space
} }
pub fn color(&self) -> Color { pub fn color(&self) -> Color {
@ -1625,12 +1625,12 @@ impl Fragment {
let mut flags = SplitOptions::empty(); let mut flags = SplitOptions::empty();
if starts_line { if starts_line {
flags.insert(SplitOptions::STARTS_LINE); flags.insert(SplitOptions::STARTS_LINE);
if self.style().get_inheritedtext().overflow_wrap == OverflowWrap::BreakWord { if self.style().get_inherited_text().overflow_wrap == OverflowWrap::BreakWord {
flags.insert(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES) flags.insert(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES)
} }
} }
match self.style().get_inheritedtext().word_break { match self.style().get_inherited_text().word_break {
WordBreak::Normal | WordBreak::KeepAll => { WordBreak::Normal | WordBreak::KeepAll => {
// Break at normal word boundaries. keep-all forbids soft wrap opportunities. // Break at normal word boundaries. keep-all forbids soft wrap opportunities.
let natural_word_breaking_strategy = let natural_word_breaking_strategy =

View file

@ -934,7 +934,7 @@ impl InlineFlow {
if fragments.fragments.is_empty() { if fragments.fragments.is_empty() {
return return
} }
let text_justify = fragments.fragments[0].style().get_inheritedtext().text_justify; let text_justify = fragments.fragments[0].style().get_inherited_text().text_justify;
// Translate `left` and `right` to logical directions. // Translate `left` and `right` to logical directions.
let is_ltr = fragments.fragments[0].style().writing_mode.is_bidi_ltr(); let is_ltr = fragments.fragments[0].style().writing_mode.is_bidi_ltr();
@ -1341,7 +1341,7 @@ impl Flow for InlineFlow {
let mut intrinsic_sizes_for_nonbroken_run = IntrinsicISizesContribution::new(); let mut intrinsic_sizes_for_nonbroken_run = IntrinsicISizesContribution::new();
for fragment in &mut self.fragments.fragments { for fragment in &mut self.fragments.fragments {
let intrinsic_sizes_for_fragment = fragment.compute_intrinsic_inline_sizes().finish(); let intrinsic_sizes_for_fragment = fragment.compute_intrinsic_inline_sizes().finish();
match fragment.style.get_inheritedtext().white_space { match fragment.style.get_inherited_text().white_space {
WhiteSpace::Nowrap => { WhiteSpace::Nowrap => {
intrinsic_sizes_for_nonbroken_run.union_nonbreaking_inline( intrinsic_sizes_for_nonbroken_run.union_nonbreaking_inline(
&intrinsic_sizes_for_fragment) &intrinsic_sizes_for_fragment)

View file

@ -959,7 +959,7 @@ fn inner_text_collection_steps<N: LayoutNode>(node: N,
}; };
// Step 2. // Step 2.
if style.get_inheritedbox().visibility != Visibility::Visible { if style.get_inherited_box().visibility != Visibility::Visible {
continue; continue;
} }

View file

@ -191,8 +191,8 @@ impl TableFlow {
/// Returns the effective spacing per cell, taking the value of `border-collapse` into account. /// Returns the effective spacing per cell, taking the value of `border-collapse` into account.
pub fn spacing(&self) -> border_spacing::T { pub fn spacing(&self) -> border_spacing::T {
let style = self.block_flow.fragment.style(); let style = self.block_flow.fragment.style();
match style.get_inheritedtable().border_collapse { match style.get_inherited_table().border_collapse {
border_collapse::T::Separate => style.get_inheritedtable().border_spacing, border_collapse::T::Separate => style.get_inherited_table().border_spacing,
border_collapse::T::Collapse => border_spacing::T::zero(), border_collapse::T::Collapse => border_spacing::T::zero(),
} }
} }
@ -298,7 +298,7 @@ impl Flow for TableFlow {
let collapsing_borders = self.block_flow let collapsing_borders = self.block_flow
.fragment .fragment
.style .style
.get_inheritedtable() .get_inherited_table()
.border_collapse == border_collapse::T::Collapse; .border_collapse == border_collapse::T::Collapse;
let table_inline_collapsed_borders = if collapsing_borders { let table_inline_collapsed_borders = if collapsing_borders {
Some(TableInlineCollapsedBorders { Some(TableInlineCollapsedBorders {
@ -522,7 +522,7 @@ impl Flow for TableFlow {
let border_painting_mode = match self.block_flow let border_painting_mode = match self.block_flow
.fragment .fragment
.style .style
.get_inheritedtable() .get_inherited_table()
.border_collapse { .border_collapse {
border_collapse::T::Separate => BorderPaintingMode::Separate, border_collapse::T::Separate => BorderPaintingMode::Separate,
border_collapse::T::Collapse => BorderPaintingMode::Hidden, border_collapse::T::Collapse => BorderPaintingMode::Hidden,
@ -771,12 +771,12 @@ pub trait TableLikeFlow {
impl TableLikeFlow for BlockFlow { impl TableLikeFlow for BlockFlow {
fn assign_block_size_for_table_like_flow(&mut self, block_direction_spacing: Au, fn assign_block_size_for_table_like_flow(&mut self, block_direction_spacing: Au,
layout_context: &LayoutContext) { layout_context: &LayoutContext) {
debug_assert!(self.fragment.style.get_inheritedtable().border_collapse == debug_assert!(self.fragment.style.get_inherited_table().border_collapse ==
border_collapse::T::Separate || block_direction_spacing == Au(0)); border_collapse::T::Separate || block_direction_spacing == Au(0));
fn border_spacing_for_row(fragment: &Fragment, row: &TableRowFlow, fn border_spacing_for_row(fragment: &Fragment, row: &TableRowFlow,
block_direction_spacing: Au) -> Au { block_direction_spacing: Au) -> Au {
match fragment.style.get_inheritedtable().border_collapse { match fragment.style.get_inherited_table().border_collapse {
border_collapse::T::Separate => block_direction_spacing, border_collapse::T::Separate => block_direction_spacing,
border_collapse::T::Collapse => { border_collapse::T::Collapse => {
row.collapsed_border_spacing.block_start row.collapsed_border_spacing.block_start
@ -1204,13 +1204,13 @@ impl<'table> TableCellStyleInfo<'table> {
use style::computed_values::visibility::T as Visibility; use style::computed_values::visibility::T as Visibility;
if !self.cell.visible || self.cell.block_flow.fragment.style() if !self.cell.visible || self.cell.block_flow.fragment.style()
.get_inheritedbox().visibility != Visibility::Visible { .get_inherited_box().visibility != Visibility::Visible {
return return
} }
let border_painting_mode = match self.cell.block_flow let border_painting_mode = match self.cell.block_flow
.fragment .fragment
.style .style
.get_inheritedtable() .get_inherited_table()
.border_collapse { .border_collapse {
border_collapse::T::Separate => BorderPaintingMode::Separate, border_collapse::T::Separate => BorderPaintingMode::Separate,
border_collapse::T::Collapse => BorderPaintingMode::Collapse(&self.cell.collapsed_borders), border_collapse::T::Collapse => BorderPaintingMode::Collapse(&self.cell.collapsed_borders),

View file

@ -353,7 +353,7 @@ impl Flow for TableRowFlow {
let collapsing_borders = self.block_flow let collapsing_borders = self.block_flow
.fragment .fragment
.style() .style()
.get_inheritedtable() .get_inherited_table()
.border_collapse == BorderCollapse::Collapse; .border_collapse == BorderCollapse::Collapse;
let row_style = &*self.block_flow.fragment.style; let row_style = &*self.block_flow.fragment.style;
self.preliminary_collapsed_borders.reset( self.preliminary_collapsed_borders.reset(
@ -500,7 +500,7 @@ impl Flow for TableRowFlow {
// Set up border collapse info. // Set up border collapse info.
let border_collapse_info = let border_collapse_info =
match self.block_flow.fragment.style().get_inheritedtable().border_collapse { match self.block_flow.fragment.style().get_inherited_table().border_collapse {
BorderCollapse::Collapse => { BorderCollapse::Collapse => {
Some(BorderCollapseInfoForChildTableCell { Some(BorderCollapseInfoForChildTableCell {
collapsed_borders_for_row: &self.final_collapsed_borders, collapsed_borders_for_row: &self.final_collapsed_borders,

View file

@ -130,7 +130,7 @@ impl Flow for TableRowGroupFlow {
let (inline_start_content_edge, inline_end_content_edge) = (Au(0), Au(0)); let (inline_start_content_edge, inline_end_content_edge) = (Au(0), Au(0));
let content_inline_size = containing_block_inline_size; let content_inline_size = containing_block_inline_size;
let border_collapse = self.block_flow.fragment.style.get_inheritedtable().border_collapse; let border_collapse = self.block_flow.fragment.style.get_inherited_table().border_collapse;
let inline_size_computer = InternalTable; let inline_size_computer = InternalTable;
inline_size_computer.compute_used_inline_size(&mut self.block_flow, inline_size_computer.compute_used_inline_size(&mut self.block_flow,
shared_context, shared_context,

View file

@ -170,7 +170,7 @@ impl TextRunScanner {
{ {
let in_fragment = self.clump.front().unwrap(); let in_fragment = self.clump.front().unwrap();
let font_style = in_fragment.style().clone_font(); let font_style = in_fragment.style().clone_font();
let inherited_text_style = in_fragment.style().get_inheritedtext(); let inherited_text_style = in_fragment.style().get_inherited_text();
font_group = font_context.font_group(font_style); font_group = font_context.font_group(font_style);
compression = match in_fragment.white_space() { compression = match in_fragment.white_space() {
WhiteSpace::Normal | WhiteSpace::Normal |
@ -477,7 +477,7 @@ pub fn font_metrics_for_style(mut font_context: &mut LayoutFontContext, style: :
/// Returns the line block-size needed by the given computed style and font size. /// Returns the line block-size needed by the given computed style and font size.
pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) -> Au { pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) -> Au {
let font_size = style.get_font().font_size.size(); let font_size = style.get_font().font_size.size();
match style.get_inheritedtext().line_height { match style.get_inherited_text().line_height {
LineHeight::Normal => Au::from(metrics.line_gap), LineHeight::Normal => Au::from(metrics.line_gap),
LineHeight::Number(l) => font_size.scale_by(l.0), LineHeight::Number(l) => font_size.scale_by(l.0),
LineHeight::Length(l) => Au::from(l) LineHeight::Length(l) => Au::from(l)

View file

@ -979,7 +979,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
// //
// If you implement other values for this property, you will almost certainly // If you implement other values for this property, you will almost certainly
// want to update this check. // want to update this check.
!self.style(context).get_inheritedtext().white_space.preserve_newlines() !self.style(context).get_inherited_text().white_space.preserve_newlines()
} }
} }

View file

@ -128,7 +128,7 @@ use style::context::{QuirksMode, RegisteredSpeculativePainter, RegisteredSpecula
use style::context::{SharedStyleContext, StyleSystemOptions, ThreadLocalStyleContextCreationInfo}; use style::context::{SharedStyleContext, StyleSystemOptions, ThreadLocalStyleContextCreationInfo};
use style::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode}; use style::dom::{ShowSubtree, ShowSubtreeDataAndPrimaryValues, TElement, TNode};
use style::driver; use style::driver;
use style::error_reporting::{NullReporter, RustLogReporter}; use style::error_reporting::RustLogReporter;
use style::invalidation::element::restyle_hints::RestyleHint; use style::invalidation::element::restyle_hints::RestyleHint;
use style::logical_geometry::LogicalPoint; use style::logical_geometry::LogicalPoint;
use style::media_queries::{Device, MediaList, MediaType}; use style::media_queries::{Device, MediaList, MediaType};
@ -1754,7 +1754,7 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
MediaList::empty(), MediaList::empty(),
shared_lock.clone(), shared_lock.clone(),
None, None,
&NullReporter, None,
QuirksMode::NoQuirks, QuirksMode::NoQuirks,
)))) ))))
} }
@ -1782,7 +1782,7 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
MediaList::empty(), MediaList::empty(),
shared_lock.clone(), shared_lock.clone(),
None, None,
&RustLogReporter, Some(&RustLogReporter),
QuirksMode::NoQuirks, QuirksMode::NoQuirks,
))) )))
); );

View file

@ -42,7 +42,8 @@ impl CSS {
&url, &url,
Some(CssRuleType::Style), Some(CssRuleType::Style),
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
QuirksMode::NoQuirks QuirksMode::NoQuirks,
None,
); );
decl.eval(&context) decl.eval(&context)
} }
@ -58,7 +59,8 @@ impl CSS {
&url, &url,
Some(CssRuleType::Style), Some(CssRuleType::Style),
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
QuirksMode::NoQuirks QuirksMode::NoQuirks,
None,
); );
cond.eval(&context) cond.eval(&context)
} else { } else {

View file

@ -75,15 +75,15 @@ impl CSSMediaRule {
let window = global.as_window(); let window = global.as_window();
let url = window.get_url(); let url = window.get_url();
let quirks_mode = window.Document().quirks_mode(); let quirks_mode = window.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = ParserContext::new_for_cssom(
ParsingMode::DEFAULT, &url,
quirks_mode); Some(CssRuleType::Media),
ParsingMode::DEFAULT,
let new_medialist = StyleMediaList::parse( quirks_mode,
&context,
&mut input,
window.css_error_reporter(), window.css_error_reporter(),
); );
let new_medialist = StyleMediaList::parse(&context, &mut input);
let mut guard = self.cssconditionrule.shared_lock().write(); let mut guard = self.cssconditionrule.shared_lock().write();
// Clone an Arc because we cant borrow `guard` twice at the same time. // Clone an Arc because we cant borrow `guard` twice at the same time.

View file

@ -181,6 +181,19 @@ macro_rules! css_properties(
); );
); );
fn remove_property(
decls: &mut PropertyDeclarationBlock,
id: &PropertyId,
) -> bool {
let first_declaration = decls.first_declaration_to_remove(id);
let first_declaration = match first_declaration {
Some(i) => i,
None => return false,
};
decls.remove_property(id, first_declaration);
true
}
impl CSSStyleDeclaration { impl CSSStyleDeclaration {
#[allow(unrooted_must_root)] #[allow(unrooted_must_root)]
pub fn new_inherited(owner: CSSStyleOwner, pub fn new_inherited(owner: CSSStyleOwner,
@ -253,7 +266,7 @@ impl CSSStyleDeclaration {
self.owner.mutate_associated_block(|pdb, changed| { self.owner.mutate_associated_block(|pdb, changed| {
if value.is_empty() { if value.is_empty() {
// Step 3 // Step 3
*changed = pdb.remove_property(&id, |_| {}); *changed = remove_property(pdb, &id);
return Ok(()); return Ok(());
} }
@ -365,7 +378,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
let mut string = String::new(); let mut string = String::new();
self.owner.mutate_associated_block(|pdb, changed| { self.owner.mutate_associated_block(|pdb, changed| {
pdb.property_value_to_css(&id, &mut string).unwrap(); pdb.property_value_to_css(&id, &mut string).unwrap();
*changed = pdb.remove_property(&id, |_| {}); *changed = remove_property(pdb, &id);
}); });
// Step 6 // Step 6

View file

@ -63,9 +63,13 @@ impl CSSSupportsRule {
let win = global.as_window(); let win = global.as_window();
let url = win.Document().url(); let url = win.Document().url();
let quirks_mode = win.Document().quirks_mode(); let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Supports), let context = ParserContext::new_for_cssom(
ParsingMode::DEFAULT, &url,
quirks_mode); Some(CssRuleType::Supports),
ParsingMode::DEFAULT,
quirks_mode,
None,
);
let enabled = cond.eval(&context); let enabled = cond.eval(&context);
let mut guard = self.cssconditionrule.shared_lock().write(); let mut guard = self.cssconditionrule.shared_lock().write();
let rule = self.supportsrule.write_with(&mut guard); let rule = self.supportsrule.write_with(&mut guard);

View file

@ -127,6 +127,7 @@ use std::cell::{Cell, Ref, RefMut};
use std::collections::{HashMap, HashSet, VecDeque}; use std::collections::{HashMap, HashSet, VecDeque};
use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::default::Default; use std::default::Default;
use std::fmt;
use std::mem; use std::mem;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::rc::Rc; use std::rc::Rc;
@ -213,6 +214,12 @@ struct StyleSheetInDocument {
owner: Dom<Element>, owner: Dom<Element>,
} }
impl fmt::Debug for StyleSheetInDocument {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
self.sheet.fmt(formatter)
}
}
impl PartialEq for StyleSheetInDocument { impl PartialEq for StyleSheetInDocument {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.sheet, &other.sheet) Arc::ptr_eq(&self.sheet, &other.sheet)

View file

@ -770,10 +770,13 @@ pub fn parse_a_sizes_attribute(input: DOMString, width: Option<u32>) -> Vec<Size
} }
let mut input = ParserInput::new(&trimmed); let mut input = ParserInput::new(&trimmed);
let url = ServoUrl::parse("about:blank").unwrap(); let url = ServoUrl::parse("about:blank").unwrap();
let context = ParserContext::new_for_cssom(&url, let context = ParserContext::new_for_cssom(
None, &url,
ParsingMode::empty(), None,
QuirksMode::NoQuirks); ParsingMode::empty(),
QuirksMode::NoQuirks,
None,
);
let mut parser = Parser::new(&mut input); let mut parser = Parser::new(&mut input);
let length = parser.try(|i| Length::parse_non_negative(&context, i)); let length = parser.try(|i| Length::parse_non_negative(&context, i));
match length { match length {

View file

@ -277,6 +277,7 @@ impl HTMLLinkElement {
let mut input = ParserInput::new(&mq_str); let mut input = ParserInput::new(&mq_str);
let mut css_parser = CssParser::new(&mut input); let mut css_parser = CssParser::new(&mut input);
let doc_url = document.url(); let doc_url = document.url();
let window = document.window();
// FIXME(emilio): This looks somewhat fishy, since we use the context // FIXME(emilio): This looks somewhat fishy, since we use the context
// only to parse the media query list, CssRuleType::Media doesn't make // only to parse the media query list, CssRuleType::Media doesn't make
// much sense. // much sense.
@ -285,13 +286,9 @@ impl HTMLLinkElement {
Some(CssRuleType::Media), Some(CssRuleType::Media),
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
document.quirks_mode(), document.quirks_mode(),
);
let window = document.window();
let media = MediaList::parse(
&context,
&mut css_parser,
window.css_error_reporter(), window.css_error_reporter(),
); );
let media = MediaList::parse(&context, &mut css_parser);
let im_attribute = element.get_attribute(&ns!(), &local_name!("integrity")); let im_attribute = element.get_attribute(&ns!(), &local_name!("integrity"));
let integrity_val = im_attribute.r().map(|a| a.value()); let integrity_val = im_attribute.r().map(|a| a.value());

View file

@ -84,25 +84,32 @@ impl HTMLStyleElement {
let data = node.GetTextContent().expect("Element.textContent must be a string"); let data = node.GetTextContent().expect("Element.textContent must be a string");
let url = window.get_url(); let url = window.get_url();
let context = CssParserContext::new_for_cssom(&url, let css_error_reporter = window.css_error_reporter();
Some(CssRuleType::Media), let context = CssParserContext::new_for_cssom(
ParsingMode::DEFAULT, &url,
doc.quirks_mode()); Some(CssRuleType::Media),
ParsingMode::DEFAULT,
doc.quirks_mode(),
css_error_reporter,
);
let shared_lock = node.owner_doc().style_shared_lock().clone(); let shared_lock = node.owner_doc().style_shared_lock().clone();
let mut input = ParserInput::new(&mq_str); let mut input = ParserInput::new(&mq_str);
let css_error_reporter = window.css_error_reporter();
let mq = Arc::new(shared_lock.wrap(MediaList::parse( let mq = Arc::new(shared_lock.wrap(MediaList::parse(
&context, &context,
&mut CssParser::new(&mut input), &mut CssParser::new(&mut input),
css_error_reporter), )));
));
let loader = StylesheetLoader::for_element(self.upcast()); let loader = StylesheetLoader::for_element(self.upcast());
let sheet = Stylesheet::from_str(&data, window.get_url(), let sheet = Stylesheet::from_str(
Origin::Author, mq, &data,
shared_lock, Some(&loader), window.get_url(),
css_error_reporter, Origin::Author,
doc.quirks_mode(), mq,
self.line_number as u32); shared_lock,
Some(&loader),
css_error_reporter,
doc.quirks_mode(),
self.line_number as u32,
);
let sheet = Arc::new(sheet); let sheet = Arc::new(sheet);

View file

@ -77,14 +77,14 @@ impl MediaListMethods for MediaList {
let window = global.as_window(); let window = global.as_window();
let url = window.get_url(); let url = window.get_url();
let quirks_mode = window.Document().quirks_mode(); let quirks_mode = window.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = ParserContext::new_for_cssom(
ParsingMode::DEFAULT, &url,
quirks_mode); Some(CssRuleType::Media),
*media_queries = StyleMediaList::parse( ParsingMode::DEFAULT,
&context, quirks_mode,
&mut parser,
window.css_error_reporter(), window.css_error_reporter(),
); );
*media_queries = StyleMediaList::parse(&context, &mut parser);
} }
// https://drafts.csswg.org/cssom/#dom-medialist-length // https://drafts.csswg.org/cssom/#dom-medialist-length
@ -117,9 +117,13 @@ impl MediaListMethods for MediaList {
let win = global.as_window(); let win = global.as_window();
let url = win.get_url(); let url = win.get_url();
let quirks_mode = win.Document().quirks_mode(); let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = ParserContext::new_for_cssom(
ParsingMode::DEFAULT, &url,
quirks_mode); Some(CssRuleType::Media),
ParsingMode::DEFAULT,
quirks_mode,
win.css_error_reporter(),
);
let m = MediaQuery::parse(&context, &mut parser); let m = MediaQuery::parse(&context, &mut parser);
// Step 2 // Step 2
if let Err(_) = m { if let Err(_) = m {
@ -146,9 +150,13 @@ impl MediaListMethods for MediaList {
let win = global.as_window(); let win = global.as_window();
let url = win.get_url(); let url = win.get_url();
let quirks_mode = win.Document().quirks_mode(); let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = ParserContext::new_for_cssom(
ParsingMode::DEFAULT, &url,
quirks_mode); Some(CssRuleType::Media),
ParsingMode::DEFAULT,
quirks_mode,
win.css_error_reporter(),
);
let m = MediaQuery::parse(&context, &mut parser); let m = MediaQuery::parse(&context, &mut parser);
// Step 2 // Step 2
if let Err(_) = m { if let Err(_) = m {

View file

@ -100,6 +100,7 @@ use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Sender, channel}; use std::sync::mpsc::{Sender, channel};
use std::sync::mpsc::TryRecvError::{Disconnected, Empty}; use std::sync::mpsc::TryRecvError::{Disconnected, Empty};
use style::error_reporting::ParseErrorReporter;
use style::media_queries; use style::media_queries;
use style::parser::ParserContext as CssParserContext; use style::parser::ParserContext as CssParserContext;
use style::properties::{ComputedValues, PropertyId}; use style::properties::{ComputedValues, PropertyId};
@ -389,8 +390,8 @@ impl Window {
&self.bluetooth_extra_permission_data &self.bluetooth_extra_permission_data
} }
pub fn css_error_reporter(&self) -> &CSSErrorReporter { pub fn css_error_reporter(&self) -> Option<&ParseErrorReporter> {
&self.error_reporter Some(&self.error_reporter)
} }
/// Sets a new list of scroll offsets. /// Sets a new list of scroll offsets.
@ -1017,14 +1018,15 @@ impl WindowMethods for Window {
let mut parser = Parser::new(&mut input); let mut parser = Parser::new(&mut input);
let url = self.get_url(); let url = self.get_url();
let quirks_mode = self.Document().quirks_mode(); let quirks_mode = self.Document().quirks_mode();
let context = CssParserContext::new_for_cssom(&url, Some(CssRuleType::Media), let context = CssParserContext::new_for_cssom(
ParsingMode::DEFAULT, &url,
quirks_mode); Some(CssRuleType::Media),
let media_query_list = media_queries::MediaList::parse( ParsingMode::DEFAULT,
&context, quirks_mode,
&mut parser,
self.css_error_reporter(), self.css_error_reporter(),
); );
let media_query_list =
media_queries::MediaList::parse(&context, &mut parser);
let document = self.Document(); let document = self.Document();
let mql = MediaQueryList::new(&document, media_query_list); let mql = MediaQueryList::new(&document, media_query_list);
self.media_query_lists.push(&*mql); self.media_query_lists.push(&*mql);

View file

@ -9,8 +9,8 @@
use Atom; use Atom;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser}; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
use cssparser::{CowRcStr, Parser, SourceLocation, Token}; use cssparser::{CowRcStr, Parser, SourceLocation, Token};
use error_reporting::{ContextualParseError, ParseErrorReporter}; use error_reporting::ContextualParseError;
use parser::{Parse, ParserContext, ParserErrorContext}; use parser::{Parse, ParserContext};
use selectors::parser::SelectorParseErrorKind; use selectors::parser::SelectorParseErrorKind;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt::{self, Write}; use std::fmt::{self, Write};
@ -73,16 +73,12 @@ pub fn parse_counter_style_name_definition<'i, 't>(
} }
/// Parse the body (inside `{}`) of an @counter-style rule /// Parse the body (inside `{}`) of an @counter-style rule
pub fn parse_counter_style_body<'i, 't, R>( pub fn parse_counter_style_body<'i, 't>(
name: CustomIdent, name: CustomIdent,
context: &ParserContext, context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
location: SourceLocation, location: SourceLocation,
) -> Result<CounterStyleRuleData, ParseError<'i>> ) -> Result<CounterStyleRuleData, ParseError<'i>> {
where
R: ParseErrorReporter,
{
let start = input.current_source_location(); let start = input.current_source_location();
let mut rule = CounterStyleRuleData::empty(name, location); let mut rule = CounterStyleRuleData::empty(name, location);
{ {
@ -98,7 +94,7 @@ where
slice, slice,
error, error,
); );
context.log_css_error(error_context, location, error) context.log_css_error(location, error)
} }
} }
} }
@ -134,7 +130,7 @@ where
_ => None, _ => None,
}; };
if let Some(error) = error { if let Some(error) = error {
context.log_css_error(error_context, start, error); context.log_css_error(start, error);
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
} else { } else {
Ok(rule) Ok(rule)

View file

@ -55,7 +55,7 @@ impl Stylesheet {
/// ///
/// Takes care of decoding the network bytes and forwards the resulting /// Takes care of decoding the network bytes and forwards the resulting
/// string to `Stylesheet::from_str`. /// string to `Stylesheet::from_str`.
pub fn from_bytes<R>( pub fn from_bytes(
bytes: &[u8], bytes: &[u8],
url_data: UrlExtraData, url_data: UrlExtraData,
protocol_encoding_label: Option<&str>, protocol_encoding_label: Option<&str>,
@ -64,12 +64,9 @@ impl Stylesheet {
media: MediaList, media: MediaList,
shared_lock: SharedRwLock, shared_lock: SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R, error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
) -> Stylesheet ) -> Stylesheet {
where
R: ParseErrorReporter,
{
let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding); let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding);
Stylesheet::from_str( Stylesheet::from_str(
&string, &string,
@ -86,17 +83,15 @@ impl Stylesheet {
/// Updates an empty stylesheet with a set of bytes that reached over the /// Updates an empty stylesheet with a set of bytes that reached over the
/// network. /// network.
pub fn update_from_bytes<R>( pub fn update_from_bytes(
existing: &Stylesheet, existing: &Stylesheet,
bytes: &[u8], bytes: &[u8],
protocol_encoding_label: Option<&str>, protocol_encoding_label: Option<&str>,
environment_encoding: Option<&'static encoding_rs::Encoding>, environment_encoding: Option<&'static encoding_rs::Encoding>,
url_data: UrlExtraData, url_data: UrlExtraData,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R, error_reporter: Option<&ParseErrorReporter>,
) where ) {
R: ParseErrorReporter,
{
let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding); let string = decode_stylesheet_bytes(bytes, protocol_encoding_label, environment_encoding);
Self::update_from_str( Self::update_from_str(
existing, existing,

View file

@ -7,7 +7,6 @@
#![deny(missing_docs)] #![deny(missing_docs)]
use cssparser::{BasicParseErrorKind, ParseErrorKind, SourceLocation, Token}; use cssparser::{BasicParseErrorKind, ParseErrorKind, SourceLocation, Token};
use log;
use std::fmt; use std::fmt;
use style_traits::ParseError; use style_traits::ParseError;
use stylesheets::UrlExtraData; use stylesheets::UrlExtraData;
@ -229,8 +228,10 @@ pub trait ParseErrorReporter {
/// This logging is silent by default, and can be enabled with a `RUST_LOG=style=info` /// This logging is silent by default, and can be enabled with a `RUST_LOG=style=info`
/// environment variable. /// environment variable.
/// (See [`env_logger`](https://rust-lang-nursery.github.io/log/env_logger/).) /// (See [`env_logger`](https://rust-lang-nursery.github.io/log/env_logger/).)
#[cfg(feature = "servo")]
pub struct RustLogReporter; pub struct RustLogReporter;
#[cfg(feature = "servo")]
impl ParseErrorReporter for RustLogReporter { impl ParseErrorReporter for RustLogReporter {
fn report_error( fn report_error(
&self, &self,
@ -238,6 +239,7 @@ impl ParseErrorReporter for RustLogReporter {
location: SourceLocation, location: SourceLocation,
error: ContextualParseError, error: ContextualParseError,
) { ) {
use log;
if log_enabled!(log::Level::Info) { if log_enabled!(log::Level::Info) {
info!( info!(
"Url:\t{}\n{}:{} {}", "Url:\t{}\n{}:{} {}",
@ -249,17 +251,3 @@ impl ParseErrorReporter for RustLogReporter {
} }
} }
} }
/// Error reporter which silently forgets errors
pub struct NullReporter;
impl ParseErrorReporter for NullReporter {
fn report_error(
&self,
_url: &UrlExtraData,
_location: SourceLocation,
_error: ContextualParseError,
) {
// do nothing
}
}

View file

@ -10,8 +10,8 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::{CowRcStr, SourceLocation}; use cssparser::{CowRcStr, SourceLocation};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use cssparser::UnicodeRange; use cssparser::UnicodeRange;
use error_reporting::{ContextualParseError, ParseErrorReporter}; use error_reporting::ContextualParseError;
use parser::{Parse, ParserContext, ParserErrorContext}; use parser::{Parse, ParserContext};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use properties::longhands::font_language_override; use properties::longhands::font_language_override;
use selectors::parser::SelectorParseErrorKind; use selectors::parser::SelectorParseErrorKind;
@ -186,15 +186,11 @@ impl ToCss for FontStyle {
/// 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<R>( pub fn parse_font_face_block(
context: &ParserContext, context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser, input: &mut Parser,
location: SourceLocation, location: SourceLocation,
) -> FontFaceRuleData ) -> FontFaceRuleData {
where
R: ParseErrorReporter,
{
let mut rule = FontFaceRuleData::empty(location); let mut rule = FontFaceRuleData::empty(location);
{ {
let parser = FontFaceRuleParser { let parser = FontFaceRuleParser {
@ -206,7 +202,7 @@ where
if let Err((error, slice)) = declaration { if let Err((error, slice)) = declaration {
let location = error.location; let location = error.location;
let error = ContextualParseError::UnsupportedFontFaceDescriptor(slice, error); let error = ContextualParseError::UnsupportedFontFaceDescriptor(slice, error);
context.log_css_error(error_context, location, error) context.log_css_error(location, error)
} }
} }
} }

View file

@ -18,13 +18,24 @@ use properties::ComputedValues;
use selector_parser::SnapshotMap; use selector_parser::SnapshotMap;
use servo_arc::Arc; use servo_arc::Arc;
use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
use std::fmt;
use stylesheets::{CssRule, Origin, StylesheetContents, StylesheetInDocument}; use stylesheets::{CssRule, Origin, StylesheetContents, StylesheetInDocument};
use stylist::Stylist; use stylist::Stylist;
/// Little wrapper to a Gecko style sheet. /// Little wrapper to a Gecko style sheet.
#[derive(Debug, Eq, PartialEq)] #[derive(Eq, PartialEq)]
pub struct GeckoStyleSheet(*const DomStyleSheet); pub struct GeckoStyleSheet(*const DomStyleSheet);
impl fmt::Debug for GeckoStyleSheet {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let contents = self.contents();
formatter.debug_struct("GeckoStyleSheet")
.field("origin", &contents.origin)
.field("url_data", &*contents.url_data.read())
.finish()
}
}
impl ToMediaListKey for ::gecko::data::GeckoStyleSheet { impl ToMediaListKey for ::gecko::data::GeckoStyleSheet {
fn to_media_list_key(&self) -> MediaListKey { fn to_media_list_key(&self) -> MediaListKey {
use std::mem; use std::mem;

View file

@ -64,6 +64,27 @@ pub struct Device {
used_viewport_size: AtomicBool, used_viewport_size: AtomicBool,
} }
impl fmt::Debug for Device {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use nsstring::nsCString;
let mut doc_uri = nsCString::new();
unsafe {
let doc =
&*self.pres_context().mDocument.raw::<structs::nsIDocument>();
bindings::Gecko_nsIURI_Debug(
doc.mDocumentURI.raw::<structs::nsIURI>(),
&mut doc_uri,
)
};
f.debug_struct("Device")
.field("document_url", &doc_uri)
.finish()
}
}
unsafe impl Sync for Device {} unsafe impl Sync for Device {}
unsafe impl Send for Device {} unsafe impl Send for Device {}

View file

@ -6,7 +6,7 @@
use cssparser::Parser; use cssparser::Parser;
use gecko_bindings::bindings; use gecko_bindings::bindings;
use gecko_bindings::structs::{ServoBundledURI, URLExtraData}; use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::structs::mozilla::css::URLValueData; use gecko_bindings::structs::mozilla::css::URLValueData;
use gecko_bindings::structs::root::{RustString, nsStyleImageRequest}; use gecko_bindings::structs::root::{RustString, nsStyleImageRequest};
use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue}; use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue};
@ -18,6 +18,7 @@ use servo_arc::{Arc, RawOffsetArc};
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use std::mem; use std::mem;
use style_traits::{CssWriter, ParseError, ToCss}; use style_traits::{CssWriter, ParseError, ToCss};
use stylesheets::UrlExtraData;
use values::computed::{Context, ToComputedValue}; use values::computed::{Context, ToComputedValue};
/// A CSS url() value for gecko. /// A CSS url() value for gecko.
@ -32,7 +33,7 @@ pub struct CssUrl {
/// The URL extra data. /// The URL extra data.
#[css(skip)] #[css(skip)]
pub extra_data: RefPtr<URLExtraData>, pub extra_data: UrlExtraData,
} }
impl CssUrl { impl CssUrl {
@ -58,7 +59,7 @@ impl CssUrl {
&url.mString as *const _ as *const RawOffsetArc<String>; &url.mString as *const _ as *const RawOffsetArc<String>;
CssUrl { CssUrl {
serialization: Arc::from_raw_offset((*arc_type).clone()), serialization: Arc::from_raw_offset((*arc_type).clone()),
extra_data: url.mExtraData.to_safe(), extra_data: UrlExtraData(url.mExtraData.to_safe()),
} }
} }
@ -88,7 +89,7 @@ impl CssUrl {
let arc_offset = Arc::into_raw_offset(self.serialization.clone()); let arc_offset = Arc::into_raw_offset(self.serialization.clone());
ServoBundledURI { ServoBundledURI {
mURLString: unsafe { mem::transmute::<_, RawOffsetArc<RustString>>(arc_offset) }, mURLString: unsafe { mem::transmute::<_, RawOffsetArc<RustString>>(arc_offset) },
mExtraData: self.extra_data.get(), mExtraData: self.extra_data.0.get(),
} }
} }
} }

View file

@ -78,15 +78,6 @@ impl<T: RefCounted> RefPtr<T> {
ret ret
} }
/// Create a reference to RefPtr from a reference to pointer.
///
/// The pointer must be valid and non null.
///
/// This method doesn't touch refcount.
pub unsafe fn from_ptr_ref(ptr: &*mut T) -> &Self {
mem::transmute(ptr)
}
/// Produces an FFI-compatible RefPtr that can be stored in style structs. /// Produces an FFI-compatible RefPtr that can be stored in style structs.
/// ///
/// structs::RefPtr does not have a destructor, so this may leak /// structs::RefPtr does not have a destructor, so this may leak

View file

@ -122,7 +122,8 @@ impl WeakAtom {
unsafe { u8_ptr.offset(string_offset) as *const u16 } unsafe { u8_ptr.offset(string_offset) as *const u16 }
} else { } else {
let atom_ptr = self.as_ptr() as *const nsDynamicAtom; let atom_ptr = self.as_ptr() as *const nsDynamicAtom;
unsafe { (*(atom_ptr)).mString } // Dynamic atom chars are stored at the end of the object.
unsafe { atom_ptr.offset(1) as *const u16 }
}; };
unsafe { slice::from_raw_parts(string, self.len() as usize) } unsafe { slice::from_raw_parts(string, self.len() as usize) }
} }

View file

@ -9,13 +9,13 @@
use context::QuirksMode; use context::QuirksMode;
use cssparser::{Delimiter, Parser}; use cssparser::{Delimiter, Parser};
use cssparser::{ParserInput, Token}; use cssparser::{ParserInput, Token};
use error_reporting::{ContextualParseError, ParseErrorReporter}; use error_reporting::ContextualParseError;
use parser::{ParserContext, ParserErrorContext}; use parser::ParserContext;
use super::{Device, MediaQuery, Qualifier}; use super::{Device, MediaQuery, Qualifier};
/// A type that encapsulates a media query list. /// A type that encapsulates a media query list.
#[css(comma)] #[css(comma, derive_debug)]
#[derive(Clone, Debug, MallocSizeOf, ToCss)] #[derive(Clone, MallocSizeOf, ToCss)]
pub struct MediaList { pub struct MediaList {
/// The list of media queries. /// The list of media queries.
#[css(iterable)] #[css(iterable)]
@ -30,14 +30,10 @@ impl MediaList {
/// "not all", see: /// "not all", see:
/// ///
/// <https://drafts.csswg.org/mediaqueries/#error-handling> /// <https://drafts.csswg.org/mediaqueries/#error-handling>
pub fn parse<R>( pub fn parse(
context: &ParserContext, context: &ParserContext,
input: &mut Parser, input: &mut Parser,
error_reporter: &R, ) -> Self {
) -> MediaList
where
R: ParseErrorReporter,
{
if input.is_exhausted() { if input.is_exhausted() {
return Self::empty(); return Self::empty();
} }
@ -54,8 +50,7 @@ impl MediaList {
let location = err.location; let location = err.location;
let error = let error =
ContextualParseError::InvalidMediaRule(input.slice_from(start_position), err); ContextualParseError::InvalidMediaRule(input.slice_from(start_position), err);
let error_context = ParserErrorContext { error_reporter }; context.log_css_error(location, error);
context.log_css_error(&error_context, location, error);
}, },
} }

View file

@ -36,12 +36,6 @@ pub fn assert_parsing_mode_match() {
} }
} }
/// The context required to report a parse error.
pub struct ParserErrorContext<'a, R: 'a> {
/// An error reporter to report syntax errors.
pub error_reporter: &'a R,
}
/// The data that the parser needs from outside in order to parse a stylesheet. /// The data that the parser needs from outside in order to parse a stylesheet.
pub struct ParserContext<'a> { pub struct ParserContext<'a> {
/// The `Origin` of the stylesheet, whether it's a user, author or /// The `Origin` of the stylesheet, whether it's a user, author or
@ -55,6 +49,8 @@ pub struct ParserContext<'a> {
pub parsing_mode: ParsingMode, pub parsing_mode: ParsingMode,
/// The quirks mode of this stylesheet. /// The quirks mode of this stylesheet.
pub quirks_mode: QuirksMode, pub quirks_mode: QuirksMode,
/// The active error reporter, or none if error reporting is disabled.
error_reporter: Option<&'a ParseErrorReporter>,
/// The currently active namespaces. /// The currently active namespaces.
pub namespaces: Option<&'a Namespaces>, pub namespaces: Option<&'a Namespaces>,
} }
@ -68,6 +64,7 @@ impl<'a> ParserContext<'a> {
rule_type: Option<CssRuleType>, rule_type: Option<CssRuleType>,
parsing_mode: ParsingMode, parsing_mode: ParsingMode,
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
error_reporter: Option<&'a ParseErrorReporter>,
) -> Self { ) -> Self {
ParserContext { ParserContext {
stylesheet_origin, stylesheet_origin,
@ -75,6 +72,7 @@ impl<'a> ParserContext<'a> {
rule_type, rule_type,
parsing_mode, parsing_mode,
quirks_mode, quirks_mode,
error_reporter,
namespaces: None, namespaces: None,
} }
} }
@ -86,6 +84,7 @@ impl<'a> ParserContext<'a> {
rule_type: Option<CssRuleType>, rule_type: Option<CssRuleType>,
parsing_mode: ParsingMode, parsing_mode: ParsingMode,
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
error_reporter: Option<&'a ParseErrorReporter>,
) -> Self { ) -> Self {
Self::new( Self::new(
Origin::Author, Origin::Author,
@ -93,6 +92,7 @@ impl<'a> ParserContext<'a> {
rule_type, rule_type,
parsing_mode, parsing_mode,
quirks_mode, quirks_mode,
error_reporter,
) )
} }
@ -110,6 +110,7 @@ impl<'a> ParserContext<'a> {
parsing_mode: context.parsing_mode, parsing_mode: context.parsing_mode,
quirks_mode: context.quirks_mode, quirks_mode: context.quirks_mode,
namespaces: Some(namespaces), namespaces: Some(namespaces),
error_reporter: context.error_reporter,
} }
} }
@ -127,21 +128,17 @@ impl<'a> ParserContext<'a> {
} }
/// Record a CSS parse error with this contexts error reporting. /// Record a CSS parse error with this contexts error reporting.
pub fn log_css_error<R>( pub fn log_css_error(
&self, &self,
context: &ParserErrorContext<R>,
location: SourceLocation, location: SourceLocation,
error: ContextualParseError, error: ContextualParseError,
) where ) {
R: ParseErrorReporter, let error_reporter = match self.error_reporter {
{ Some(r) => r,
let location = SourceLocation { None => return,
line: location.line,
column: location.column,
}; };
context
.error_reporter error_reporter.report_error(self.url_data, location, error)
.report_error(self.url_data, location, error)
} }
/// Returns whether chrome-only rules should be parsed. /// Returns whether chrome-only rules should be parsed.

View file

@ -19,6 +19,34 @@ import data
RE_PYTHON_ADDR = re.compile(r'<.+? object at 0x[0-9a-fA-F]+>') RE_PYTHON_ADDR = re.compile(r'<.+? object at 0x[0-9a-fA-F]+>')
OUT_DIR = os.environ.get("OUT_DIR", "")
STYLE_STRUCT_LIST = [
"background",
"border",
"box",
"color",
"column",
"counters",
"effects",
"font",
"inherited_box",
"inherited_table",
"inherited_text",
"inherited_ui",
"inherited_svg",
"list",
"margin",
"outline",
"padding",
"position",
"table",
"text",
"ui",
"svg",
"xul",
]
def main(): def main():
usage = "Usage: %s [ servo | gecko ] [ style-crate | geckolib <template> | html ]" % sys.argv[0] usage = "Usage: %s [ servo | gecko ] [ style-crate | geckolib <template> | html ]" % sys.argv[0]
@ -31,14 +59,41 @@ def main():
abort(usage) abort(usage)
properties = data.PropertiesData(product=product) properties = data.PropertiesData(product=product)
template = os.path.join(BASE, "properties.mako.rs") files = {}
rust = render(template, product=product, data=properties, __file__=template) for kind in ["longhands", "shorthands"]:
files[kind] = {}
for struct in STYLE_STRUCT_LIST:
file_name = os.path.join(BASE, kind, "{}.mako.rs".format(struct))
if kind == "shorthands" and not os.path.exists(file_name):
files[kind][struct] = ""
continue
files[kind][struct] = render(
file_name,
product=product,
data=properties,
)
properties_template = os.path.join(BASE, "properties.mako.rs")
files["properties"] = render(
properties_template,
product=product,
data=properties,
__file__=properties_template,
OUT_DIR=OUT_DIR,
)
if output == "style-crate": if output == "style-crate":
write(os.environ["OUT_DIR"], "properties.rs", rust) write(OUT_DIR, "properties.rs", files["properties"])
for kind in ["longhands", "shorthands"]:
for struct in files[kind]:
write(
os.path.join(OUT_DIR, kind),
"{}.rs".format(struct),
files[kind][struct],
)
if product == "gecko": if product == "gecko":
template = os.path.join(BASE, "gecko.mako.rs") template = os.path.join(BASE, "gecko.mako.rs")
rust = render(template, data=properties) rust = render(template, data=properties)
write(os.environ["OUT_DIR"], "gecko_properties.rs", rust) write(OUT_DIR, "gecko_properties.rs", rust)
elif output == "geckolib": elif output == "geckolib":
if len(sys.argv) < 4: if len(sys.argv) < 4:
abort(usage) abort(usage)

View file

@ -38,6 +38,10 @@ def to_rust_ident(name):
return name return name
def to_snake_case(ident):
return re.sub("([A-Z]+)", lambda m: "_" + m.group(1).lower(), ident).strip("_")
def to_camel_case(ident): def to_camel_case(ident):
return re.sub("(^|_|-)([a-z0-9])", lambda m: m.group(2).upper(), ident.strip("_").strip("-")) return re.sub("(^|_|-)([a-z0-9])", lambda m: m.group(2).upper(), ident.strip("_").strip("-"))
@ -451,7 +455,7 @@ class StyleStruct(object):
def __init__(self, name, inherited, gecko_name=None, additional_methods=None): def __init__(self, name, inherited, gecko_name=None, additional_methods=None):
self.gecko_struct_name = "Gecko" + name self.gecko_struct_name = "Gecko" + name
self.name = name self.name = name
self.name_lower = name.lower() self.name_lower = to_snake_case(name)
self.ident = to_rust_ident(self.name_lower) self.ident = to_rust_ident(self.name_lower)
self.longhands = [] self.longhands = []
self.inherited = inherited self.inherited = inherited

View file

@ -11,8 +11,8 @@ use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind}; use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind};
use custom_properties::CustomPropertiesBuilder; use custom_properties::CustomPropertiesBuilder;
use error_reporting::{ParseErrorReporter, ContextualParseError}; use error_reporting::{ParseErrorReporter, ContextualParseError};
use parser::{ParserContext, ParserErrorContext}; use parser::ParserContext;
use properties::animated_properties::AnimationValue; use properties::animated_properties::{AnimationValue, AnimationValueMap};
use shared_lock::Locked; use shared_lock::Locked;
use smallbitvec::{self, SmallBitVec}; use smallbitvec::{self, SmallBitVec};
use smallvec::SmallVec; use smallvec::SmallVec;
@ -24,7 +24,6 @@ use style_traits::{CssWriter, ParseError, ParsingMode, StyleParseErrorKind, ToCs
use stylesheets::{CssRuleType, Origin, UrlExtraData}; use stylesheets::{CssRuleType, Origin, UrlExtraData};
use super::*; use super::*;
use values::computed::Context; use values::computed::Context;
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
/// The animation rules. /// The animation rules.
/// ///
@ -564,51 +563,71 @@ impl PropertyDeclarationBlock {
true true
} }
/// Returns the first declaration that would be removed by removing
/// `property`.
#[inline]
pub fn first_declaration_to_remove(
&self,
property: &PropertyId,
) -> Option<usize> {
if let Some(id) = property.longhand_id() {
if !self.longhands.contains(id) {
return None;
}
}
self.declarations.iter().position(|declaration| {
declaration.id().is_or_is_longhand_of(property)
})
}
/// Removes a given declaration at a given index.
#[inline]
fn remove_declaration_at(&mut self, i: usize) {
{
let id = self.declarations[i].id();
if let PropertyDeclarationId::Longhand(id) = id {
self.longhands.remove(id);
}
self.declarations_importance.remove(i);
}
self.declarations.remove(i);
}
/// <https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty> /// <https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty>
/// ///
/// Returns whether any declaration was actually removed. /// `first_declaration` needs to be the result of
pub fn remove_property<C>( /// `first_declaration_to_remove`.
#[inline]
pub fn remove_property(
&mut self, &mut self,
property: &PropertyId, property: &PropertyId,
mut before_change_callback: C, first_declaration: usize,
) -> bool ) {
where debug_assert_eq!(
C: FnMut(&Self), Some(first_declaration),
{ self.first_declaration_to_remove(property)
let longhand_id = property.longhand_id(); );
if let Some(id) = longhand_id { debug_assert!(self.declarations[first_declaration].id().is_or_is_longhand_of(property));
if !self.longhands.contains(id) {
return false self.remove_declaration_at(first_declaration);
}
} let shorthand = match property.as_shorthand() {
let mut removed_at_least_one = false; Ok(s) => s,
let mut i = 0; Err(_longhand_or_custom) => return,
};
let mut i = first_declaration;
let mut len = self.len(); let mut len = self.len();
while i < len { while i < len {
{ if !self.declarations[i].id().is_longhand_of(shorthand) {
let id = self.declarations[i].id(); i += 1;
if !id.is_or_is_longhand_of(property) { continue;
i += 1;
continue;
}
if !removed_at_least_one {
before_change_callback(&*self);
}
removed_at_least_one = true;
if let PropertyDeclarationId::Longhand(id) = id {
self.longhands.remove(id);
}
self.declarations_importance.remove(i);
} }
self.declarations.remove(i);
self.remove_declaration_at(i);
len -= 1; len -= 1;
} }
if longhand_id.is_some() {
debug_assert!(removed_at_least_one);
}
removed_at_least_one
} }
/// Take a declaration block known to contain a single property and serialize it. /// Take a declaration block known to contain a single property and serialize it.
@ -667,7 +686,6 @@ impl PropertyDeclarationBlock {
} }
/// Convert AnimationValueMap to PropertyDeclarationBlock. /// Convert AnimationValueMap to PropertyDeclarationBlock.
#[cfg(feature = "gecko")]
pub fn from_animation_value_map(animation_value_map: &AnimationValueMap) -> Self { pub fn from_animation_value_map(animation_value_map: &AnimationValueMap) -> Self {
let len = animation_value_map.len(); let len = animation_value_map.len();
let mut declarations = Vec::with_capacity(len); let mut declarations = Vec::with_capacity(len);
@ -687,7 +705,6 @@ impl PropertyDeclarationBlock {
/// Returns true if the declaration block has a CSSWideKeyword for the given /// Returns true if the declaration block has a CSSWideKeyword for the given
/// property. /// property.
#[cfg(feature = "gecko")]
pub fn has_css_wide_keyword(&self, property: &PropertyId) -> bool { pub fn has_css_wide_keyword(&self, property: &PropertyId) -> bool {
if let Some(id) = property.longhand_id() { if let Some(id) = property.longhand_id() {
if !self.longhands.contains(id) { if !self.longhands.contains(id) {
@ -727,9 +744,7 @@ impl PropertyDeclarationBlock {
builder.build() builder.build()
} }
}
impl PropertyDeclarationBlock {
/// Like the method on ToCss, but without the type parameter to avoid /// Like the method on ToCss, but without the type parameter to avoid
/// accidentally monomorphizing this large function multiple times for /// accidentally monomorphizing this large function multiple times for
/// different writers. /// different writers.
@ -1061,50 +1076,49 @@ where
/// A helper to parse the style attribute of an element, in order for this to be /// A helper to parse the style attribute of an element, in order for this to be
/// shared between Servo and Gecko. /// shared between Servo and Gecko.
pub fn parse_style_attribute<R>( ///
/// Inline because we call this cross-crate.
#[inline]
pub fn parse_style_attribute(
input: &str, input: &str,
url_data: &UrlExtraData, url_data: &UrlExtraData,
error_reporter: &R, error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
) -> PropertyDeclarationBlock ) -> PropertyDeclarationBlock {
where
R: ParseErrorReporter
{
let context = ParserContext::new( let context = ParserContext::new(
Origin::Author, Origin::Author,
url_data, url_data,
Some(CssRuleType::Style), Some(CssRuleType::Style),
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
quirks_mode, quirks_mode,
error_reporter,
); );
let error_context = ParserErrorContext { error_reporter: error_reporter };
let mut input = ParserInput::new(input); let mut input = ParserInput::new(input);
parse_property_declaration_list(&context, &error_context, &mut Parser::new(&mut input)) parse_property_declaration_list(&context, &mut Parser::new(&mut input))
} }
/// Parse a given property declaration. Can result in multiple /// Parse a given property declaration. Can result in multiple
/// `PropertyDeclaration`s when expanding a shorthand, for example. /// `PropertyDeclaration`s when expanding a shorthand, for example.
/// ///
/// This does not attempt to parse !important at all. /// This does not attempt to parse !important at all.
pub fn parse_one_declaration_into<R>( #[inline]
pub fn parse_one_declaration_into(
declarations: &mut SourcePropertyDeclaration, declarations: &mut SourcePropertyDeclaration,
id: PropertyId, id: PropertyId,
input: &str, input: &str,
url_data: &UrlExtraData, url_data: &UrlExtraData,
error_reporter: &R, error_reporter: Option<&ParseErrorReporter>,
parsing_mode: ParsingMode, parsing_mode: ParsingMode,
quirks_mode: QuirksMode quirks_mode: QuirksMode
) -> Result<(), ()> ) -> Result<(), ()> {
where
R: ParseErrorReporter
{
let context = ParserContext::new( let context = ParserContext::new(
Origin::Author, Origin::Author,
url_data, url_data,
Some(CssRuleType::Style), Some(CssRuleType::Style),
parsing_mode, parsing_mode,
quirks_mode, quirks_mode,
error_reporter,
); );
let mut input = ParserInput::new(input); let mut input = ParserInput::new(input);
@ -1115,9 +1129,10 @@ where
}).map_err(|err| { }).map_err(|err| {
let location = err.location; let location = err.location;
let error = ContextualParseError::UnsupportedPropertyDeclaration( let error = ContextualParseError::UnsupportedPropertyDeclaration(
parser.slice_from(start_position), err); parser.slice_from(start_position),
let error_context = ParserErrorContext { error_reporter: error_reporter }; err,
context.log_css_error(&error_context, location, error); );
context.log_css_error(location, error);
}) })
} }
@ -1177,14 +1192,10 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
/// Parse a list of property declarations and return a property declaration /// Parse a list of property declarations and return a property declaration
/// block. /// block.
pub fn parse_property_declaration_list<R>( pub fn parse_property_declaration_list(
context: &ParserContext, context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser, input: &mut Parser,
) -> PropertyDeclarationBlock ) -> PropertyDeclarationBlock {
where
R: ParseErrorReporter
{
let mut declarations = SourcePropertyDeclaration::new(); let mut declarations = SourcePropertyDeclaration::new();
let mut block = PropertyDeclarationBlock::new(); let mut block = PropertyDeclarationBlock::new();
let parser = PropertyDeclarationParser { let parser = PropertyDeclarationParser {
@ -1212,7 +1223,7 @@ where
let location = error.location; let location = error.location;
let error = ContextualParseError::UnsupportedPropertyDeclaration(slice, error); let error = ContextualParseError::UnsupportedPropertyDeclaration(slice, error);
context.log_css_error(error_context, location, error); context.log_css_error(location, error);
} }
} }
} }

View file

@ -25,7 +25,7 @@ use servo_arc::Arc;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{cmp, ptr}; use std::{cmp, ptr};
use std::mem::{self, ManuallyDrop}; use std::mem::{self, ManuallyDrop};
#[cfg(feature = "gecko")] use hash::FnvHashMap; use hash::FnvHashMap;
use super::ComputedValues; use super::ComputedValues;
use values::CSSFloat; use values::CSSFloat;
use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero};
@ -229,8 +229,8 @@ impl AnimatedProperty {
/// A collection of AnimationValue that were composed on an element. /// A collection of AnimationValue that were composed on an element.
/// This HashMap stores the values that are the last AnimationValue to be /// This HashMap stores the values that are the last AnimationValue to be
/// composed for each TransitionProperty. /// composed for each TransitionProperty.
#[cfg(feature = "gecko")]
pub type AnimationValueMap = FnvHashMap<LonghandId, AnimationValue>; pub type AnimationValueMap = FnvHashMap<LonghandId, AnimationValue>;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
unsafe impl HasFFI for AnimationValueMap { unsafe impl HasFFI for AnimationValueMap {
type FFIType = RawServoAnimationValueMap; type FFIType = RawServoAnimationValueMap;

View file

@ -606,8 +606,9 @@ ${helpers.single_keyword("-moz-appearance",
scalethumb-horizontal scalethumbstart scalethumbtick scalethumb-vertical scale-vertical scalethumb-horizontal scalethumbstart scalethumbtick scalethumb-vertical scale-vertical
scrollbar scrollbar-horizontal scrollbar-small scrollbar-vertical scrollbarbutton-down scrollbar scrollbar-horizontal scrollbar-small scrollbar-vertical scrollbarbutton-down
scrollbarbutton-left scrollbarbutton-right scrollbarbutton-up scrollbarthumb-horizontal scrollbarbutton-left scrollbarbutton-right scrollbarbutton-up scrollbarthumb-horizontal
scrollbarthumb-vertical scrollbartrack-horizontal scrollbartrack-vertical searchfield scrollbarthumb-vertical scrollbartrack-horizontal scrollbartrack-vertical scrollcorner
separator spinner spinner-downbutton spinner-textfield spinner-upbutton splitter statusbar searchfield separator
spinner spinner-downbutton spinner-textfield spinner-upbutton splitter statusbar
statusbarpanel tab tabpanel tabpanels tab-scroll-arrow-back tab-scroll-arrow-forward statusbarpanel tab tabpanel tabpanels tab-scroll-arrow-back tab-scroll-arrow-forward
textfield textfield-multiline toolbar toolbarbutton toolbarbutton-dropdown toolbargripper textfield textfield-multiline toolbar toolbarbutton toolbarbutton-dropdown toolbargripper
toolbox tooltip treeheader treeheadercell treeheadersortarrow treeitem treeline treetwisty toolbox tooltip treeheader treeheadercell treeheadersortarrow treeitem treeline treetwisty

View file

@ -97,29 +97,9 @@ macro_rules! expanded {
/// A module with all the code for longhand properties. /// A module with all the code for longhand properties.
#[allow(missing_docs)] #[allow(missing_docs)]
pub mod longhands { pub mod longhands {
<%include file="/longhand/background.mako.rs" /> % for style_struct in data.style_structs:
<%include file="/longhand/border.mako.rs" /> include!("${repr(os.path.join(OUT_DIR, 'longhands/{}.rs'.format(style_struct.name_lower)))[1:-1]}");
<%include file="/longhand/box.mako.rs" /> % endfor
<%include file="/longhand/color.mako.rs" />
<%include file="/longhand/column.mako.rs" />
<%include file="/longhand/counters.mako.rs" />
<%include file="/longhand/effects.mako.rs" />
<%include file="/longhand/font.mako.rs" />
<%include file="/longhand/inherited_box.mako.rs" />
<%include file="/longhand/inherited_table.mako.rs" />
<%include file="/longhand/inherited_text.mako.rs" />
<%include file="/longhand/inherited_ui.mako.rs" />
<%include file="/longhand/list.mako.rs" />
<%include file="/longhand/margin.mako.rs" />
<%include file="/longhand/outline.mako.rs" />
<%include file="/longhand/padding.mako.rs" />
<%include file="/longhand/position.mako.rs" />
<%include file="/longhand/table.mako.rs" />
<%include file="/longhand/text.mako.rs" />
<%include file="/longhand/ui.mako.rs" />
<%include file="/longhand/inherited_svg.mako.rs" />
<%include file="/longhand/svg.mako.rs" />
<%include file="/longhand/xul.mako.rs" />
} }
macro_rules! unwrap_or_initial { macro_rules! unwrap_or_initial {
@ -137,23 +117,37 @@ pub mod shorthands {
use style_traits::{ParseError, StyleParseErrorKind}; use style_traits::{ParseError, StyleParseErrorKind};
use values::specified; use values::specified;
<%include file="/shorthand/serialize.mako.rs" /> use style_traits::{CssWriter, ToCss};
<%include file="/shorthand/background.mako.rs" /> use values::specified::{BorderStyle, Color};
<%include file="/shorthand/border.mako.rs" /> use std::fmt::{self, Write};
<%include file="/shorthand/box.mako.rs" />
<%include file="/shorthand/column.mako.rs" />
<%include file="/shorthand/font.mako.rs" />
<%include file="/shorthand/inherited_text.mako.rs" />
<%include file="/shorthand/list.mako.rs" />
<%include file="/shorthand/margin.mako.rs" />
<%include file="/shorthand/mask.mako.rs" />
<%include file="/shorthand/outline.mako.rs" />
<%include file="/shorthand/padding.mako.rs" />
<%include file="/shorthand/position.mako.rs" />
<%include file="/shorthand/inherited_svg.mako.rs" />
<%include file="/shorthand/text.mako.rs" />
// We don't defined the 'all' shorthand using the regular helpers:shorthand fn serialize_directional_border<W, I,>(
dest: &mut CssWriter<W>,
width: &I,
style: &BorderStyle,
color: &Color,
) -> fmt::Result
where
W: Write,
I: ToCss,
{
width.to_css(dest)?;
// FIXME(emilio): Should we really serialize the border style if it's
// `solid`?
dest.write_str(" ")?;
style.to_css(dest)?;
if *color != Color::CurrentColor {
dest.write_str(" ")?;
color.to_css(dest)?;
}
Ok(())
}
% for style_struct in data.style_structs:
include!("${repr(os.path.join(OUT_DIR, 'shorthands/{}.rs'.format(style_struct.name_lower)))[1:-1]}");
% endfor
// We didn't define the 'all' shorthand using the regular helpers:shorthand
// mechanism, since it causes some very large types to be generated. // mechanism, since it causes some very large types to be generated.
// //
// Also, make sure logical properties appear before its physical // Also, make sure logical properties appear before its physical
@ -1448,6 +1442,7 @@ impl UnparsedValue {
None, None,
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
quirks_mode, quirks_mode,
None,
); );
let mut input = ParserInput::new(&css); let mut input = ParserInput::new(&css);
@ -3852,7 +3847,7 @@ where
} }
% if category_to_cascade_now == "early": % if category_to_cascade_now == "early":
let writing_mode = let writing_mode =
WritingMode::new(context.builder.get_inheritedbox()); WritingMode::new(context.builder.get_inherited_box());
context.builder.writing_mode = writing_mode; context.builder.writing_mode = writing_mode;
let mut _skip_font_family = false; let mut _skip_font_family = false;

View file

@ -1,27 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
use style_traits::{CssWriter, ToCss};
use values::specified::{BorderStyle, Color};
use std::fmt::{self, Write};
fn serialize_directional_border<W, I,>(
dest: &mut CssWriter<W>,
width: &I,
style: &BorderStyle,
color: &Color,
) -> fmt::Result
where
W: Write,
I: ToCss,
{
width.to_css(dest)?;
dest.write_str(" ")?;
style.to_css(dest)?;
if *color != Color::CurrentColor {
dest.write_str(" ")?;
color.to_css(dest)?;
}
Ok(())
}

View file

@ -24,7 +24,7 @@ use values::computed::font::FontSize;
/// is displayed in. /// is displayed in.
/// ///
/// This is the struct against which media queries are evaluated. /// This is the struct against which media queries are evaluated.
#[derive(MallocSizeOf)] #[derive(Debug, MallocSizeOf)]
pub struct Device { pub struct Device {
/// The current media type used by de device. /// The current media type used by de device.
media_type: MediaType, media_type: MediaType,

View file

@ -815,7 +815,11 @@ impl<E: TElement> StyleSharingCache<E> {
Some(candidate.element.borrow_data().unwrap().share_styles()) Some(candidate.element.borrow_data().unwrap().share_styles())
} }
/// Attempts to find an element in the cache with the given primary rule node and parent. /// Attempts to find an element in the cache with the given primary rule
/// node and parent.
///
/// FIXME(emilio): re-measure this optimization, and remove if it's not very
/// useful... It's probably not worth the complexity / obscure bugs.
pub fn lookup_by_rules( pub fn lookup_by_rules(
&mut self, &mut self,
shared_context: &SharedStyleContext, shared_context: &SharedStyleContext,
@ -841,7 +845,15 @@ impl<E: TElement> StyleSharingCache<E> {
if style.visited_rules() != visited_rules { if style.visited_rules() != visited_rules {
return None; return None;
} }
// NOTE(emilio): We only need to check name / namespace because we
// do name-dependent style adjustments, like the display: contents
// to display: none adjustment.
if target.namespace() != candidate.element.namespace() {
return None;
}
if target.local_name() != candidate.element.local_name() {
return None;
}
// Rule nodes and styles are computed independent of the element's // Rule nodes and styles are computed independent of the element's
// actual visitedness, but at the end of the cascade (in // actual visitedness, but at the end of the cascade (in
// `adjust_for_visited`) we do store the visitedness as a flag in // `adjust_for_visited`) we do store the visitedness as a flag in
@ -853,6 +865,7 @@ impl<E: TElement> StyleSharingCache<E> {
// FIXME(jryans): This seems like it breaks the constant time // FIXME(jryans): This seems like it breaks the constant time
// requirements of visited, assuming we get a cache hit on only one // requirements of visited, assuming we get a cache hit on only one
// of unvisited vs. visited. // of unvisited vs. visited.
// TODO(emilio): We no longer have such a flag, remove this check.
if target.is_visited_link() != candidate.element.is_visited_link() { if target.is_visited_link() != candidate.element.is_visited_link() {
return None; return None;
} }

View file

@ -19,6 +19,14 @@ use properties::longhands::position::computed_value::T as Position;
/// NOTE(emilio): If new adjustments are introduced that depend on reset /// NOTE(emilio): If new adjustments are introduced that depend on reset
/// properties of the parent, you may need tweaking the /// properties of the parent, you may need tweaking the
/// `ChildCascadeRequirement` code in `matching.rs`. /// `ChildCascadeRequirement` code in `matching.rs`.
///
/// NOTE(emilio): Also, if new adjustments are introduced that break the
/// following invariant:
///
/// Given same tag name, namespace, rules and parent style, two elements would
/// end up with exactly the same style.
///
/// Then you need to adjust the lookup_by_rules conditions in the sharing cache.
pub struct StyleAdjuster<'a, 'b: 'a> { pub struct StyleAdjuster<'a, 'b: 'a> {
style: &'a mut StyleBuilder<'b>, style: &'a mut StyleBuilder<'b>,
} }
@ -248,8 +256,8 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
use computed_values::text_combine_upright::T as TextCombineUpright; use computed_values::text_combine_upright::T as TextCombineUpright;
use computed_values::writing_mode::T as WritingMode; use computed_values::writing_mode::T as WritingMode;
let writing_mode = self.style.get_inheritedbox().clone_writing_mode(); let writing_mode = self.style.get_inherited_box().clone_writing_mode();
let text_combine_upright = self.style.get_inheritedtext().clone_text_combine_upright(); let text_combine_upright = self.style.get_inherited_text().clone_text_combine_upright();
if writing_mode != WritingMode::HorizontalTb && if writing_mode != WritingMode::HorizontalTb &&
text_combine_upright == TextCombineUpright::All text_combine_upright == TextCombineUpright::All
@ -258,7 +266,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
.flags .flags
.insert(ComputedValueFlags::IS_TEXT_COMBINED); .insert(ComputedValueFlags::IS_TEXT_COMBINED);
self.style self.style
.mutate_inheritedbox() .mutate_inherited_box()
.set_writing_mode(WritingMode::HorizontalTb); .set_writing_mode(WritingMode::HorizontalTb);
} }
} }
@ -297,8 +305,8 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
/// <https://lists.w3.org/Archives/Public/www-style/2017Mar/0045.html> /// <https://lists.w3.org/Archives/Public/www-style/2017Mar/0045.html>
/// <https://github.com/servo/servo/issues/15754> /// <https://github.com/servo/servo/issues/15754>
fn adjust_for_writing_mode(&mut self, layout_parent_style: &ComputedValues) { fn adjust_for_writing_mode(&mut self, layout_parent_style: &ComputedValues) {
let our_writing_mode = self.style.get_inheritedbox().clone_writing_mode(); let our_writing_mode = self.style.get_inherited_box().clone_writing_mode();
let parent_writing_mode = layout_parent_style.get_inheritedbox().clone_writing_mode(); let parent_writing_mode = layout_parent_style.get_inherited_box().clone_writing_mode();
if our_writing_mode != parent_writing_mode && if our_writing_mode != parent_writing_mode &&
self.style.get_box().clone_display() == Display::Inline self.style.get_box().clone_display() == Display::Inline
@ -488,13 +496,13 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
return; return;
} }
match self.style.get_inheritedtext().clone_text_align() { match self.style.get_inherited_text().clone_text_align() {
TextAlign::MozLeft | TextAlign::MozCenter | TextAlign::MozRight => {}, TextAlign::MozLeft | TextAlign::MozCenter | TextAlign::MozRight => {},
_ => return, _ => return,
} }
self.style self.style
.mutate_inheritedtext() .mutate_inherited_text()
.set_text_align(TextAlign::Start) .set_text_align(TextAlign::Start)
} }
@ -508,8 +516,8 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
use values::computed::text::TextDecorationsInEffect; use values::computed::text::TextDecorationsInEffect;
let decorations_in_effect = TextDecorationsInEffect::from_style(&self.style); let decorations_in_effect = TextDecorationsInEffect::from_style(&self.style);
if self.style.get_inheritedtext().text_decorations_in_effect != decorations_in_effect { if self.style.get_inherited_text().text_decorations_in_effect != decorations_in_effect {
self.style.mutate_inheritedtext().text_decorations_in_effect = decorations_in_effect; self.style.mutate_inherited_text().text_decorations_in_effect = decorations_in_effect;
} }
} }

View file

@ -10,12 +10,12 @@ use Atom;
use cssparser::{AtRuleParser, AtRuleType, BasicParseErrorKind, CowRcStr}; use cssparser::{AtRuleParser, AtRuleType, BasicParseErrorKind, CowRcStr};
use cssparser::{DeclarationListParser, DeclarationParser, Parser}; use cssparser::{DeclarationListParser, DeclarationParser, Parser};
use cssparser::{QualifiedRuleParser, RuleListParser, SourceLocation, Token}; use cssparser::{QualifiedRuleParser, RuleListParser, SourceLocation, Token};
use error_reporting::{ContextualParseError, ParseErrorReporter}; use error_reporting::ContextualParseError;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry; use gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray}; use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray};
use parser::{Parse, ParserContext, ParserErrorContext}; use parser::{Parse, ParserContext};
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt::{self, Write}; use std::fmt::{self, Write};
use str::CssStringWriter; use str::CssStringWriter;
@ -267,27 +267,24 @@ macro_rules! font_feature_values_blocks {
} }
/// Parses a `FontFeatureValuesRule`. /// Parses a `FontFeatureValuesRule`.
pub fn parse<R>(context: &ParserContext, pub fn parse(
error_context: &ParserErrorContext<R>, context: &ParserContext,
input: &mut Parser, input: &mut Parser,
family_names: Vec<FamilyName>, family_names: Vec<FamilyName>,
location: SourceLocation) location: SourceLocation,
-> FontFeatureValuesRule ) -> Self {
where R: ParseErrorReporter
{
let mut rule = FontFeatureValuesRule::new(family_names, location); let mut rule = FontFeatureValuesRule::new(family_names, location);
{ {
let mut iter = RuleListParser::new_for_nested_rule(input, FontFeatureValuesRuleParser { let mut iter = RuleListParser::new_for_nested_rule(input, FontFeatureValuesRuleParser {
context: context, context: context,
error_context: error_context,
rule: &mut rule, rule: &mut rule,
}); });
while let Some(result) = iter.next() { while let Some(result) = iter.next() {
if let Err((error, slice)) = result { if let Err((error, slice)) = result {
let location = error.location; let location = error.location;
let error = ContextualParseError::UnsupportedRule(slice, error); let error = ContextualParseError::UnsupportedRule(slice, error);
context.log_css_error(error_context, location, error); context.log_css_error(location, error);
} }
} }
} }
@ -398,20 +395,19 @@ macro_rules! font_feature_values_blocks {
/// } /// }
/// <feature-type> = @stylistic | @historical-forms | @styleset | /// <feature-type> = @stylistic | @historical-forms | @styleset |
/// @character-variant | @swash | @ornaments | @annotation /// @character-variant | @swash | @ornaments | @annotation
struct FontFeatureValuesRuleParser<'a, R: 'a> { struct FontFeatureValuesRuleParser<'a> {
context: &'a ParserContext<'a>, context: &'a ParserContext<'a>,
error_context: &'a ParserErrorContext<'a, R>,
rule: &'a mut FontFeatureValuesRule, rule: &'a mut FontFeatureValuesRule,
} }
/// Default methods reject all qualified rules. /// Default methods reject all qualified rules.
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> { impl<'a, 'i> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a> {
type Prelude = (); type Prelude = ();
type QualifiedRule = (); type QualifiedRule = ();
type Error = StyleParseErrorKind<'i>; type Error = StyleParseErrorKind<'i>;
} }
impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> { impl<'a, 'i> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a> {
type PreludeNoBlock = (); type PreludeNoBlock = ();
type PreludeBlock = BlockType; type PreludeBlock = BlockType;
type AtRule = (); type AtRule = ();
@ -450,7 +446,7 @@ macro_rules! font_feature_values_blocks {
let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration( let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(
slice, error slice, error
); );
self.context.log_css_error(self.error_context, location, error); self.context.log_css_error(location, error);
} }
} }
}, },

View file

@ -6,8 +6,8 @@
use cssparser::{AtRuleParser, CowRcStr, Parser, ParserInput, QualifiedRuleParser, RuleListParser}; use cssparser::{AtRuleParser, CowRcStr, Parser, ParserInput, QualifiedRuleParser, RuleListParser};
use cssparser::{parse_one_rule, DeclarationListParser, DeclarationParser, SourceLocation, Token}; use cssparser::{parse_one_rule, DeclarationListParser, DeclarationParser, SourceLocation, Token};
use error_reporting::{ContextualParseError, NullReporter, ParseErrorReporter}; use error_reporting::ContextualParseError;
use parser::{ParserContext, ParserErrorContext}; use parser::ParserContext;
use properties::{DeclarationSource, Importance, PropertyDeclaration}; use properties::{DeclarationSource, Importance, PropertyDeclaration};
use properties::{LonghandId, PropertyDeclarationBlock, PropertyId}; use properties::{LonghandId, PropertyDeclarationBlock, PropertyId};
use properties::{PropertyDeclarationId, SourcePropertyDeclaration}; use properties::{PropertyDeclarationId, SourcePropertyDeclaration};
@ -211,7 +211,6 @@ impl Keyframe {
lock: &SharedRwLock, lock: &SharedRwLock,
) -> Result<Arc<Locked<Self>>, ParseError<'i>> { ) -> Result<Arc<Locked<Self>>, ParseError<'i>> {
let url_data = parent_stylesheet_contents.url_data.read(); let url_data = parent_stylesheet_contents.url_data.read();
let error_reporter = NullReporter;
let namespaces = parent_stylesheet_contents.namespaces.read(); let namespaces = parent_stylesheet_contents.namespaces.read();
let mut context = ParserContext::new( let mut context = ParserContext::new(
parent_stylesheet_contents.origin, parent_stylesheet_contents.origin,
@ -219,10 +218,8 @@ impl Keyframe {
Some(CssRuleType::Keyframe), Some(CssRuleType::Keyframe),
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
parent_stylesheet_contents.quirks_mode, parent_stylesheet_contents.quirks_mode,
None,
); );
let error_context = ParserErrorContext {
error_reporter: &error_reporter,
};
context.namespaces = Some(&*namespaces); context.namespaces = Some(&*namespaces);
let mut input = ParserInput::new(css); let mut input = ParserInput::new(css);
let mut input = Parser::new(&mut input); let mut input = Parser::new(&mut input);
@ -230,7 +227,6 @@ impl Keyframe {
let mut declarations = SourcePropertyDeclaration::new(); let mut declarations = SourcePropertyDeclaration::new();
let mut rule_parser = KeyframeListParser { let mut rule_parser = KeyframeListParser {
context: &context, context: &context,
error_context: &error_context,
shared_lock: &lock, shared_lock: &lock,
declarations: &mut declarations, declarations: &mut declarations,
}; };
@ -477,23 +473,18 @@ impl KeyframesAnimation {
/// 40%, 60%, 100% { /// 40%, 60%, 100% {
/// width: 100%; /// width: 100%;
/// } /// }
struct KeyframeListParser<'a, R: 'a> { struct KeyframeListParser<'a> {
context: &'a ParserContext<'a>, context: &'a ParserContext<'a>,
error_context: &'a ParserErrorContext<'a, R>,
shared_lock: &'a SharedRwLock, shared_lock: &'a SharedRwLock,
declarations: &'a mut SourcePropertyDeclaration, declarations: &'a mut SourcePropertyDeclaration,
} }
/// Parses a keyframe list from CSS input. /// Parses a keyframe list from CSS input.
pub fn parse_keyframe_list<R>( pub fn parse_keyframe_list(
context: &ParserContext, context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser, input: &mut Parser,
shared_lock: &SharedRwLock, shared_lock: &SharedRwLock,
) -> Vec<Arc<Locked<Keyframe>>> ) -> Vec<Arc<Locked<Keyframe>>> {
where
R: ParseErrorReporter,
{
debug_assert!( debug_assert!(
context.namespaces.is_some(), context.namespaces.is_some(),
"Parsing a keyframe list from a context without namespaces?" "Parsing a keyframe list from a context without namespaces?"
@ -504,7 +495,6 @@ where
input, input,
KeyframeListParser { KeyframeListParser {
context: context, context: context,
error_context: error_context,
shared_lock: shared_lock, shared_lock: shared_lock,
declarations: &mut declarations, declarations: &mut declarations,
}, },
@ -512,7 +502,7 @@ where
.collect() .collect()
} }
impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> { impl<'a, 'i> AtRuleParser<'i> for KeyframeListParser<'a> {
type PreludeNoBlock = (); type PreludeNoBlock = ();
type PreludeBlock = (); type PreludeBlock = ();
type AtRule = Arc<Locked<Keyframe>>; type AtRule = Arc<Locked<Keyframe>>;
@ -525,7 +515,7 @@ struct KeyframeSelectorParserPrelude {
source_location: SourceLocation, source_location: SourceLocation,
} }
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> { impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> {
type Prelude = KeyframeSelectorParserPrelude; type Prelude = KeyframeSelectorParserPrelude;
type QualifiedRule = Arc<Locked<Keyframe>>; type QualifiedRule = Arc<Locked<Keyframe>>;
type Error = StyleParseErrorKind<'i>; type Error = StyleParseErrorKind<'i>;
@ -547,8 +537,7 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
input.slice_from(start_position), input.slice_from(start_position),
e.clone(), e.clone(),
); );
self.context self.context.log_css_error(location, error);
.log_css_error(self.error_context, location, error);
Err(e) Err(e)
}, },
} }
@ -585,7 +574,7 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars
let location = error.location; let location = error.location;
let error = let error =
ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error); ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error);
context.log_css_error(self.error_context, location, error); context.log_css_error(location, error);
}, },
} }
// `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.

View file

@ -24,10 +24,9 @@ pub mod supports_rule;
pub mod viewport_rule; pub mod viewport_rule;
use cssparser::{parse_one_rule, Parser, ParserInput}; use cssparser::{parse_one_rule, Parser, ParserInput};
use error_reporting::NullReporter;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use parser::{ParserContext, ParserErrorContext}; use parser::ParserContext;
use servo_arc::Arc; use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
use shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
@ -62,22 +61,52 @@ pub type UrlExtraData = ::servo_url::ServoUrl;
/// Extra data that the backend may need to resolve url values. /// Extra data that the backend may need to resolve url values.
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub type UrlExtraData = #[derive(Clone, PartialEq)]
::gecko_bindings::sugar::refptr::RefPtr<::gecko_bindings::structs::URLExtraData>; pub struct UrlExtraData(
pub ::gecko_bindings::sugar::refptr::RefPtr<::gecko_bindings::structs::URLExtraData>
);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
impl UrlExtraData { impl UrlExtraData {
/// Returns a string for the url. /// True if this URL scheme is chrome.
/// #[inline]
/// Unimplemented currently. pub fn is_chrome(&self) -> bool {
pub fn as_str(&self) -> &str { self.0.mIsChrome
// TODO
"(stylo: not supported)"
} }
/// True if this URL scheme is chrome. /// Create a reference to this `UrlExtraData` from a reference to pointer.
pub fn is_chrome(&self) -> bool { ///
self.mIsChrome /// The pointer must be valid and non null.
///
/// This method doesn't touch refcount.
#[inline]
pub unsafe fn from_ptr_ref(ptr: &*mut ::gecko_bindings::structs::URLExtraData) -> &Self {
::std::mem::transmute(ptr)
}
}
#[cfg(feature = "gecko")]
impl fmt::Debug for UrlExtraData {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
use gecko_bindings::{structs, bindings};
struct DebugURI(*mut structs::nsIURI);
impl fmt::Debug for DebugURI {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
use nsstring::nsCString;
let mut spec = nsCString::new();
unsafe {
bindings::Gecko_nsIURI_Debug(self.0, &mut spec);
}
spec.fmt(formatter)
}
}
formatter.debug_struct("URLExtraData")
.field("is_chrome", &self.is_chrome())
.field("base", &DebugURI(self.0.mBaseURI.raw::<structs::nsIURI>()))
.field("referrer", &DebugURI(self.0.mReferrer.raw::<structs::nsIURI>()))
.finish()
} }
} }
@ -228,13 +257,13 @@ impl CssRule {
loader: Option<&StylesheetLoader>, loader: Option<&StylesheetLoader>,
) -> Result<Self, RulesMutateError> { ) -> Result<Self, RulesMutateError> {
let url_data = parent_stylesheet_contents.url_data.read(); let url_data = parent_stylesheet_contents.url_data.read();
let error_reporter = NullReporter;
let context = ParserContext::new( let context = ParserContext::new(
parent_stylesheet_contents.origin, parent_stylesheet_contents.origin,
&url_data, &url_data,
None, None,
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
parent_stylesheet_contents.quirks_mode, parent_stylesheet_contents.quirks_mode,
None,
); );
let mut input = ParserInput::new(css); let mut input = ParserInput::new(css);
@ -246,9 +275,6 @@ impl CssRule {
let mut rule_parser = TopLevelRuleParser { let mut rule_parser = TopLevelRuleParser {
stylesheet_origin: parent_stylesheet_contents.origin, stylesheet_origin: parent_stylesheet_contents.origin,
context, context,
error_context: ParserErrorContext {
error_reporter: &error_reporter,
},
shared_lock: &shared_lock, shared_lock: &shared_lock,
loader, loader,
state, state,

View file

@ -8,10 +8,10 @@ use {Namespace, Prefix};
use counter_style::{parse_counter_style_body, parse_counter_style_name_definition}; use counter_style::{parse_counter_style_body, parse_counter_style_name_definition};
use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser}; use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser};
use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, SourceLocation}; use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, SourceLocation};
use error_reporting::{ContextualParseError, ParseErrorReporter}; use error_reporting::ContextualParseError;
use font_face::parse_font_face_block; use font_face::parse_font_face_block;
use media_queries::MediaList; use media_queries::MediaList;
use parser::{Parse, ParserContext, ParserErrorContext}; use parser::{Parse, ParserContext};
use properties::parse_property_declaration_list; use properties::parse_property_declaration_list;
use selector_parser::{SelectorImpl, SelectorParser}; use selector_parser::{SelectorImpl, SelectorParser};
use selectors::SelectorList; use selectors::SelectorList;
@ -40,7 +40,7 @@ pub struct InsertRuleContext<'a> {
} }
/// The parser for the top-level rules in a stylesheet. /// The parser for the top-level rules in a stylesheet.
pub struct TopLevelRuleParser<'a, R: 'a> { pub struct TopLevelRuleParser<'a> {
/// The origin of the stylesheet we're parsing. /// The origin of the stylesheet we're parsing.
pub stylesheet_origin: Origin, pub stylesheet_origin: Origin,
/// A reference to the lock we need to use to create rules. /// A reference to the lock we need to use to create rules.
@ -52,8 +52,6 @@ pub struct TopLevelRuleParser<'a, R: 'a> {
/// This won't contain any namespaces, and only nested parsers created with /// This won't contain any namespaces, and only nested parsers created with
/// `ParserContext::new_with_rule_type` will. /// `ParserContext::new_with_rule_type` will.
pub context: ParserContext<'a>, pub context: ParserContext<'a>,
/// The context required for reporting parse errors.
pub error_context: ParserErrorContext<'a, R>,
/// The current state of the parser. /// The current state of the parser.
pub state: State, pub state: State,
/// Whether we have tried to parse was invalid due to being in the wrong /// Whether we have tried to parse was invalid due to being in the wrong
@ -68,13 +66,12 @@ pub struct TopLevelRuleParser<'a, R: 'a> {
pub insert_rule_context: Option<InsertRuleContext<'a>>, pub insert_rule_context: Option<InsertRuleContext<'a>>,
} }
impl<'b, R> TopLevelRuleParser<'b, R> { impl<'b> TopLevelRuleParser<'b> {
fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b, R> { fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b> {
NestedRuleParser { NestedRuleParser {
stylesheet_origin: self.stylesheet_origin, stylesheet_origin: self.stylesheet_origin,
shared_lock: self.shared_lock, shared_lock: self.shared_lock,
context: &self.context, context: &self.context,
error_context: &self.error_context,
namespaces: &self.namespaces, namespaces: &self.namespaces,
} }
} }
@ -176,7 +173,7 @@ pub enum AtRuleNonBlockPrelude {
Namespace(Option<Prefix>, Namespace, SourceLocation), Namespace(Option<Prefix>, Namespace, SourceLocation),
} }
impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, R> { impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
type PreludeNoBlock = AtRuleNonBlockPrelude; type PreludeNoBlock = AtRuleNonBlockPrelude;
type PreludeBlock = AtRuleBlockPrelude; type PreludeBlock = AtRuleBlockPrelude;
type AtRule = CssRule; type AtRule = CssRule;
@ -197,11 +194,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a,
let url_string = input.expect_url_or_string()?.as_ref().to_owned(); let url_string = input.expect_url_or_string()?.as_ref().to_owned();
let url = CssUrl::parse_from_string(url_string, &self.context); let url = CssUrl::parse_from_string(url_string, &self.context);
let media = MediaList::parse( let media = MediaList::parse(&self.context, input);
&self.context,
input,
self.error_context.error_reporter,
);
let media = Arc::new(self.shared_lock.wrap(media)); let media = Arc::new(self.shared_lock.wrap(media));
let prelude = AtRuleNonBlockPrelude::Import(url, media, location); let prelude = AtRuleNonBlockPrelude::Import(url, media, location);
@ -296,7 +289,7 @@ pub struct QualifiedRuleParserPrelude {
source_location: SourceLocation, source_location: SourceLocation,
} }
impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRuleParser<'a, R> { impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> {
type Prelude = QualifiedRuleParserPrelude; type Prelude = QualifiedRuleParserPrelude;
type QualifiedRule = CssRule; type QualifiedRule = CssRule;
type Error = StyleParseErrorKind<'i>; type Error = StyleParseErrorKind<'i>;
@ -327,27 +320,29 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRulePars
} }
#[derive(Clone)] // shallow, relatively cheap .clone #[derive(Clone)] // shallow, relatively cheap .clone
struct NestedRuleParser<'a, 'b: 'a, R: 'b> { struct NestedRuleParser<'a, 'b: 'a> {
stylesheet_origin: Origin, stylesheet_origin: Origin,
shared_lock: &'a SharedRwLock, shared_lock: &'a SharedRwLock,
context: &'a ParserContext<'b>, context: &'a ParserContext<'b>,
error_context: &'a ParserErrorContext<'b, R>,
namespaces: &'a Namespaces, namespaces: &'a Namespaces,
} }
impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> { impl<'a, 'b> NestedRuleParser<'a, 'b> {
fn parse_nested_rules( fn parse_nested_rules(
&mut self, &mut self,
input: &mut Parser, input: &mut Parser,
rule_type: CssRuleType, rule_type: CssRuleType,
) -> Arc<Locked<CssRules>> { ) -> Arc<Locked<CssRules>> {
let context = ParserContext::new_with_rule_type(self.context, rule_type, self.namespaces); let context = ParserContext::new_with_rule_type(
self.context,
rule_type,
self.namespaces,
);
let nested_parser = NestedRuleParser { let nested_parser = NestedRuleParser {
stylesheet_origin: self.stylesheet_origin, stylesheet_origin: self.stylesheet_origin,
shared_lock: self.shared_lock, shared_lock: self.shared_lock,
context: &context, context: &context,
error_context: &self.error_context,
namespaces: self.namespaces, namespaces: self.namespaces,
}; };
@ -359,8 +354,7 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
Err((error, slice)) => { Err((error, slice)) => {
let location = error.location; let location = error.location;
let error = ContextualParseError::InvalidRule(slice, error); let error = ContextualParseError::InvalidRule(slice, error);
self.context self.context.log_css_error(location, error);
.log_css_error(self.error_context, location, error);
}, },
} }
} }
@ -368,7 +362,7 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
} }
} }
impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a, 'b, R> { impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
type PreludeNoBlock = AtRuleNonBlockPrelude; type PreludeNoBlock = AtRuleNonBlockPrelude;
type PreludeBlock = AtRuleBlockPrelude; type PreludeBlock = AtRuleBlockPrelude;
type AtRule = CssRule; type AtRule = CssRule;
@ -383,11 +377,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
match_ignore_ascii_case! { &*name, match_ignore_ascii_case! { &*name,
"media" => { "media" => {
let media_queries = MediaList::parse( let media_queries = MediaList::parse(self.context, input);
self.context,
input,
self.error_context.error_reporter,
);
let arc = Arc::new(self.shared_lock.wrap(media_queries)); let arc = Arc::new(self.shared_lock.wrap(media_queries));
Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Media(arc, location))) Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Media(arc, location)))
}, },
@ -473,7 +463,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
); );
Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap( Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap(
parse_font_face_block(&context, self.error_context, input, location).into(), parse_font_face_block(&context, input, location).into(),
)))) ))))
}, },
AtRuleBlockPrelude::FontFeatureValues(family_names, location) => { AtRuleBlockPrelude::FontFeatureValues(family_names, location) => {
@ -486,7 +476,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap( Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap(
FontFeatureValuesRule::parse( FontFeatureValuesRule::parse(
&context, &context,
self.error_context,
input, input,
family_names, family_names,
location, location,
@ -505,7 +494,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
parse_counter_style_body( parse_counter_style_body(
name, name,
&context, &context,
self.error_context,
input, input,
location, location,
)?.into(), )?.into(),
@ -544,7 +532,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
); );
Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap( Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap(
ViewportRule::parse(&context, self.error_context, input)?, ViewportRule::parse(&context, input)?,
)))) ))))
}, },
AtRuleBlockPrelude::Keyframes(name, vendor_prefix, source_location) => { AtRuleBlockPrelude::Keyframes(name, vendor_prefix, source_location) => {
@ -559,7 +547,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
name, name,
keyframes: parse_keyframe_list( keyframes: parse_keyframe_list(
&context, &context,
self.error_context,
input, input,
self.shared_lock, self.shared_lock,
), ),
@ -576,7 +563,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
); );
let declarations = let declarations =
parse_property_declaration_list(&context, self.error_context, input); 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 {
block: Arc::new(self.shared_lock.wrap(declarations)), block: Arc::new(self.shared_lock.wrap(declarations)),
source_location, source_location,
@ -598,7 +585,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
} }
} }
impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b, R> { impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> {
type Prelude = QualifiedRuleParserPrelude; type Prelude = QualifiedRuleParserPrelude;
type QualifiedRule = CssRule; type QualifiedRule = CssRule;
type Error = StyleParseErrorKind<'i>; type Error = StyleParseErrorKind<'i>;
@ -627,7 +614,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRulePa
let context = let context =
ParserContext::new_with_rule_type(self.context, CssRuleType::Style, self.namespaces); ParserContext::new_with_rule_type(self.context, CssRuleType::Style, self.namespaces);
let declarations = parse_property_declaration_list(&context, self.error_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, selectors: prelude.selectors,
block: Arc::new(self.shared_lock.wrap(declarations)), block: Arc::new(self.shared_lock.wrap(declarations)),

View file

@ -13,7 +13,7 @@ use invalidation::media_queries::{MediaListKey, ToMediaListKey};
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use media_queries::{Device, MediaList}; use media_queries::{Device, MediaList};
use parking_lot::RwLock; use parking_lot::RwLock;
use parser::{ParserContext, ParserErrorContext}; use parser::ParserContext;
use servo_arc::Arc; use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard}; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard};
use std::mem; use std::mem;
@ -69,13 +69,13 @@ pub struct StylesheetContents {
impl StylesheetContents { impl StylesheetContents {
/// Parse a given CSS string, with a given url-data, origin, and /// Parse a given CSS string, with a given url-data, origin, and
/// quirks mode. /// quirks mode.
pub fn from_str<R: ParseErrorReporter>( pub fn from_str(
css: &str, css: &str,
url_data: UrlExtraData, url_data: UrlExtraData,
origin: Origin, origin: Origin,
shared_lock: &SharedRwLock, shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R, error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
line_number_offset: u32, line_number_offset: u32,
) -> Self { ) -> Self {
@ -137,7 +137,7 @@ impl DeepCloneWithLock for StylesheetContents {
url_data: RwLock::new((*self.url_data.read()).clone()), url_data: RwLock::new((*self.url_data.read()).clone()),
namespaces: RwLock::new((*self.namespaces.read()).clone()), namespaces: RwLock::new((*self.namespaces.read()).clone()),
source_map_url: RwLock::new((*self.source_map_url.read()).clone()), source_map_url: RwLock::new((*self.source_map_url.read()).clone()),
source_url: RwLock::new((*self.source_map_url.read()).clone()), source_url: RwLock::new((*self.source_url.read()).clone()),
} }
} }
} }
@ -176,7 +176,7 @@ macro_rules! rule_filter {
} }
/// A trait to represent a given stylesheet in a document. /// A trait to represent a given stylesheet in a document.
pub trait StylesheetInDocument { pub trait StylesheetInDocument : ::std::fmt::Debug {
/// Get the stylesheet origin. /// Get the stylesheet origin.
fn origin(&self, guard: &SharedRwLockReadGuard) -> Origin; fn origin(&self, guard: &SharedRwLockReadGuard) -> Origin;
@ -263,7 +263,7 @@ impl StylesheetInDocument for Stylesheet {
/// A simple wrapper over an `Arc<Stylesheet>`, with pointer comparison, and /// A simple wrapper over an `Arc<Stylesheet>`, with pointer comparison, and
/// suitable for its use in a `StylesheetSet`. /// suitable for its use in a `StylesheetSet`.
#[derive(Clone)] #[derive(Clone, Debug)]
#[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[cfg_attr(feature = "servo", derive(MallocSizeOf))]
pub struct DocumentStyleSheet( pub struct DocumentStyleSheet(
#[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] pub Arc<Stylesheet>, #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] pub Arc<Stylesheet>,
@ -306,18 +306,16 @@ impl StylesheetInDocument for DocumentStyleSheet {
impl Stylesheet { impl Stylesheet {
/// Updates an empty stylesheet from a given string of text. /// Updates an empty stylesheet from a given string of text.
pub fn update_from_str<R>( pub fn update_from_str(
existing: &Stylesheet, existing: &Stylesheet,
css: &str, css: &str,
url_data: UrlExtraData, url_data: UrlExtraData,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R, error_reporter: Option<&ParseErrorReporter>,
line_number_offset: u32, line_number_offset: u32,
) where ) {
R: ParseErrorReporter,
{
let namespaces = RwLock::new(Namespaces::default()); let namespaces = RwLock::new(Namespaces::default());
let (rules, source_map_url, source_url) = Stylesheet::parse_rules( let (rules, source_map_url, source_url) = Self::parse_rules(
css, css,
&url_data, &url_data,
existing.contents.origin, existing.contents.origin,
@ -342,14 +340,14 @@ impl Stylesheet {
*existing.contents.source_url.write() = source_url; *existing.contents.source_url.write() = source_url;
} }
fn parse_rules<R: ParseErrorReporter>( fn parse_rules(
css: &str, css: &str,
url_data: &UrlExtraData, url_data: &UrlExtraData,
origin: Origin, origin: Origin,
namespaces: &mut Namespaces, namespaces: &mut Namespaces,
shared_lock: &SharedRwLock, shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R, error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
line_number_offset: u32, line_number_offset: u32,
) -> (Vec<CssRule>, Option<String>, Option<String>) { ) -> (Vec<CssRule>, Option<String>, Option<String>) {
@ -357,16 +355,20 @@ impl Stylesheet {
let mut input = ParserInput::new_with_line_number_offset(css, line_number_offset); let mut input = ParserInput::new_with_line_number_offset(css, line_number_offset);
let mut input = Parser::new(&mut input); let mut input = Parser::new(&mut input);
let context = ParserContext::new(origin, url_data, None, ParsingMode::DEFAULT, quirks_mode); let context = ParserContext::new(
origin,
let error_context = ParserErrorContext { error_reporter }; url_data,
None,
ParsingMode::DEFAULT,
quirks_mode,
error_reporter,
);
let rule_parser = TopLevelRuleParser { let rule_parser = TopLevelRuleParser {
stylesheet_origin: origin, stylesheet_origin: origin,
shared_lock, shared_lock,
loader: stylesheet_loader, loader: stylesheet_loader,
context, context,
error_context,
state: State::Start, state: State::Start,
dom_error: None, dom_error: None,
insert_rule_context: None, insert_rule_context: None,
@ -390,7 +392,6 @@ impl Stylesheet {
let location = error.location; let location = error.location;
let error = ContextualParseError::InvalidRule(slice, error); let error = ContextualParseError::InvalidRule(slice, error);
iter.parser.context.log_css_error( iter.parser.context.log_css_error(
&iter.parser.error_context,
location, location,
error, error,
); );
@ -409,17 +410,17 @@ impl Stylesheet {
/// ///
/// Effectively creates a new stylesheet and forwards the hard work to /// Effectively creates a new stylesheet and forwards the hard work to
/// `Stylesheet::update_from_str`. /// `Stylesheet::update_from_str`.
pub fn from_str<R: ParseErrorReporter>( pub fn from_str(
css: &str, css: &str,
url_data: UrlExtraData, url_data: UrlExtraData,
origin: Origin, origin: Origin,
media: Arc<Locked<MediaList>>, media: Arc<Locked<MediaList>>,
shared_lock: SharedRwLock, shared_lock: SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &R, error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode, quirks_mode: QuirksMode,
line_number_offset: u32, line_number_offset: u32,
) -> Stylesheet { ) -> Self {
let contents = StylesheetContents::from_str( let contents = StylesheetContents::from_str(
css, css,
url_data, url_data,

View file

@ -11,11 +11,11 @@ use app_units::Au;
use context::QuirksMode; use context::QuirksMode;
use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser};
use cssparser::CowRcStr; use cssparser::CowRcStr;
use error_reporting::{ContextualParseError, ParseErrorReporter}; use error_reporting::ContextualParseError;
use euclid::TypedSize2D; use euclid::TypedSize2D;
use font_metrics::get_metrics_provider_for_product; use font_metrics::get_metrics_provider_for_product;
use media_queries::Device; use media_queries::Device;
use parser::{ParserContext, ParserErrorContext}; use parser::ParserContext;
use properties::StyleBuilder; use properties::StyleBuilder;
use rule_cache::RuleCacheConditions; use rule_cache::RuleCacheConditions;
use selectors::parser::SelectorParseErrorKind; use selectors::parser::SelectorParseErrorKind;
@ -355,15 +355,13 @@ fn is_whitespace_separator_or_equals(c: &char) -> bool {
impl ViewportRule { impl ViewportRule {
/// Parse a single @viewport rule. /// Parse a single @viewport rule.
pub fn parse<'i, 't, R>( ///
/// TODO(emilio): This could use the `Parse` trait now.
pub fn parse<'i, 't>(
context: &ParserContext, context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser<'i, 't>, input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> ) -> Result<Self, ParseError<'i>> {
where let parser = ViewportRuleParser { context };
R: ParseErrorReporter,
{
let parser = ViewportRuleParser { context: context };
let mut cascade = Cascade::new(); let mut cascade = Cascade::new();
let mut parser = DeclarationListParser::new(input, parser); let mut parser = DeclarationListParser::new(input, parser);
@ -380,7 +378,7 @@ impl ViewportRule {
slice, slice,
error, error,
); );
context.log_css_error(error_context, location, error); context.log_css_error(location, error);
}, },
} }
} }

View file

@ -75,6 +75,10 @@ impl UserAgentCascadeDataCache {
Self { entries: vec![] } Self { entries: vec![] }
} }
fn len(&self) -> usize {
self.entries.len()
}
// FIXME(emilio): This may need to be keyed on quirks-mode too, though there // FIXME(emilio): This may need to be keyed on quirks-mode too, though there
// aren't class / id selectors on those sheets, usually, so it's probably // aren't class / id selectors on those sheets, usually, so it's probably
// ok... // ok...
@ -90,6 +94,7 @@ impl UserAgentCascadeDataCache {
S: StylesheetInDocument + ToMediaListKey + PartialEq + 'static, S: StylesheetInDocument + ToMediaListKey + PartialEq + 'static,
{ {
let mut key = EffectiveMediaQueryResults::new(); let mut key = EffectiveMediaQueryResults::new();
debug!("UserAgentCascadeDataCache::lookup({:?})", device);
for sheet in sheets.clone() { for sheet in sheets.clone() {
CascadeData::collect_applicable_media_query_results_into(device, sheet, guard, &mut key) CascadeData::collect_applicable_media_query_results_into(device, sheet, guard, &mut key)
} }
@ -105,6 +110,8 @@ impl UserAgentCascadeDataCache {
precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations::default(), precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations::default(),
}; };
debug!("> Picking the slow path");
for sheet in sheets { for sheet in sheets {
new_data.cascade_data.add_stylesheet( new_data.cascade_data.add_stylesheet(
device, device,
@ -117,7 +124,6 @@ impl UserAgentCascadeDataCache {
} }
let new_data = Arc::new(new_data); let new_data = Arc::new(new_data);
self.entries.push(new_data.clone()); self.entries.push(new_data.clone());
Ok(new_data) Ok(new_data)
} }
@ -244,8 +250,8 @@ impl DocumentCascadeData {
let origin_sheets = flusher.origin_sheets(Origin::UserAgent); let origin_sheets = flusher.origin_sheets(Origin::UserAgent);
let ua_cascade_data = let ua_cascade_data =
ua_cache.lookup(origin_sheets, device, quirks_mode, guards.ua_or_user)?; ua_cache.lookup(origin_sheets, device, quirks_mode, guards.ua_or_user)?;
ua_cache.expire_unused(); ua_cache.expire_unused();
debug!("User agent data cache size {:?}", ua_cache.len());
self.user_agent = ua_cascade_data; self.user_agent = ua_cascade_data;
} }
} }
@ -1085,7 +1091,7 @@ impl Stylist {
guards: &StylesheetGuards, guards: &StylesheetGuards,
device: &Device, device: &Device,
) -> OriginSet { ) -> OriginSet {
debug!("Stylist::media_features_change_changed_style"); debug!("Stylist::media_features_change_changed_style {:?}", device);
let mut origins = OriginSet::empty(); let mut origins = OriginSet::empty();
let stylesheets = self.stylesheets.iter(); let stylesheets = self.stylesheets.iter();
@ -2145,16 +2151,19 @@ impl CascadeData {
return; return;
} }
debug!(" + {:?}", stylesheet);
results.saw_effective(stylesheet); results.saw_effective(stylesheet);
for rule in stylesheet.effective_rules(device, guard) { for rule in stylesheet.effective_rules(device, guard) {
match *rule { match *rule {
CssRule::Import(ref lock) => { CssRule::Import(ref lock) => {
let import_rule = lock.read_with(guard); let import_rule = lock.read_with(guard);
debug!(" + {:?}", import_rule.stylesheet.media(guard));
results.saw_effective(import_rule); results.saw_effective(import_rule);
}, },
CssRule::Media(ref lock) => { CssRule::Media(ref lock) => {
let media_rule = lock.read_with(guard); let media_rule = lock.read_with(guard);
debug!(" + {:?}", media_rule.media_queries.read_with(guard));
results.saw_effective(media_rule); results.saw_effective(media_rule);
}, },
_ => {}, _ => {},
@ -2346,8 +2355,10 @@ impl CascadeData {
if effective_now != effective_then { if effective_now != effective_then {
debug!( debug!(
" > Stylesheet changed -> {}, {}", " > Stylesheet {:?} changed -> {}, {}",
effective_then, effective_now stylesheet.media(guard),
effective_then,
effective_now
); );
return false; return false;
} }
@ -2382,8 +2393,10 @@ impl CascadeData {
.was_effective(import_rule); .was_effective(import_rule);
if effective_now != effective_then { if effective_now != effective_then {
debug!( debug!(
" > @import rule changed {} -> {}", " > @import rule {:?} changed {} -> {}",
effective_then, effective_now import_rule.stylesheet.media(guard),
effective_then,
effective_now
); );
return false; return false;
} }
@ -2401,8 +2414,10 @@ impl CascadeData {
if effective_now != effective_then { if effective_now != effective_then {
debug!( debug!(
" > @media rule changed {} -> {}", " > @media rule {:?} changed {} -> {}",
effective_then, effective_now mq,
effective_then,
effective_now
); );
return false; return false;
} }

View file

@ -107,7 +107,7 @@ impl TextDecorationsInEffect {
let mut result = match style.get_box().clone_display() { let mut result = match style.get_box().clone_display() {
Display::InlineBlock | Display::InlineTable => Self::default(), Display::InlineBlock | Display::InlineTable => Self::default(),
_ => style _ => style
.get_parent_inheritedtext() .get_parent_inherited_text()
.text_decorations_in_effect .text_decorations_in_effect
.clone(), .clone(),
}; };

View file

@ -514,7 +514,7 @@ impl ToComputedValue for TextAlign {
} }
let parent = _context let parent = _context
.builder .builder
.get_parent_inheritedtext() .get_parent_inherited_text()
.clone_text_align(); .clone_text_align();
let ltr = _context.builder.inherited_writing_mode().is_bidi_ltr(); let ltr = _context.builder.inherited_writing_mode().is_bidi_ltr();
match (parent, ltr) { match (parent, ltr) {
@ -529,7 +529,7 @@ impl ToComputedValue for TextAlign {
TextAlign::MozCenterOrInherit => { TextAlign::MozCenterOrInherit => {
let parent = _context let parent = _context
.builder .builder
.get_parent_inheritedtext() .get_parent_inherited_text()
.clone_text_align(); .clone_text_align();
if parent == TextAlignKeyword::Start { if parent == TextAlignKeyword::Start {
TextAlignKeyword::Center TextAlignKeyword::Center
@ -653,7 +653,7 @@ impl ToComputedValue for TextEmphasisStyle {
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self { match *self {
TextEmphasisStyle::Keyword(ref keyword) => { TextEmphasisStyle::Keyword(ref keyword) => {
let default_shape = if context.style().get_inheritedbox().clone_writing_mode() == let default_shape = if context.style().get_inherited_box().clone_writing_mode() ==
SpecifiedWritingMode::HorizontalTb SpecifiedWritingMode::HorizontalTb
{ {
TextEmphasisShapeKeyword::Circle TextEmphasisShapeKeyword::Circle

View file

@ -231,6 +231,8 @@ pub struct CssInputAttrs {
#[derive(Default, FromVariant)] #[derive(Default, FromVariant)]
pub struct CssVariantAttrs { pub struct CssVariantAttrs {
pub function: Option<Override<String>>, pub function: Option<Override<String>>,
// Here because structs variants are also their whole type definition.
pub derive_debug: bool,
pub comma: bool, pub comma: bool,
pub dimension: bool, pub dimension: bool,
pub keyword: Option<String>, pub keyword: Option<String>,

View file

@ -45,7 +45,7 @@ mod writing_modes {
#[test] #[test]
fn initial_writing_mode_is_empty() { fn initial_writing_mode_is_empty() {
assert_eq!( assert_eq!(
WritingMode::new(INITIAL_SERVO_VALUES.get_inheritedbox()), WritingMode::new(INITIAL_SERVO_VALUES.get_inherited_box()),
WritingMode::empty(), WritingMode::empty(),
) )
} }

View file

@ -2,7 +2,6 @@
* 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 euclid::TypedScale; use euclid::TypedScale;
use euclid::TypedSize2D; use euclid::TypedSize2D;
use servo_arc::Arc; use servo_arc::Arc;
@ -10,7 +9,6 @@ use servo_url::ServoUrl;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use style::Atom; use style::Atom;
use style::context::QuirksMode; use style::context::QuirksMode;
use style::error_reporting::{ParseErrorReporter, ContextualParseError};
use style::media_queries::*; use style::media_queries::*;
use style::servo::media_queries::*; use style::servo::media_queries::*;
use style::shared_lock::SharedRwLock; use style::shared_lock::SharedRwLock;
@ -18,18 +16,9 @@ use style::stylesheets::{AllRules, Stylesheet, StylesheetInDocument, Origin, Css
use style::values::{CustomIdent, specified}; use style::values::{CustomIdent, specified};
use style_traits::ToCss; use style_traits::ToCss;
pub struct CSSErrorReporterTest;
impl ParseErrorReporter for CSSErrorReporterTest {
fn report_error(&self,
_url: &ServoUrl,
_location: SourceLocation,
_error: ContextualParseError) {
}
}
fn test_media_rule<F>(css: &str, callback: F) fn test_media_rule<F>(css: &str, callback: F)
where F: Fn(&MediaList, &str), where
F: Fn(&MediaList, &str),
{ {
let url = ServoUrl::parse("http://localhost").unwrap(); let url = ServoUrl::parse("http://localhost").unwrap();
let css_str = css.to_owned(); let css_str = css.to_owned();
@ -37,7 +26,7 @@ fn test_media_rule<F>(css: &str, callback: F)
let media_list = Arc::new(lock.wrap(MediaList::empty())); let media_list = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str( let stylesheet = Stylesheet::from_str(
css, url, Origin::Author, media_list, lock, css, url, Origin::Author, media_list, lock,
None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0); None, None, QuirksMode::NoQuirks, 0);
let dummy = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), TypedScale::new(1.0)); let dummy = Device::new(MediaType::screen(), TypedSize2D::new(200.0, 100.0), TypedScale::new(1.0));
let mut rule_count = 0; let mut rule_count = 0;
let guard = stylesheet.shared_lock.read(); let guard = stylesheet.shared_lock.read();
@ -56,7 +45,7 @@ fn media_query_test(device: &Device, css: &str, expected_rule_count: usize) {
let media_list = Arc::new(lock.wrap(MediaList::empty())); let media_list = Arc::new(lock.wrap(MediaList::empty()));
let ss = Stylesheet::from_str( let ss = Stylesheet::from_str(
css, url, Origin::Author, media_list, lock, css, url, Origin::Author, media_list, lock,
None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0); None, None, QuirksMode::NoQuirks, 0);
let mut rule_count = 0; let mut rule_count = 0;
ss.effective_style_rules(device, &ss.shared_lock.read(), |_| rule_count += 1); ss.effective_style_rules(device, &ss.shared_lock.read(), |_| rule_count += 1);
assert!(rule_count == expected_rule_count, css.to_owned()); assert!(rule_count == expected_rule_count, css.to_owned());

View file

@ -1,49 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
use cssparser::{Parser, ParserInput};
use parsing::parse;
use style::context::QuirksMode;
use style::parser::{Parse, ParserContext};
use style::stylesheets::{CssRuleType, Origin};
use style::values::specified::length::{AbsoluteLength, Length, NoCalcLength};
use style_traits::{ParsingMode, ToCss};
#[test]
fn test_calc() {
assert!(parse(Length::parse, "calc(1px+ 2px)").is_err());
assert!(parse(Length::parse, "calc(calc(1px) + calc(1px + 4px))").is_ok());
assert!(parse(Length::parse, "calc( 1px + 2px )").is_ok());
assert!(parse(Length::parse, "calc(1px + 2px )").is_ok());
assert!(parse(Length::parse, "calc( 1px + 2px)").is_ok());
assert!(parse(Length::parse, "calc( 1px + 2px / ( 1 + 2 - 1))").is_ok());
}
#[test]
fn test_length_literals() {
assert_roundtrip_with_context!(Length::parse, "0.33px", "0.33px");
assert_roundtrip_with_context!(Length::parse, "0.33in", "0.33in");
assert_roundtrip_with_context!(Length::parse, "0.33cm", "0.33cm");
assert_roundtrip_with_context!(Length::parse, "0.33mm", "0.33mm");
assert_roundtrip_with_context!(Length::parse, "0.33q", "0.33q");
assert_roundtrip_with_context!(Length::parse, "0.33pt", "0.33pt");
assert_roundtrip_with_context!(Length::parse, "0.33pc", "0.33pc");
}
#[test]
fn test_parsing_modes() {
// In default length mode, non-zero lengths must have a unit.
assert!(parse(Length::parse, "1").is_err());
// In SVG length mode, non-zero lengths are assumed to be px.
let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
let context = ParserContext::new(Origin::Author, &url,
Some(CssRuleType::Style), ParsingMode::ALLOW_UNITLESS_LENGTH,
QuirksMode::NoQuirks);
let mut input = ParserInput::new("1");
let mut parser = Parser::new(&mut input);
let result = Length::parse(&context, &mut parser);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(1.))));
}

View file

@ -21,7 +21,7 @@ where F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>> {
let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
let context = ParserContext::new(Origin::Author, &url, Some(CssRuleType::Style), let context = ParserContext::new(Origin::Author, &url, Some(CssRuleType::Style),
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
QuirksMode::NoQuirks); QuirksMode::NoQuirks, None);
let mut parser = Parser::new(input); let mut parser = Parser::new(input);
f(&context, &mut parser) f(&context, &mut parser)
} }
@ -111,7 +111,6 @@ mod column;
mod effects; mod effects;
mod image; mod image;
mod inherited_text; mod inherited_text;
mod length;
mod outline; mod outline;
mod position; mod position;
mod selectors; mod selectors;
@ -119,4 +118,3 @@ mod supports;
mod text_overflow; mod text_overflow;
mod transition_duration; mod transition_duration;
mod transition_timing_function; mod transition_timing_function;
mod value;

View file

@ -1,25 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
use cssparser::{Parser, ParserInput};
use style::context::QuirksMode;
use style::parser::ParserContext;
use style::stylesheets::{CssRuleType, Origin};
use style::values::specified::Number;
use style_traits::ParsingMode;
#[test]
fn test_parsing_allo_all_numeric_values() {
// In SVG length mode, non-zero lengths are assumed to be px.
let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
let context = ParserContext::new(Origin::Author, &url,
Some(CssRuleType::Style), ParsingMode::ALLOW_ALL_NUMERIC_VALUES,
QuirksMode::NoQuirks);
let mut input = ParserInput::new("-1");
let mut parser = Parser::new(&mut input);
let result = Number::parse_non_negative(&context, &mut parser);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Number::new(-1.));
}

View file

@ -1,11 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
use properties::parse;
use style::properties::longhands::background_size;
#[test]
fn background_size_should_reject_negative_values() {
assert!(parse(|c, _, i| background_size::parse(c, i), "-40% -40%").is_err());
}

View file

@ -3,34 +3,32 @@
* 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::{Parser, ParserInput}; use cssparser::{Parser, ParserInput};
use media_queries::CSSErrorReporterTest;
use style::context::QuirksMode; use style::context::QuirksMode;
use style::parser::{ParserContext, ParserErrorContext}; use style::parser::ParserContext;
use style::stylesheets::{CssRuleType, Origin}; use style::stylesheets::{CssRuleType, Origin};
use style_traits::{ParsingMode, ParseError}; use style_traits::{ParsingMode, ParseError};
fn parse<T, F>(f: F, s: &'static str) -> Result<T, ParseError<'static>> fn parse<T, F>(f: F, s: &'static str) -> Result<T, ParseError<'static>>
where F: for<'t> Fn(&ParserContext, where
&ParserErrorContext<CSSErrorReporterTest>, F: for<'t> Fn(
&mut Parser<'static, 't>) -> Result<T, ParseError<'static>> &ParserContext,
&mut Parser<'static, 't>,
) -> Result<T, ParseError<'static>>
{ {
let mut input = ParserInput::new(s); let mut input = ParserInput::new(s);
parse_input(f, &mut input) parse_input(f, &mut input)
} }
fn parse_input<'i: 't, 't, T, F>(f: F, input: &'t mut ParserInput<'i>) -> Result<T, ParseError<'i>> fn parse_input<'i: 't, 't, T, F>(f: F, input: &'t mut ParserInput<'i>) -> Result<T, ParseError<'i>>
where F: Fn(&ParserContext, where
&ParserErrorContext<CSSErrorReporterTest>, F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>>,
&mut Parser<'i, 't>) -> Result<T, ParseError<'i>>
{ {
let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap(); let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
let context = ParserContext::new(Origin::Author, &url, Some(CssRuleType::Style), let context = ParserContext::new(Origin::Author, &url, Some(CssRuleType::Style),
ParsingMode::DEFAULT, ParsingMode::DEFAULT,
QuirksMode::NoQuirks); QuirksMode::NoQuirks, None);
let reporter = CSSErrorReporterTest;
let error_context = ParserErrorContext { error_reporter: &reporter };
let mut parser = Parser::new(input); let mut parser = Parser::new(input);
f(&context, &error_context, &mut parser) f(&context, &mut parser)
} }
macro_rules! assert_roundtrip_with_context { macro_rules! assert_roundtrip_with_context {
@ -38,7 +36,7 @@ macro_rules! assert_roundtrip_with_context {
assert_roundtrip_with_context!($fun, $string, $string); assert_roundtrip_with_context!($fun, $string, $string);
}; };
($fun:expr, $input:expr, $output:expr) => {{ ($fun:expr, $input:expr, $output:expr) => {{
let serialized = parse(|context, _, i| { let serialized = parse(|context, i| {
let parsed = $fun(context, i) let parsed = $fun(context, i)
.expect(&format!("Failed to parse {}", $input)); .expect(&format!("Failed to parse {}", $input));
let serialized = ToCss::to_css_string(&parsed); let serialized = ToCss::to_css_string(&parsed);
@ -47,7 +45,7 @@ macro_rules! assert_roundtrip_with_context {
}, $input).unwrap(); }, $input).unwrap();
let mut input = ::cssparser::ParserInput::new(&serialized); let mut input = ::cssparser::ParserInput::new(&serialized);
let unwrapped = parse_input(|context, _, i| { let unwrapped = parse_input(|context, i| {
let re_parsed = $fun(context, i) let re_parsed = $fun(context, i)
.expect(&format!("Failed to parse serialization {}", $input)); .expect(&format!("Failed to parse serialization {}", $input));
let re_serialized = ToCss::to_css_string(&re_parsed); let re_serialized = ToCss::to_css_string(&re_parsed);
@ -58,6 +56,5 @@ macro_rules! assert_roundtrip_with_context {
}} }}
} }
mod background;
mod scaffolding; mod scaffolding;
mod serialization; mod serialization;

View file

@ -451,7 +451,7 @@ mod shorthand_serialization {
border-left: 4px solid; \ border-left: 4px solid; \
border-image: none;"; border-image: none;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -503,7 +503,7 @@ mod shorthand_serialization {
background-origin: border-box; \ background-origin: border-box; \
background-clip: padding-box;"; background-clip: padding-box;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -527,7 +527,7 @@ mod shorthand_serialization {
background-origin: padding-box; \ background-origin: padding-box; \
background-clip: padding-box;"; background-clip: padding-box;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -551,7 +551,7 @@ mod shorthand_serialization {
background-origin: border-box, padding-box; \ background-origin: border-box, padding-box; \
background-clip: padding-box, padding-box;"; background-clip: padding-box, padding-box;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -582,7 +582,7 @@ mod shorthand_serialization {
background-origin: border-box; \ background-origin: border-box; \
background-clip: padding-box, padding-box;"; background-clip: padding-box, padding-box;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -596,7 +596,7 @@ mod shorthand_serialization {
let block_text = "\ let block_text = "\
background-position-x: 30px;\ background-position-x: 30px;\
background-position-y: bottom 20px;"; background-position-y: bottom 20px;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
assert_eq!(serialization, "background-position: left 30px bottom 20px;"); assert_eq!(serialization, "background-position: left 30px bottom 20px;");
@ -605,7 +605,7 @@ mod shorthand_serialization {
let block_text = "\ let block_text = "\
background-position-x: center;\ background-position-x: center;\
background-position-y: 20px;"; background-position-y: 20px;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
assert_eq!(serialization, "background-position: center 20px;"); assert_eq!(serialization, "background-position: center 20px;");
} }
@ -691,7 +691,7 @@ mod shorthand_serialization {
animation-iteration-count: infinite;\ animation-iteration-count: infinite;\
animation-play-state: paused;"; animation-play-state: paused;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -710,7 +710,7 @@ mod shorthand_serialization {
animation-iteration-count: infinite, 2;\ animation-iteration-count: infinite, 2;\
animation-play-state: paused, running;"; animation-play-state: paused, running;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -736,7 +736,7 @@ mod shorthand_serialization {
animation-iteration-count: infinite, 2; \ animation-iteration-count: infinite, 2; \
animation-play-state: paused, running;"; animation-play-state: paused, running;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -753,7 +753,7 @@ mod shorthand_serialization {
animation-iteration-count: infinite, 2; \ animation-iteration-count: infinite, 2; \
animation-play-state: paused, running;"; animation-play-state: paused, running;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -771,7 +771,7 @@ mod shorthand_serialization {
transition-delay: 4s; \ transition-delay: 4s; \
transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2);"; transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2);";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -785,7 +785,7 @@ mod shorthand_serialization {
transition-delay: 4s, 5s; \ transition-delay: 4s, 5s; \
transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2), ease;"; transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2), ease;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -807,7 +807,7 @@ mod shorthand_serialization {
transition-delay: 4s, 5s; \ transition-delay: 4s, 5s; \
transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2), ease;"; transition-timing-function: cubic-bezier(0.2, 5, 0.5, 2), ease;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -820,7 +820,7 @@ mod shorthand_serialization {
transition-duration: 3s; \ transition-duration: 3s; \
transition-delay: 4s; \ transition-delay: 4s; \
transition-timing-function: steps(2, start);"; transition-timing-function: steps(2, start);";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -833,7 +833,7 @@ mod shorthand_serialization {
transition-duration: 3s; \ transition-duration: 3s; \
transition-delay: 4s; \ transition-delay: 4s; \
transition-timing-function: frames(2);"; transition-timing-function: frames(2);";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
@ -846,7 +846,7 @@ mod shorthand_serialization {
#[test] #[test]
fn css_wide_keywords_should_be_parsed() { fn css_wide_keywords_should_be_parsed() {
let block_text = "--a:inherit;"; let block_text = "--a:inherit;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
assert_eq!(serialization, "--a: inherit;"); assert_eq!(serialization, "--a: inherit;");
@ -855,7 +855,7 @@ mod shorthand_serialization {
#[test] #[test]
fn non_keyword_custom_property_should_be_unparsed() { fn non_keyword_custom_property_should_be_unparsed() {
let block_text = "--main-color: #06c;"; let block_text = "--main-color: #06c;";
let block = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), block_text).unwrap(); let block = parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap();
let serialization = block.to_css_string(); let serialization = block.to_css_string();
assert_eq!(serialization, block_text); assert_eq!(serialization, block_text);
@ -885,7 +885,7 @@ mod shorthand_serialization {
let shadow_decl = BoxShadowList(vec![shadow_val]); let shadow_decl = BoxShadowList(vec![shadow_val]);
properties.push(PropertyDeclaration::BoxShadow(shadow_decl)); properties.push(PropertyDeclaration::BoxShadow(shadow_decl));
let shadow_css = "box-shadow: 1px 2px 3px 4px;"; let shadow_css = "box-shadow: 1px 2px 3px 4px;";
let shadow = parse(|c, e, i| Ok(parse_property_declaration_list(c, e, i)), shadow_css).unwrap(); let shadow = parse(|c, i| Ok(parse_property_declaration_list(c, i)), shadow_css).unwrap();
assert_eq!(shadow.to_css_string(), shadow_css); assert_eq!(shadow.to_css_string(), shadow_css);
} }

View file

@ -55,7 +55,7 @@ fn parse_rules(css: &str) -> Vec<(StyleSource, CascadeLevel)> {
media, media,
lock, lock,
None, None,
&ErrorringErrorReporter, Some(&ErrorringErrorReporter),
QuirksMode::NoQuirks, QuirksMode::NoQuirks,
0); 0);
let guard = s.shared_lock.read(); let guard = s.shared_lock.read();

View file

@ -4,7 +4,6 @@
use cssparser::{self, SourceLocation}; use cssparser::{self, SourceLocation};
use html5ever::{Namespace as NsAtom}; use html5ever::{Namespace as NsAtom};
use media_queries::CSSErrorReporterTest;
use parking_lot::RwLock; use parking_lot::RwLock;
use selectors::attr::*; use selectors::attr::*;
use selectors::parser::*; use selectors::parser::*;
@ -71,7 +70,7 @@ fn test_parse_stylesheet() {
let lock = SharedRwLock::new(); let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty())); let media = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock, let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0); None, None, QuirksMode::NoQuirks, 0);
let mut namespaces = Namespaces::default(); let mut namespaces = Namespaces::default();
namespaces.default = Some(ns!(html)); namespaces.default = Some(ns!(html));
let expected = Stylesheet { let expected = Stylesheet {
@ -345,7 +344,7 @@ fn test_report_error_stylesheet() {
let lock = SharedRwLock::new(); let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty())); let media = Arc::new(lock.wrap(MediaList::empty()));
Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock, Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
None, &error_reporter, QuirksMode::NoQuirks, 5); None, Some(&error_reporter), QuirksMode::NoQuirks, 5);
error_reporter.assert_messages_contain(&[ error_reporter.assert_messages_contain(&[
(8, 18, "Unsupported property declaration: 'display: invalid;'"), (8, 18, "Unsupported property declaration: 'display: invalid;'"),
@ -387,7 +386,7 @@ fn test_no_report_unrecognized_vendor_properties() {
let lock = SharedRwLock::new(); let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty())); let media = Arc::new(lock.wrap(MediaList::empty()));
Stylesheet::from_str(css, url, Origin::UserAgent, media, lock, Stylesheet::from_str(css, url, Origin::UserAgent, media, lock,
None, &error_reporter, QuirksMode::NoQuirks, 0); None, Some(&error_reporter), QuirksMode::NoQuirks, 0);
error_reporter.assert_messages_contain(&[ error_reporter.assert_messages_contain(&[
(4, 31, "Unsupported property declaration: '-moz-background-color: red;'"), (4, 31, "Unsupported property declaration: '-moz-background-color: red;'"),
@ -406,7 +405,7 @@ fn test_source_map_url() {
let lock = SharedRwLock::new(); let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty())); let media = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(test.0, url.clone(), Origin::UserAgent, media, lock, let stylesheet = Stylesheet::from_str(test.0, url.clone(), Origin::UserAgent, media, lock,
None, &CSSErrorReporterTest, QuirksMode::NoQuirks, None, None, QuirksMode::NoQuirks,
0); 0);
let url_opt = stylesheet.contents.source_map_url.read(); let url_opt = stylesheet.contents.source_map_url.read();
assert_eq!(*url_opt, test.1); assert_eq!(*url_opt, test.1);
@ -425,7 +424,7 @@ fn test_source_url() {
let lock = SharedRwLock::new(); let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty())); let media = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(test.0, url.clone(), Origin::UserAgent, media, lock, let stylesheet = Stylesheet::from_str(test.0, url.clone(), Origin::UserAgent, media, lock,
None, &CSSErrorReporterTest, QuirksMode::NoQuirks, None, None, QuirksMode::NoQuirks,
0); 0);
let url_opt = stylesheet.contents.source_url.read(); let url_opt = stylesheet.contents.source_url.read();
assert_eq!(*url_opt, test.1); assert_eq!(*url_opt, test.1);

Some files were not shown because too many files have changed in this diff Show more