stylo: Create error reporters linked to documents (bug 1352669)

This commit is contained in:
Josh Matthews 2017-07-06 13:18:36 -04:00
parent 901525c911
commit dc2a500f4b
12 changed files with 5713 additions and 4361 deletions

View file

@ -8,6 +8,9 @@
use cssparser::{Parser, SourcePosition, BasicParseError, Token};
use cssparser::ParseError as CssParseError;
#[cfg(feature = "gecko")] use gecko::error_reporter::ErrorReporter;
#[cfg(feature = "gecko")] use gecko_bindings::structs::Loader;
#[cfg(feature = "gecko")] use gecko_bindings::structs::ServoStyleSheet;
use log;
use style_traits::ParseError;
use stylesheets::UrlExtraData;
@ -190,6 +193,15 @@ impl ParseErrorReporter for NullReporter {
}
/// Create an instance of the default error reporter.
#[cfg(feature = "servo")]
pub fn create_error_reporter() -> RustLogReporter {
RustLogReporter
}
/// Create an instance of the default error reporter for Stylo.
#[cfg(feature = "gecko")]
pub fn create_error_reporter(sheet: *mut ServoStyleSheet,
loader: *mut Loader)
-> ErrorReporter {
ErrorReporter::new(loader, sheet)
}

View file

@ -0,0 +1,90 @@
/* 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/. */
//! Wrapper around Gecko's CSS error reporting mechanism.
#![allow(unsafe_code)]
use cssparser::{Parser, SourcePosition};
use error_reporting::{ParseErrorReporter, ContextualParseError};
use gecko_bindings::bindings::{Gecko_CreateCSSErrorReporter, Gecko_DestroyCSSErrorReporter};
use gecko_bindings::bindings::Gecko_ReportUnexpectedCSSError;
use gecko_bindings::structs::{Loader, ServoStyleSheet, nsIURI};
use gecko_bindings::structs::ErrorReporter as GeckoErrorReporter;
use stylesheets::UrlExtraData;
/// Wrapper around an instance of Gecko's CSS error reporter.
pub struct ErrorReporter(*mut GeckoErrorReporter);
unsafe impl Sync for ErrorReporter {}
impl ErrorReporter {
/// Create a new instance of the Gecko error reporter.
pub fn new(loader: *mut Loader,
sheet: *mut ServoStyleSheet) -> ErrorReporter {
unsafe {
ErrorReporter(Gecko_CreateCSSErrorReporter(sheet, loader))
}
}
}
impl Drop for ErrorReporter {
fn drop(&mut self) {
unsafe {
Gecko_DestroyCSSErrorReporter(self.0);
}
}
}
impl<'a> ContextualParseError<'a> {
fn to_gecko_message(&self) -> (&'static [u8], &'a str) {
match *self {
ContextualParseError::UnsupportedPropertyDeclaration(decl, _) =>
(b"PEUnknownProperty\0", decl),
ContextualParseError::UnsupportedFontFaceDescriptor(decl, _) =>
(b"PEUnknwnFontDesc\0", decl),
ContextualParseError::InvalidKeyframeRule(rule, _) =>
(b"PEKeyframeBadName\0", rule),
ContextualParseError::UnsupportedKeyframePropertyDeclaration(decl, _) =>
(b"PEBadSelectorKeyframeRuleIgnored\0", decl),
ContextualParseError::InvalidRule(rule, _) =>
(b"PEDeclDropped\0", rule),
ContextualParseError::UnsupportedRule(rule, _) =>
(b"PEDeclDropped\0", rule),
ContextualParseError::UnsupportedViewportDescriptorDeclaration(..) |
ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(..) |
ContextualParseError::InvalidCounterStyleWithoutSymbols(..) |
ContextualParseError::InvalidCounterStyleNotEnoughSymbols(..) |
ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols |
ContextualParseError::InvalidCounterStyleExtendsWithSymbols |
ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols =>
(b"PEUnknownAtRule\0", ""),
}
}
}
impl ParseErrorReporter for ErrorReporter {
fn report_error<'a>(&self,
input: &mut Parser,
position: SourcePosition,
error: ContextualParseError<'a>,
url: &UrlExtraData,
line_number_offset: u64) {
let location = input.source_location(position);
let line_number = location.line + line_number_offset as u32;
let (name, param) = error.to_gecko_message();
let source = "";
unsafe {
Gecko_ReportUnexpectedCSSError(self.0,
name.as_ptr() as *const _,
param.as_ptr() as *const _,
param.len() as u32,
source.as_ptr() as *const _,
source.len() as u32,
line_number as u32,
location.column as u32,
url.mBaseURI.raw::<nsIURI>());
}
}
}

View file

@ -6,6 +6,7 @@ use gecko_bindings::structs::nsTArray;
type nsACString_internal = nsACString;
type nsAString_internal = nsAString;
use gecko_bindings::structs::mozilla::css::GridTemplateAreasValue;
use gecko_bindings::structs::mozilla::css::ErrorReporter;
use gecko_bindings::structs::mozilla::css::ImageValue;
use gecko_bindings::structs::mozilla::css::URLValue;
use gecko_bindings::structs::mozilla::css::URLValueData;
@ -71,6 +72,7 @@ use gecko_bindings::structs::nsChangeHint;
use gecko_bindings::structs::nsCursorImage;
use gecko_bindings::structs::nsFont;
use gecko_bindings::structs::nsIAtom;
use gecko_bindings::structs::nsIURI;
use gecko_bindings::structs::nsCompatibility;
use gecko_bindings::structs::nsMediaFeature;
use gecko_bindings::structs::nsRestyleHint;
@ -591,6 +593,10 @@ extern "C" {
pub fn Gecko_GetDocumentLWTheme(aDocument: *const nsIDocument)
-> nsIDocument_DocumentTheme;
}
extern "C" {
pub fn Gecko_GetDocumentLoader(aPresCtx: RawGeckoPresContextBorrowed)
-> *mut Loader;
}
extern "C" {
pub fn Gecko_AtomAttrValue(element: RawGeckoElementBorrowed,
attribute: *mut nsIAtom) -> *mut nsIAtom;
@ -1956,7 +1962,8 @@ extern "C" {
parent_style:
ServoComputedValuesBorrowedOrNull,
declarations:
RawServoDeclarationBlockBorrowed)
RawServoDeclarationBlockBorrowed,
loader: *mut Loader)
-> ServoComputedValuesStrong;
}
extern "C" {
@ -2161,6 +2168,16 @@ extern "C" {
pub fn Servo_StyleRule_GetSelectorCount(rule: RawServoStyleRuleBorrowed,
count: *mut u32);
}
extern "C" {
pub fn Servo_StyleRule_SelectorMatchesElement(arg1:
RawServoStyleRuleBorrowed,
arg2:
RawGeckoElementBorrowed,
index: u32,
pseudo_type:
CSSPseudoElementType)
-> bool;
}
extern "C" {
pub fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed,
result: *mut nsAString);
@ -2254,7 +2271,8 @@ extern "C" {
value: *const nsACString,
data: *mut RawGeckoURLExtraData,
parsing_mode: ParsingMode,
quirks_mode: nsCompatibility)
quirks_mode: nsCompatibility,
loader: *mut Loader)
-> RawServoDeclarationBlockStrong;
}
extern "C" {
@ -2403,7 +2421,8 @@ extern "C" {
extern "C" {
pub fn Servo_ParseStyleAttribute(data: *const nsACString,
extra_data: *mut RawGeckoURLExtraData,
quirks_mode: nsCompatibility)
quirks_mode: nsCompatibility,
loader: *mut Loader)
-> RawServoDeclarationBlockStrong;
}
extern "C" {
@ -2472,8 +2491,8 @@ extern "C" {
is_important: bool,
data: *mut RawGeckoURLExtraData,
parsing_mode: ParsingMode,
quirks_mode: nsCompatibility)
-> bool;
quirks_mode: nsCompatibility,
loader: *mut Loader) -> bool;
}
extern "C" {
pub fn Servo_DeclarationBlock_SetPropertyById(declarations:
@ -2485,7 +2504,8 @@ extern "C" {
*mut RawGeckoURLExtraData,
parsing_mode: ParsingMode,
quirks_mode:
nsCompatibility)
nsCompatibility,
loader: *mut Loader)
-> bool;
}
extern "C" {
@ -2882,3 +2902,23 @@ extern "C" {
ServoComputedValuesBorrowedOrNull)
-> *const nsStyleEffects;
}
extern "C" {
pub fn Gecko_CreateCSSErrorReporter(sheet: *mut ServoStyleSheet,
loader: *mut Loader)
-> *mut ErrorReporter;
}
extern "C" {
pub fn Gecko_DestroyCSSErrorReporter(reporter: *mut ErrorReporter);
}
extern "C" {
pub fn Gecko_ReportUnexpectedCSSError(reporter: *mut ErrorReporter,
message:
*const ::std::os::raw::c_char,
param:
*const ::std::os::raw::c_char,
paramLen: u32,
source:
*const ::std::os::raw::c_char,
sourceLen: u32, lineNumber: u32,
colNumber: u32, aURI: *mut nsIURI);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -10,6 +10,7 @@ mod non_ts_pseudo_class_list;
pub mod arc_types;
pub mod conversions;
pub mod data;
pub mod error_reporter;
pub mod global_style_data;
pub mod media_queries;
pub mod pseudo_element;

View file

@ -23,7 +23,7 @@ use data::ElementData;
use dom::{self, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
use dom::{OpaqueNode, PresentationalHintsSynthesizer};
use element_state::{ElementState, DocumentState, NS_DOCUMENT_STATE_WINDOW_INACTIVE};
use error_reporting::create_error_reporter;
use error_reporting::ParseErrorReporter;
use font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult};
use gecko::data::PerDocumentStyleData;
use gecko::global_style_data::GLOBAL_STYLE_DATA;
@ -478,8 +478,9 @@ impl<'le> GeckoElement<'le> {
/// Parse the style attribute of an element.
pub fn parse_style_attribute(value: &str,
url_data: &UrlExtraData,
quirks_mode: QuirksMode) -> PropertyDeclarationBlock {
parse_style_attribute(value, url_data, &create_error_reporter(), quirks_mode)
quirks_mode: QuirksMode,
reporter: &ParseErrorReporter) -> PropertyDeclarationBlock {
parse_style_attribute(value, url_data, reporter, quirks_mode)
}
fn flags(&self) -> u32 {

View file

@ -111,16 +111,19 @@ pub struct AnimationValueIterator<'a, 'cx, 'cx_a:'cx> {
iter: Iter<'a, (PropertyDeclaration, Importance)>,
context: &'cx mut Context<'cx_a>,
default_values: &'a Arc<ComputedValues>,
reporter: &'a ParseErrorReporter,
}
impl<'a, 'cx, 'cx_a:'cx> AnimationValueIterator<'a, 'cx, 'cx_a> {
fn new(declarations: &'a PropertyDeclarationBlock,
context: &'cx mut Context<'cx_a>,
default_values: &'a Arc<ComputedValues>) -> AnimationValueIterator<'a, 'cx, 'cx_a> {
default_values: &'a Arc<ComputedValues>,
reporter: &'a ParseErrorReporter) -> AnimationValueIterator<'a, 'cx, 'cx_a> {
AnimationValueIterator {
iter: declarations.declarations().iter(),
context: context,
default_values: default_values,
reporter: reporter
}
}
}
@ -138,7 +141,8 @@ impl<'a, 'cx, 'cx_a:'cx> Iterator for AnimationValueIterator<'a, 'cx, 'cx_a> {
if importance == Importance::Normal {
let property = AnimatableLonghand::from_declaration(decl);
let animation = AnimationValue::from_declaration(decl, &mut self.context,
self.default_values);
self.default_values,
self.reporter);
debug_assert!(property.is_none() == animation.is_none(),
"The failure condition of AnimatableLonghand::from_declaration \
and AnimationValue::from_declaration should be the same");
@ -204,9 +208,10 @@ impl PropertyDeclarationBlock {
/// Return an iterator of (AnimatableLonghand, AnimationValue).
pub fn to_animation_value_iter<'a, 'cx, 'cx_a:'cx>(&'a self,
context: &'cx mut Context<'cx_a>,
default_values: &'a Arc<ComputedValues>)
default_values: &'a Arc<ComputedValues>,
reporter: &'a ParseErrorReporter)
-> AnimationValueIterator<'a, 'cx, 'cx_a> {
AnimationValueIterator::new(self, context, default_values)
AnimationValueIterator::new(self, context, default_values, reporter)
}
/// Returns whether this block contains any declaration with `!important`.

View file

@ -8,6 +8,7 @@
use app_units::Au;
use cssparser::{Parser, RGBA};
use error_reporting::ParseErrorReporter;
use euclid::{Point2D, Size2D};
#[cfg(feature = "gecko")] use gecko_bindings::bindings::RawServoAnimationValueMap;
#[cfg(feature = "gecko")] use gecko_bindings::structs::RawGeckoGfxMatrix4x4;
@ -522,8 +523,8 @@ impl AnimationValue {
/// Construct an AnimationValue from a property declaration
pub fn from_declaration(decl: &PropertyDeclaration, context: &mut Context,
initial: &ComputedValues) -> Option<Self> {
use error_reporting::create_error_reporter;
initial: &ComputedValues,
reporter: &ParseErrorReporter) -> Option<Self> {
use properties::LonghandId;
use properties::DeclaredValue;
@ -587,7 +588,6 @@ impl AnimationValue {
},
PropertyDeclaration::WithVariables(id, ref variables) => {
let custom_props = context.style().custom_properties();
let reporter = create_error_reporter();
match id {
% for prop in data.longhands:
% if prop.animatable:
@ -610,9 +610,13 @@ impl AnimationValue {
},
DeclaredValue::WithVariables(_) => unreachable!(),
};
result = AnimationValue::from_declaration(&declaration, context, initial);
result = AnimationValue::from_declaration(
&declaration,
context,
initial,
reporter);
},
&reporter,
reporter,
quirks_mode);
result
},

View file

@ -10,6 +10,8 @@ use bit_vec::BitVec;
use context::{CascadeInputs, QuirksMode};
use dom::TElement;
use element_state::ElementState;
use error_reporting::ParseErrorReporter;
#[cfg(feature = "servo")]
use error_reporting::create_error_reporter;
use font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")]
@ -597,12 +599,15 @@ impl Stylist {
/// parent; otherwise, non-inherited properties are reset to their initial
/// values. The flow constructor uses this flag when constructing anonymous
/// flows.
///
/// The error reporter is only needed when processing custom variables.
pub fn precomputed_values_for_pseudo(&self,
guards: &StylesheetGuards,
pseudo: &PseudoElement,
parent: Option<&Arc<ComputedValues>>,
cascade_flags: CascadeFlags,
font_metrics: &FontMetricsProvider)
font_metrics: &FontMetricsProvider,
reporter: &ParseErrorReporter)
-> Arc<ComputedValues> {
debug_assert!(pseudo.is_precomputed());
@ -639,7 +644,7 @@ impl Stylist {
parent.map(|p| &**p),
None,
None,
&create_error_reporter(),
reporter,
font_metrics,
cascade_flags,
self.quirks_mode);
@ -680,7 +685,7 @@ impl Stylist {
cascade_flags.insert(INHERIT_ALL);
}
self.precomputed_values_for_pseudo(guards, &pseudo, Some(parent_style), cascade_flags,
&ServoMetricsProvider)
&ServoMetricsProvider, &create_error_reporter())
}
/// Computes a pseudo-element style lazily during layout.
@ -690,6 +695,8 @@ impl Stylist {
///
/// Check the documentation on lazy pseudo-elements in
/// docs/components/style.md
///
/// The error reporter is only required for processing custom variables.
pub fn lazily_compute_pseudo_element_style<E>(&self,
guards: &StylesheetGuards,
element: &E,
@ -697,7 +704,8 @@ impl Stylist {
rule_inclusion: RuleInclusion,
parent_style: &Arc<ComputedValues>,
is_probe: bool,
font_metrics: &FontMetricsProvider)
font_metrics: &FontMetricsProvider,
reporter: &ParseErrorReporter)
-> Option<Arc<ComputedValues>>
where E: TElement,
{
@ -706,18 +714,22 @@ impl Stylist {
self.compute_pseudo_element_style_with_inputs(&cascade_inputs,
guards,
parent_style,
font_metrics)
font_metrics,
reporter)
}
/// Computes a pseudo-element style lazily using the given CascadeInputs.
/// This can be used for truly lazy pseudo-elements or to avoid redoing
/// selector matching for eager pseudo-elements when we need to recompute
/// their style with a new parent style.
///
/// The error reporter is only required for processing custom variables.
pub fn compute_pseudo_element_style_with_inputs(&self,
inputs: &CascadeInputs,
guards: &StylesheetGuards,
parent_style: &Arc<ComputedValues>,
font_metrics: &FontMetricsProvider)
font_metrics: &FontMetricsProvider,
reporter: &ParseErrorReporter)
-> Option<Arc<ComputedValues>>
{
// We may have only visited rules in cases when we are actually
@ -748,7 +760,7 @@ impl Stylist {
Some(inherited_style),
None,
None,
&create_error_reporter(),
reporter,
font_metrics,
CascadeFlags::empty(),
self.quirks_mode);
@ -780,7 +792,7 @@ impl Stylist {
Some(parent_style),
visited_values,
None,
&create_error_reporter(),
reporter,
font_metrics,
CascadeFlags::empty(),
self.quirks_mode);
@ -1342,10 +1354,12 @@ impl Stylist {
}
/// Computes styles for a given declaration with parent_style.
/// The error reporter is only used for processing custom variables.
pub fn compute_for_declarations(&self,
guards: &StylesheetGuards,
parent_style: &Arc<ComputedValues>,
declarations: Arc<Locked<PropertyDeclarationBlock>>)
declarations: Arc<Locked<PropertyDeclarationBlock>>,
reporter: &ParseErrorReporter)
-> Arc<ComputedValues> {
use font_metrics::get_metrics_provider_for_product;
@ -1367,7 +1381,7 @@ impl Stylist {
Some(parent_style),
None,
None,
&create_error_reporter(),
reporter,
&metrics,
CascadeFlags::empty(),
self.quirks_mode))