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

style: Import changes from mozilla-central.

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

View file

@ -1417,7 +1417,7 @@ impl BlockFlow {
// Per CSS 2.1 § 16.3.1, text alignment propagates to all children in flow.
//
// 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);
// Handle `text-indent` on behalf of any inline children that we have. This is
@ -1425,7 +1425,7 @@ impl BlockFlow {
// we know.
if kid.is_inline_flow() {
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);
}
}
@ -2340,7 +2340,7 @@ pub trait ISizeAndMarginsComputer {
containing_block_inline_size),
MaybeAuto::from_style(position.inline_end,
containing_block_inline_size),
style.get_inheritedtext().text_align,
style.get_inherited_text().text_align,
available_inline_size)
}

View file

@ -1095,7 +1095,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
kid_flow.as_block()
.fragment
.style()
.get_inheritedtable()
.get_inherited_table()
.caption_side == side {
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
// if the cell has any in-flow elements (even empty ones!) and has `empty-cells` set to
// `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| {
let position = kid.style(self.style_context()).get_box().position;
!kid.is_content() ||
@ -1871,7 +1871,7 @@ fn bidi_control_chars(style: &ServoArc<ComputedValues>) -> Option<(&'static str,
use style::computed_values::unicode_bidi::T::*;
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
match (unicode_bidi, direction) {

View file

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

View file

@ -561,7 +561,7 @@ impl FlexFlow {
.explicit_block_size(parent_container_size)
.map(|x| max(x - box_border, Au(0)));
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) {
let items = &mut self.items[line.range.clone()];

View file

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

View file

@ -934,7 +934,7 @@ impl InlineFlow {
if fragments.fragments.is_empty() {
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.
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();
for fragment in &mut self.fragments.fragments {
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 => {
intrinsic_sizes_for_nonbroken_run.union_nonbreaking_inline(
&intrinsic_sizes_for_fragment)

View file

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

View file

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

View file

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

View file

@ -130,7 +130,7 @@ impl Flow for TableRowGroupFlow {
let (inline_start_content_edge, inline_end_content_edge) = (Au(0), Au(0));
let 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;
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
shared_context,

View file

@ -170,7 +170,7 @@ impl TextRunScanner {
{
let in_fragment = self.clump.front().unwrap();
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);
compression = match in_fragment.white_space() {
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.
pub fn line_height_from_style(style: &ComputedValues, metrics: &FontMetrics) -> Au {
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::Number(l) => font_size.scale_by(l.0),
LineHeight::Length(l) => Au::from(l)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -127,6 +127,7 @@ use std::cell::{Cell, Ref, RefMut};
use std::collections::{HashMap, HashSet, VecDeque};
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::default::Default;
use std::fmt;
use std::mem;
use std::ptr::NonNull;
use std::rc::Rc;
@ -213,6 +214,12 @@ struct StyleSheetInDocument {
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 {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.sheet, &other.sheet)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,8 +9,8 @@
use Atom;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
use cssparser::{CowRcStr, Parser, SourceLocation, Token};
use error_reporting::{ContextualParseError, ParseErrorReporter};
use parser::{Parse, ParserContext, ParserErrorContext};
use error_reporting::ContextualParseError;
use parser::{Parse, ParserContext};
use selectors::parser::SelectorParseErrorKind;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
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
pub fn parse_counter_style_body<'i, 't, R>(
pub fn parse_counter_style_body<'i, 't>(
name: CustomIdent,
context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser<'i, 't>,
location: SourceLocation,
) -> Result<CounterStyleRuleData, ParseError<'i>>
where
R: ParseErrorReporter,
{
) -> Result<CounterStyleRuleData, ParseError<'i>> {
let start = input.current_source_location();
let mut rule = CounterStyleRuleData::empty(name, location);
{
@ -98,7 +94,7 @@ where
slice,
error,
);
context.log_css_error(error_context, location, error)
context.log_css_error(location, error)
}
}
}
@ -134,7 +130,7 @@ where
_ => None,
};
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))
} else {
Ok(rule)

View file

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

View file

@ -7,7 +7,6 @@
#![deny(missing_docs)]
use cssparser::{BasicParseErrorKind, ParseErrorKind, SourceLocation, Token};
use log;
use std::fmt;
use style_traits::ParseError;
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`
/// environment variable.
/// (See [`env_logger`](https://rust-lang-nursery.github.io/log/env_logger/).)
#[cfg(feature = "servo")]
pub struct RustLogReporter;
#[cfg(feature = "servo")]
impl ParseErrorReporter for RustLogReporter {
fn report_error(
&self,
@ -238,6 +239,7 @@ impl ParseErrorReporter for RustLogReporter {
location: SourceLocation,
error: ContextualParseError,
) {
use log;
if log_enabled!(log::Level::Info) {
info!(
"Url:\t{}\n{}:{} {}",
@ -249,17 +251,3 @@ impl ParseErrorReporter for RustLogReporter {
}
}
}
/// Error reporter which silently forgets errors
pub struct NullReporter;
impl ParseErrorReporter for NullReporter {
fn report_error(
&self,
_url: &UrlExtraData,
_location: SourceLocation,
_error: ContextualParseError,
) {
// do nothing
}
}

View file

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

View file

@ -18,13 +18,24 @@ use properties::ComputedValues;
use selector_parser::SnapshotMap;
use servo_arc::Arc;
use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards};
use std::fmt;
use stylesheets::{CssRule, Origin, StylesheetContents, StylesheetInDocument};
use stylist::Stylist;
/// Little wrapper to a Gecko style sheet.
#[derive(Debug, Eq, PartialEq)]
#[derive(Eq, PartialEq)]
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 {
fn to_media_list_key(&self) -> MediaListKey {
use std::mem;

View file

@ -64,6 +64,27 @@ pub struct Device {
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 Send for Device {}

View file

@ -6,7 +6,7 @@
use cssparser::Parser;
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::root::{RustString, nsStyleImageRequest};
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::mem;
use style_traits::{CssWriter, ParseError, ToCss};
use stylesheets::UrlExtraData;
use values::computed::{Context, ToComputedValue};
/// A CSS url() value for gecko.
@ -32,7 +33,7 @@ pub struct CssUrl {
/// The URL extra data.
#[css(skip)]
pub extra_data: RefPtr<URLExtraData>,
pub extra_data: UrlExtraData,
}
impl CssUrl {
@ -58,7 +59,7 @@ impl CssUrl {
&url.mString as *const _ as *const RawOffsetArc<String>;
CssUrl {
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());
ServoBundledURI {
mURLString: unsafe { mem::transmute::<_, RawOffsetArc<RustString>>(arc_offset) },
mExtraData: self.extra_data.get(),
mExtraData: self.extra_data.0.get(),
}
}
}

View file

@ -78,15 +78,6 @@ impl<T: RefCounted> RefPtr<T> {
ret
}
/// 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.
///
/// structs::RefPtr does not have a destructor, so this may leak

View file

@ -122,7 +122,8 @@ impl WeakAtom {
unsafe { u8_ptr.offset(string_offset) as *const u16 }
} else {
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) }
}

View file

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

View file

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

View file

@ -19,6 +19,34 @@ import data
RE_PYTHON_ADDR = re.compile(r'<.+? object at 0x[0-9a-fA-F]+>')
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():
usage = "Usage: %s [ servo | gecko ] [ style-crate | geckolib <template> | html ]" % sys.argv[0]
@ -31,14 +59,41 @@ def main():
abort(usage)
properties = data.PropertiesData(product=product)
template = os.path.join(BASE, "properties.mako.rs")
rust = render(template, product=product, data=properties, __file__=template)
files = {}
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":
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":
template = os.path.join(BASE, "gecko.mako.rs")
rust = render(template, data=properties)
write(os.environ["OUT_DIR"], "gecko_properties.rs", rust)
write(OUT_DIR, "gecko_properties.rs", rust)
elif output == "geckolib":
if len(sys.argv) < 4:
abort(usage)

View file

@ -38,6 +38,10 @@ def to_rust_ident(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):
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):
self.gecko_struct_name = "Gecko" + 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.longhands = []
self.inherited = inherited

View file

@ -11,8 +11,8 @@ use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind};
use custom_properties::CustomPropertiesBuilder;
use error_reporting::{ParseErrorReporter, ContextualParseError};
use parser::{ParserContext, ParserErrorContext};
use properties::animated_properties::AnimationValue;
use parser::ParserContext;
use properties::animated_properties::{AnimationValue, AnimationValueMap};
use shared_lock::Locked;
use smallbitvec::{self, SmallBitVec};
use smallvec::SmallVec;
@ -24,7 +24,6 @@ use style_traits::{CssWriter, ParseError, ParsingMode, StyleParseErrorKind, ToCs
use stylesheets::{CssRuleType, Origin, UrlExtraData};
use super::*;
use values::computed::Context;
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
/// The animation rules.
///
@ -564,51 +563,71 @@ impl PropertyDeclarationBlock {
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>
///
/// Returns whether any declaration was actually removed.
pub fn remove_property<C>(
/// `first_declaration` needs to be the result of
/// `first_declaration_to_remove`.
#[inline]
pub fn remove_property(
&mut self,
property: &PropertyId,
mut before_change_callback: C,
) -> bool
where
C: FnMut(&Self),
{
let longhand_id = property.longhand_id();
if let Some(id) = longhand_id {
if !self.longhands.contains(id) {
return false
}
}
let mut removed_at_least_one = false;
let mut i = 0;
first_declaration: usize,
) {
debug_assert_eq!(
Some(first_declaration),
self.first_declaration_to_remove(property)
);
debug_assert!(self.declarations[first_declaration].id().is_or_is_longhand_of(property));
self.remove_declaration_at(first_declaration);
let shorthand = match property.as_shorthand() {
Ok(s) => s,
Err(_longhand_or_custom) => return,
};
let mut i = first_declaration;
let mut len = self.len();
while i < len {
{
let id = self.declarations[i].id();
if !id.is_or_is_longhand_of(property) {
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);
if !self.declarations[i].id().is_longhand_of(shorthand) {
i += 1;
continue;
}
self.declarations.remove(i);
self.remove_declaration_at(i);
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.
@ -667,7 +686,6 @@ impl PropertyDeclarationBlock {
}
/// Convert AnimationValueMap to PropertyDeclarationBlock.
#[cfg(feature = "gecko")]
pub fn from_animation_value_map(animation_value_map: &AnimationValueMap) -> Self {
let len = animation_value_map.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
/// property.
#[cfg(feature = "gecko")]
pub fn has_css_wide_keyword(&self, property: &PropertyId) -> bool {
if let Some(id) = property.longhand_id() {
if !self.longhands.contains(id) {
@ -727,9 +744,7 @@ impl PropertyDeclarationBlock {
builder.build()
}
}
impl PropertyDeclarationBlock {
/// Like the method on ToCss, but without the type parameter to avoid
/// accidentally monomorphizing this large function multiple times for
/// different writers.
@ -1061,50 +1076,49 @@ where
/// A helper to parse the style attribute of an element, in order for this to be
/// 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,
url_data: &UrlExtraData,
error_reporter: &R,
error_reporter: Option<&ParseErrorReporter>,
quirks_mode: QuirksMode,
) -> PropertyDeclarationBlock
where
R: ParseErrorReporter
{
) -> PropertyDeclarationBlock {
let context = ParserContext::new(
Origin::Author,
url_data,
Some(CssRuleType::Style),
ParsingMode::DEFAULT,
quirks_mode,
error_reporter,
);
let error_context = ParserErrorContext { error_reporter: error_reporter };
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
/// `PropertyDeclaration`s when expanding a shorthand, for example.
///
/// 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,
id: PropertyId,
input: &str,
url_data: &UrlExtraData,
error_reporter: &R,
error_reporter: Option<&ParseErrorReporter>,
parsing_mode: ParsingMode,
quirks_mode: QuirksMode
) -> Result<(), ()>
where
R: ParseErrorReporter
{
) -> Result<(), ()> {
let context = ParserContext::new(
Origin::Author,
url_data,
Some(CssRuleType::Style),
parsing_mode,
quirks_mode,
error_reporter,
);
let mut input = ParserInput::new(input);
@ -1115,9 +1129,10 @@ where
}).map_err(|err| {
let location = err.location;
let error = ContextualParseError::UnsupportedPropertyDeclaration(
parser.slice_from(start_position), err);
let error_context = ParserErrorContext { error_reporter: error_reporter };
context.log_css_error(&error_context, location, error);
parser.slice_from(start_position),
err,
);
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
/// block.
pub fn parse_property_declaration_list<R>(
pub fn parse_property_declaration_list(
context: &ParserContext,
error_context: &ParserErrorContext<R>,
input: &mut Parser,
) -> PropertyDeclarationBlock
where
R: ParseErrorReporter
{
) -> PropertyDeclarationBlock {
let mut declarations = SourcePropertyDeclaration::new();
let mut block = PropertyDeclarationBlock::new();
let parser = PropertyDeclarationParser {
@ -1212,7 +1223,7 @@ where
let location = error.location;
let error = ContextualParseError::UnsupportedPropertyDeclaration(slice, error);
context.log_css_error(error_context, location, error);
context.log_css_error(location, error);
}
}
}

View file

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

View file

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

View file

@ -97,29 +97,9 @@ macro_rules! expanded {
/// A module with all the code for longhand properties.
#[allow(missing_docs)]
pub mod longhands {
<%include file="/longhand/background.mako.rs" />
<%include file="/longhand/border.mako.rs" />
<%include file="/longhand/box.mako.rs" />
<%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" />
% for style_struct in data.style_structs:
include!("${repr(os.path.join(OUT_DIR, 'longhands/{}.rs'.format(style_struct.name_lower)))[1:-1]}");
% endfor
}
macro_rules! unwrap_or_initial {
@ -137,23 +117,37 @@ pub mod shorthands {
use style_traits::{ParseError, StyleParseErrorKind};
use values::specified;
<%include file="/shorthand/serialize.mako.rs" />
<%include file="/shorthand/background.mako.rs" />
<%include file="/shorthand/border.mako.rs" />
<%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" />
use style_traits::{CssWriter, ToCss};
use values::specified::{BorderStyle, Color};
use std::fmt::{self, Write};
// 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.
//
// Also, make sure logical properties appear before its physical
@ -1448,6 +1442,7 @@ impl UnparsedValue {
None,
ParsingMode::DEFAULT,
quirks_mode,
None,
);
let mut input = ParserInput::new(&css);
@ -3852,7 +3847,7 @@ where
}
% if category_to_cascade_now == "early":
let writing_mode =
WritingMode::new(context.builder.get_inheritedbox());
WritingMode::new(context.builder.get_inherited_box());
context.builder.writing_mode = writing_mode;
let mut _skip_font_family = false;

View file

@ -1,27 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use style_traits::{CssWriter, ToCss};
use values::specified::{BorderStyle, Color};
use std::fmt::{self, Write};
fn serialize_directional_border<W, I,>(
dest: &mut CssWriter<W>,
width: &I,
style: &BorderStyle,
color: &Color,
) -> fmt::Result
where
W: Write,
I: ToCss,
{
width.to_css(dest)?;
dest.write_str(" ")?;
style.to_css(dest)?;
if *color != Color::CurrentColor {
dest.write_str(" ")?;
color.to_css(dest)?;
}
Ok(())
}

View file

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

View file

@ -815,7 +815,11 @@ impl<E: TElement> StyleSharingCache<E> {
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(
&mut self,
shared_context: &SharedStyleContext,
@ -841,7 +845,15 @@ impl<E: TElement> StyleSharingCache<E> {
if style.visited_rules() != visited_rules {
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
// actual visitedness, but at the end of the cascade (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
// requirements of visited, assuming we get a cache hit on only one
// 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() {
return None;
}

View file

@ -19,6 +19,14 @@ use properties::longhands::position::computed_value::T as Position;
/// NOTE(emilio): If new adjustments are introduced that depend on reset
/// properties of the parent, you may need tweaking the
/// `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> {
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::writing_mode::T as WritingMode;
let writing_mode = self.style.get_inheritedbox().clone_writing_mode();
let text_combine_upright = self.style.get_inheritedtext().clone_text_combine_upright();
let writing_mode = self.style.get_inherited_box().clone_writing_mode();
let text_combine_upright = self.style.get_inherited_text().clone_text_combine_upright();
if writing_mode != WritingMode::HorizontalTb &&
text_combine_upright == TextCombineUpright::All
@ -258,7 +266,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
.flags
.insert(ComputedValueFlags::IS_TEXT_COMBINED);
self.style
.mutate_inheritedbox()
.mutate_inherited_box()
.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://github.com/servo/servo/issues/15754>
fn adjust_for_writing_mode(&mut self, layout_parent_style: &ComputedValues) {
let our_writing_mode = self.style.get_inheritedbox().clone_writing_mode();
let parent_writing_mode = layout_parent_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_inherited_box().clone_writing_mode();
if our_writing_mode != parent_writing_mode &&
self.style.get_box().clone_display() == Display::Inline
@ -488,13 +496,13 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
return;
}
match self.style.get_inheritedtext().clone_text_align() {
match self.style.get_inherited_text().clone_text_align() {
TextAlign::MozLeft | TextAlign::MozCenter | TextAlign::MozRight => {},
_ => return,
}
self.style
.mutate_inheritedtext()
.mutate_inherited_text()
.set_text_align(TextAlign::Start)
}
@ -508,8 +516,8 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
use values::computed::text::TextDecorationsInEffect;
let decorations_in_effect = TextDecorationsInEffect::from_style(&self.style);
if self.style.get_inheritedtext().text_decorations_in_effect != decorations_in_effect {
self.style.mutate_inheritedtext().text_decorations_in_effect = decorations_in_effect;
if self.style.get_inherited_text().text_decorations_in_effect != decorations_in_effect {
self.style.mutate_inherited_text().text_decorations_in_effect = decorations_in_effect;
}
}

View file

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

View file

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

View file

@ -24,10 +24,9 @@ pub mod supports_rule;
pub mod viewport_rule;
use cssparser::{parse_one_rule, Parser, ParserInput};
use error_reporting::NullReporter;
#[cfg(feature = "gecko")]
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
use parser::{ParserContext, ParserErrorContext};
use parser::ParserContext;
use servo_arc::Arc;
use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked};
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.
#[cfg(feature = "gecko")]
pub type UrlExtraData =
::gecko_bindings::sugar::refptr::RefPtr<::gecko_bindings::structs::URLExtraData>;
#[derive(Clone, PartialEq)]
pub struct UrlExtraData(
pub ::gecko_bindings::sugar::refptr::RefPtr<::gecko_bindings::structs::URLExtraData>
);
#[cfg(feature = "gecko")]
impl UrlExtraData {
/// Returns a string for the url.
///
/// Unimplemented currently.
pub fn as_str(&self) -> &str {
// TODO
"(stylo: not supported)"
/// True if this URL scheme is chrome.
#[inline]
pub fn is_chrome(&self) -> bool {
self.0.mIsChrome
}
/// True if this URL scheme is chrome.
pub fn is_chrome(&self) -> bool {
self.mIsChrome
/// Create a reference to this `UrlExtraData` from a reference to pointer.
///
/// 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>,
) -> Result<Self, RulesMutateError> {
let url_data = parent_stylesheet_contents.url_data.read();
let error_reporter = NullReporter;
let context = ParserContext::new(
parent_stylesheet_contents.origin,
&url_data,
None,
ParsingMode::DEFAULT,
parent_stylesheet_contents.quirks_mode,
None,
);
let mut input = ParserInput::new(css);
@ -246,9 +275,6 @@ impl CssRule {
let mut rule_parser = TopLevelRuleParser {
stylesheet_origin: parent_stylesheet_contents.origin,
context,
error_context: ParserErrorContext {
error_reporter: &error_reporter,
},
shared_lock: &shared_lock,
loader,
state,

View file

@ -8,10 +8,10 @@ use {Namespace, Prefix};
use counter_style::{parse_counter_style_body, parse_counter_style_name_definition};
use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser};
use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, SourceLocation};
use error_reporting::{ContextualParseError, ParseErrorReporter};
use error_reporting::ContextualParseError;
use font_face::parse_font_face_block;
use media_queries::MediaList;
use parser::{Parse, ParserContext, ParserErrorContext};
use parser::{Parse, ParserContext};
use properties::parse_property_declaration_list;
use selector_parser::{SelectorImpl, SelectorParser};
use selectors::SelectorList;
@ -40,7 +40,7 @@ pub struct InsertRuleContext<'a> {
}
/// 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.
pub stylesheet_origin: Origin,
/// 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
/// `ParserContext::new_with_rule_type` will.
pub context: ParserContext<'a>,
/// The context required for reporting parse errors.
pub error_context: ParserErrorContext<'a, R>,
/// The current state of the parser.
pub state: State,
/// 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>>,
}
impl<'b, R> TopLevelRuleParser<'b, R> {
fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b, R> {
impl<'b> TopLevelRuleParser<'b> {
fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b> {
NestedRuleParser {
stylesheet_origin: self.stylesheet_origin,
shared_lock: self.shared_lock,
context: &self.context,
error_context: &self.error_context,
namespaces: &self.namespaces,
}
}
@ -176,7 +173,7 @@ pub enum AtRuleNonBlockPrelude {
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 PreludeBlock = AtRuleBlockPrelude;
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 = CssUrl::parse_from_string(url_string, &self.context);
let media = MediaList::parse(
&self.context,
input,
self.error_context.error_reporter,
);
let media = MediaList::parse(&self.context, input);
let media = Arc::new(self.shared_lock.wrap(media));
let prelude = AtRuleNonBlockPrelude::Import(url, media, location);
@ -296,7 +289,7 @@ pub struct QualifiedRuleParserPrelude {
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 QualifiedRule = CssRule;
type Error = StyleParseErrorKind<'i>;
@ -327,27 +320,29 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRulePars
}
#[derive(Clone)] // shallow, relatively cheap .clone
struct NestedRuleParser<'a, 'b: 'a, R: 'b> {
struct NestedRuleParser<'a, 'b: 'a> {
stylesheet_origin: Origin,
shared_lock: &'a SharedRwLock,
context: &'a ParserContext<'b>,
error_context: &'a ParserErrorContext<'b, R>,
namespaces: &'a Namespaces,
}
impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
impl<'a, 'b> NestedRuleParser<'a, 'b> {
fn parse_nested_rules(
&mut self,
input: &mut Parser,
rule_type: CssRuleType,
) -> 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 {
stylesheet_origin: self.stylesheet_origin,
shared_lock: self.shared_lock,
context: &context,
error_context: &self.error_context,
namespaces: self.namespaces,
};
@ -359,8 +354,7 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> {
Err((error, slice)) => {
let location = error.location;
let error = ContextualParseError::InvalidRule(slice, error);
self.context
.log_css_error(self.error_context, location, error);
self.context.log_css_error(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 PreludeBlock = AtRuleBlockPrelude;
type AtRule = CssRule;
@ -383,11 +377,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
match_ignore_ascii_case! { &*name,
"media" => {
let media_queries = MediaList::parse(
self.context,
input,
self.error_context.error_reporter,
);
let media_queries = MediaList::parse(self.context, input);
let arc = Arc::new(self.shared_lock.wrap(media_queries));
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(
parse_font_face_block(&context, self.error_context, input, location).into(),
parse_font_face_block(&context, input, location).into(),
))))
},
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(
FontFeatureValuesRule::parse(
&context,
self.error_context,
input,
family_names,
location,
@ -505,7 +494,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
parse_counter_style_body(
name,
&context,
self.error_context,
input,
location,
)?.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(
ViewportRule::parse(&context, self.error_context, input)?,
ViewportRule::parse(&context, input)?,
))))
},
AtRuleBlockPrelude::Keyframes(name, vendor_prefix, source_location) => {
@ -559,7 +547,6 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
name,
keyframes: parse_keyframe_list(
&context,
self.error_context,
input,
self.shared_lock,
),
@ -576,7 +563,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a
);
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 {
block: Arc::new(self.shared_lock.wrap(declarations)),
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 QualifiedRule = CssRule;
type Error = StyleParseErrorKind<'i>;
@ -627,7 +614,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRulePa
let context =
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 {
selectors: prelude.selectors,
block: Arc::new(self.shared_lock.wrap(declarations)),

View file

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

View file

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

View file

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

View file

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

View file

@ -514,7 +514,7 @@ impl ToComputedValue for TextAlign {
}
let parent = _context
.builder
.get_parent_inheritedtext()
.get_parent_inherited_text()
.clone_text_align();
let ltr = _context.builder.inherited_writing_mode().is_bidi_ltr();
match (parent, ltr) {
@ -529,7 +529,7 @@ impl ToComputedValue for TextAlign {
TextAlign::MozCenterOrInherit => {
let parent = _context
.builder
.get_parent_inheritedtext()
.get_parent_inherited_text()
.clone_text_align();
if parent == TextAlignKeyword::Start {
TextAlignKeyword::Center
@ -653,7 +653,7 @@ impl ToComputedValue for TextEmphasisStyle {
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
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
{
TextEmphasisShapeKeyword::Circle

View file

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