mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
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:
commit
16bdf9225d
101 changed files with 645 additions and 640 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
||||||
(
|
(
|
||||||
|
|
|
@ -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()];
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
)))
|
)))
|
||||||
);
|
);
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 can’t borrow `guard` twice at the same time.
|
// Clone an Arc because we can’t borrow `guard` twice at the same time.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
||||||
|
|
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 context’s error reporting.
|
/// Record a CSS parse error with this context’s 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.
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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(())
|
|
||||||
}
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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.))));
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
|
|
|
@ -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.));
|
|
||||||
}
|
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue