mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
stylo: Create error reporters linked to documents (bug 1352669)
This commit is contained in:
parent
901525c911
commit
dc2a500f4b
12 changed files with 5713 additions and 4361 deletions
|
@ -415,7 +415,8 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
|
||||||
&style_pseudo,
|
&style_pseudo,
|
||||||
Some(data.styles.primary()),
|
Some(data.styles.primary()),
|
||||||
CascadeFlags::empty(),
|
CascadeFlags::empty(),
|
||||||
&ServoMetricsProvider)
|
&ServoMetricsProvider,
|
||||||
|
context.error_reporter)
|
||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
PseudoElementCascadeType::Lazy => {
|
PseudoElementCascadeType::Lazy => {
|
||||||
|
@ -427,7 +428,8 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
|
||||||
RuleInclusion::All,
|
RuleInclusion::All,
|
||||||
data.styles.primary(),
|
data.styles.primary(),
|
||||||
/* is_probe = */ false,
|
/* is_probe = */ false,
|
||||||
&ServoMetricsProvider)
|
&ServoMetricsProvider,
|
||||||
|
context.error_reporter)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
use cssparser::{Parser, SourcePosition, BasicParseError, Token};
|
use cssparser::{Parser, SourcePosition, BasicParseError, Token};
|
||||||
use cssparser::ParseError as CssParseError;
|
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 log;
|
||||||
use style_traits::ParseError;
|
use style_traits::ParseError;
|
||||||
use stylesheets::UrlExtraData;
|
use stylesheets::UrlExtraData;
|
||||||
|
@ -190,6 +193,15 @@ impl ParseErrorReporter for NullReporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an instance of the default error reporter.
|
/// Create an instance of the default error reporter.
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
pub fn create_error_reporter() -> RustLogReporter {
|
pub fn create_error_reporter() -> RustLogReporter {
|
||||||
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)
|
||||||
|
}
|
||||||
|
|
90
components/style/gecko/error_reporter.rs
Normal file
90
components/style/gecko/error_reporter.rs
Normal 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>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ use gecko_bindings::structs::nsTArray;
|
||||||
type nsACString_internal = nsACString;
|
type nsACString_internal = nsACString;
|
||||||
type nsAString_internal = nsAString;
|
type nsAString_internal = nsAString;
|
||||||
use gecko_bindings::structs::mozilla::css::GridTemplateAreasValue;
|
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::ImageValue;
|
||||||
use gecko_bindings::structs::mozilla::css::URLValue;
|
use gecko_bindings::structs::mozilla::css::URLValue;
|
||||||
use gecko_bindings::structs::mozilla::css::URLValueData;
|
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::nsCursorImage;
|
||||||
use gecko_bindings::structs::nsFont;
|
use gecko_bindings::structs::nsFont;
|
||||||
use gecko_bindings::structs::nsIAtom;
|
use gecko_bindings::structs::nsIAtom;
|
||||||
|
use gecko_bindings::structs::nsIURI;
|
||||||
use gecko_bindings::structs::nsCompatibility;
|
use gecko_bindings::structs::nsCompatibility;
|
||||||
use gecko_bindings::structs::nsMediaFeature;
|
use gecko_bindings::structs::nsMediaFeature;
|
||||||
use gecko_bindings::structs::nsRestyleHint;
|
use gecko_bindings::structs::nsRestyleHint;
|
||||||
|
@ -591,6 +593,10 @@ extern "C" {
|
||||||
pub fn Gecko_GetDocumentLWTheme(aDocument: *const nsIDocument)
|
pub fn Gecko_GetDocumentLWTheme(aDocument: *const nsIDocument)
|
||||||
-> nsIDocument_DocumentTheme;
|
-> nsIDocument_DocumentTheme;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_GetDocumentLoader(aPresCtx: RawGeckoPresContextBorrowed)
|
||||||
|
-> *mut Loader;
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_AtomAttrValue(element: RawGeckoElementBorrowed,
|
pub fn Gecko_AtomAttrValue(element: RawGeckoElementBorrowed,
|
||||||
attribute: *mut nsIAtom) -> *mut nsIAtom;
|
attribute: *mut nsIAtom) -> *mut nsIAtom;
|
||||||
|
@ -1956,7 +1962,8 @@ extern "C" {
|
||||||
parent_style:
|
parent_style:
|
||||||
ServoComputedValuesBorrowedOrNull,
|
ServoComputedValuesBorrowedOrNull,
|
||||||
declarations:
|
declarations:
|
||||||
RawServoDeclarationBlockBorrowed)
|
RawServoDeclarationBlockBorrowed,
|
||||||
|
loader: *mut Loader)
|
||||||
-> ServoComputedValuesStrong;
|
-> ServoComputedValuesStrong;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -2161,6 +2168,16 @@ extern "C" {
|
||||||
pub fn Servo_StyleRule_GetSelectorCount(rule: RawServoStyleRuleBorrowed,
|
pub fn Servo_StyleRule_GetSelectorCount(rule: RawServoStyleRuleBorrowed,
|
||||||
count: *mut u32);
|
count: *mut u32);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Servo_StyleRule_SelectorMatchesElement(arg1:
|
||||||
|
RawServoStyleRuleBorrowed,
|
||||||
|
arg2:
|
||||||
|
RawGeckoElementBorrowed,
|
||||||
|
index: u32,
|
||||||
|
pseudo_type:
|
||||||
|
CSSPseudoElementType)
|
||||||
|
-> bool;
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed,
|
pub fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed,
|
||||||
result: *mut nsAString);
|
result: *mut nsAString);
|
||||||
|
@ -2254,7 +2271,8 @@ extern "C" {
|
||||||
value: *const nsACString,
|
value: *const nsACString,
|
||||||
data: *mut RawGeckoURLExtraData,
|
data: *mut RawGeckoURLExtraData,
|
||||||
parsing_mode: ParsingMode,
|
parsing_mode: ParsingMode,
|
||||||
quirks_mode: nsCompatibility)
|
quirks_mode: nsCompatibility,
|
||||||
|
loader: *mut Loader)
|
||||||
-> RawServoDeclarationBlockStrong;
|
-> RawServoDeclarationBlockStrong;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -2403,7 +2421,8 @@ extern "C" {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_ParseStyleAttribute(data: *const nsACString,
|
pub fn Servo_ParseStyleAttribute(data: *const nsACString,
|
||||||
extra_data: *mut RawGeckoURLExtraData,
|
extra_data: *mut RawGeckoURLExtraData,
|
||||||
quirks_mode: nsCompatibility)
|
quirks_mode: nsCompatibility,
|
||||||
|
loader: *mut Loader)
|
||||||
-> RawServoDeclarationBlockStrong;
|
-> RawServoDeclarationBlockStrong;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -2472,8 +2491,8 @@ extern "C" {
|
||||||
is_important: bool,
|
is_important: bool,
|
||||||
data: *mut RawGeckoURLExtraData,
|
data: *mut RawGeckoURLExtraData,
|
||||||
parsing_mode: ParsingMode,
|
parsing_mode: ParsingMode,
|
||||||
quirks_mode: nsCompatibility)
|
quirks_mode: nsCompatibility,
|
||||||
-> bool;
|
loader: *mut Loader) -> bool;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Servo_DeclarationBlock_SetPropertyById(declarations:
|
pub fn Servo_DeclarationBlock_SetPropertyById(declarations:
|
||||||
|
@ -2485,7 +2504,8 @@ extern "C" {
|
||||||
*mut RawGeckoURLExtraData,
|
*mut RawGeckoURLExtraData,
|
||||||
parsing_mode: ParsingMode,
|
parsing_mode: ParsingMode,
|
||||||
quirks_mode:
|
quirks_mode:
|
||||||
nsCompatibility)
|
nsCompatibility,
|
||||||
|
loader: *mut Loader)
|
||||||
-> bool;
|
-> bool;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -2882,3 +2902,23 @@ extern "C" {
|
||||||
ServoComputedValuesBorrowedOrNull)
|
ServoComputedValuesBorrowedOrNull)
|
||||||
-> *const nsStyleEffects;
|
-> *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
|
@ -10,6 +10,7 @@ mod non_ts_pseudo_class_list;
|
||||||
pub mod arc_types;
|
pub mod arc_types;
|
||||||
pub mod conversions;
|
pub mod conversions;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
|
pub mod error_reporter;
|
||||||
pub mod global_style_data;
|
pub mod global_style_data;
|
||||||
pub mod media_queries;
|
pub mod media_queries;
|
||||||
pub mod pseudo_element;
|
pub mod pseudo_element;
|
||||||
|
|
|
@ -23,7 +23,7 @@ use data::ElementData;
|
||||||
use dom::{self, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
|
use dom::{self, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
|
||||||
use dom::{OpaqueNode, PresentationalHintsSynthesizer};
|
use dom::{OpaqueNode, PresentationalHintsSynthesizer};
|
||||||
use element_state::{ElementState, DocumentState, NS_DOCUMENT_STATE_WINDOW_INACTIVE};
|
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 font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult};
|
||||||
use gecko::data::PerDocumentStyleData;
|
use gecko::data::PerDocumentStyleData;
|
||||||
use gecko::global_style_data::GLOBAL_STYLE_DATA;
|
use gecko::global_style_data::GLOBAL_STYLE_DATA;
|
||||||
|
@ -478,8 +478,9 @@ impl<'le> GeckoElement<'le> {
|
||||||
/// Parse the style attribute of an element.
|
/// Parse the style attribute of an element.
|
||||||
pub fn parse_style_attribute(value: &str,
|
pub fn parse_style_attribute(value: &str,
|
||||||
url_data: &UrlExtraData,
|
url_data: &UrlExtraData,
|
||||||
quirks_mode: QuirksMode) -> PropertyDeclarationBlock {
|
quirks_mode: QuirksMode,
|
||||||
parse_style_attribute(value, url_data, &create_error_reporter(), quirks_mode)
|
reporter: &ParseErrorReporter) -> PropertyDeclarationBlock {
|
||||||
|
parse_style_attribute(value, url_data, reporter, quirks_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flags(&self) -> u32 {
|
fn flags(&self) -> u32 {
|
||||||
|
|
|
@ -111,16 +111,19 @@ pub struct AnimationValueIterator<'a, 'cx, 'cx_a:'cx> {
|
||||||
iter: Iter<'a, (PropertyDeclaration, Importance)>,
|
iter: Iter<'a, (PropertyDeclaration, Importance)>,
|
||||||
context: &'cx mut Context<'cx_a>,
|
context: &'cx mut Context<'cx_a>,
|
||||||
default_values: &'a Arc<ComputedValues>,
|
default_values: &'a Arc<ComputedValues>,
|
||||||
|
reporter: &'a ParseErrorReporter,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'cx, 'cx_a:'cx> AnimationValueIterator<'a, 'cx, 'cx_a> {
|
impl<'a, 'cx, 'cx_a:'cx> AnimationValueIterator<'a, 'cx, 'cx_a> {
|
||||||
fn new(declarations: &'a PropertyDeclarationBlock,
|
fn new(declarations: &'a PropertyDeclarationBlock,
|
||||||
context: &'cx mut Context<'cx_a>,
|
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 {
|
AnimationValueIterator {
|
||||||
iter: declarations.declarations().iter(),
|
iter: declarations.declarations().iter(),
|
||||||
context: context,
|
context: context,
|
||||||
default_values: default_values,
|
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 {
|
if importance == Importance::Normal {
|
||||||
let property = AnimatableLonghand::from_declaration(decl);
|
let property = AnimatableLonghand::from_declaration(decl);
|
||||||
let animation = AnimationValue::from_declaration(decl, &mut self.context,
|
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(),
|
debug_assert!(property.is_none() == animation.is_none(),
|
||||||
"The failure condition of AnimatableLonghand::from_declaration \
|
"The failure condition of AnimatableLonghand::from_declaration \
|
||||||
and AnimationValue::from_declaration should be the same");
|
and AnimationValue::from_declaration should be the same");
|
||||||
|
@ -204,9 +208,10 @@ impl PropertyDeclarationBlock {
|
||||||
/// Return an iterator of (AnimatableLonghand, AnimationValue).
|
/// Return an iterator of (AnimatableLonghand, AnimationValue).
|
||||||
pub fn to_animation_value_iter<'a, 'cx, 'cx_a:'cx>(&'a self,
|
pub fn to_animation_value_iter<'a, 'cx, 'cx_a:'cx>(&'a self,
|
||||||
context: &'cx mut Context<'cx_a>,
|
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<'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`.
|
/// Returns whether this block contains any declaration with `!important`.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use cssparser::{Parser, RGBA};
|
use cssparser::{Parser, RGBA};
|
||||||
|
use error_reporting::ParseErrorReporter;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::{Point2D, Size2D};
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::bindings::RawServoAnimationValueMap;
|
#[cfg(feature = "gecko")] use gecko_bindings::bindings::RawServoAnimationValueMap;
|
||||||
#[cfg(feature = "gecko")] use gecko_bindings::structs::RawGeckoGfxMatrix4x4;
|
#[cfg(feature = "gecko")] use gecko_bindings::structs::RawGeckoGfxMatrix4x4;
|
||||||
|
@ -522,8 +523,8 @@ impl AnimationValue {
|
||||||
|
|
||||||
/// Construct an AnimationValue from a property declaration
|
/// Construct an AnimationValue from a property declaration
|
||||||
pub fn from_declaration(decl: &PropertyDeclaration, context: &mut Context,
|
pub fn from_declaration(decl: &PropertyDeclaration, context: &mut Context,
|
||||||
initial: &ComputedValues) -> Option<Self> {
|
initial: &ComputedValues,
|
||||||
use error_reporting::create_error_reporter;
|
reporter: &ParseErrorReporter) -> Option<Self> {
|
||||||
use properties::LonghandId;
|
use properties::LonghandId;
|
||||||
use properties::DeclaredValue;
|
use properties::DeclaredValue;
|
||||||
|
|
||||||
|
@ -587,7 +588,6 @@ impl AnimationValue {
|
||||||
},
|
},
|
||||||
PropertyDeclaration::WithVariables(id, ref variables) => {
|
PropertyDeclaration::WithVariables(id, ref variables) => {
|
||||||
let custom_props = context.style().custom_properties();
|
let custom_props = context.style().custom_properties();
|
||||||
let reporter = create_error_reporter();
|
|
||||||
match id {
|
match id {
|
||||||
% for prop in data.longhands:
|
% for prop in data.longhands:
|
||||||
% if prop.animatable:
|
% if prop.animatable:
|
||||||
|
@ -610,9 +610,13 @@ impl AnimationValue {
|
||||||
},
|
},
|
||||||
DeclaredValue::WithVariables(_) => unreachable!(),
|
DeclaredValue::WithVariables(_) => unreachable!(),
|
||||||
};
|
};
|
||||||
result = AnimationValue::from_declaration(&declaration, context, initial);
|
result = AnimationValue::from_declaration(
|
||||||
|
&declaration,
|
||||||
|
context,
|
||||||
|
initial,
|
||||||
|
reporter);
|
||||||
},
|
},
|
||||||
&reporter,
|
reporter,
|
||||||
quirks_mode);
|
quirks_mode);
|
||||||
result
|
result
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,6 +10,8 @@ use bit_vec::BitVec;
|
||||||
use context::{CascadeInputs, QuirksMode};
|
use context::{CascadeInputs, QuirksMode};
|
||||||
use dom::TElement;
|
use dom::TElement;
|
||||||
use element_state::ElementState;
|
use element_state::ElementState;
|
||||||
|
use error_reporting::ParseErrorReporter;
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
use error_reporting::create_error_reporter;
|
use error_reporting::create_error_reporter;
|
||||||
use font_metrics::FontMetricsProvider;
|
use font_metrics::FontMetricsProvider;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -597,12 +599,15 @@ impl Stylist {
|
||||||
/// parent; otherwise, non-inherited properties are reset to their initial
|
/// parent; otherwise, non-inherited properties are reset to their initial
|
||||||
/// values. The flow constructor uses this flag when constructing anonymous
|
/// values. The flow constructor uses this flag when constructing anonymous
|
||||||
/// flows.
|
/// flows.
|
||||||
|
///
|
||||||
|
/// The error reporter is only needed when processing custom variables.
|
||||||
pub fn precomputed_values_for_pseudo(&self,
|
pub fn precomputed_values_for_pseudo(&self,
|
||||||
guards: &StylesheetGuards,
|
guards: &StylesheetGuards,
|
||||||
pseudo: &PseudoElement,
|
pseudo: &PseudoElement,
|
||||||
parent: Option<&Arc<ComputedValues>>,
|
parent: Option<&Arc<ComputedValues>>,
|
||||||
cascade_flags: CascadeFlags,
|
cascade_flags: CascadeFlags,
|
||||||
font_metrics: &FontMetricsProvider)
|
font_metrics: &FontMetricsProvider,
|
||||||
|
reporter: &ParseErrorReporter)
|
||||||
-> Arc<ComputedValues> {
|
-> Arc<ComputedValues> {
|
||||||
debug_assert!(pseudo.is_precomputed());
|
debug_assert!(pseudo.is_precomputed());
|
||||||
|
|
||||||
|
@ -639,7 +644,7 @@ impl Stylist {
|
||||||
parent.map(|p| &**p),
|
parent.map(|p| &**p),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
&create_error_reporter(),
|
reporter,
|
||||||
font_metrics,
|
font_metrics,
|
||||||
cascade_flags,
|
cascade_flags,
|
||||||
self.quirks_mode);
|
self.quirks_mode);
|
||||||
|
@ -680,7 +685,7 @@ impl Stylist {
|
||||||
cascade_flags.insert(INHERIT_ALL);
|
cascade_flags.insert(INHERIT_ALL);
|
||||||
}
|
}
|
||||||
self.precomputed_values_for_pseudo(guards, &pseudo, Some(parent_style), cascade_flags,
|
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.
|
/// Computes a pseudo-element style lazily during layout.
|
||||||
|
@ -690,6 +695,8 @@ impl Stylist {
|
||||||
///
|
///
|
||||||
/// Check the documentation on lazy pseudo-elements in
|
/// Check the documentation on lazy pseudo-elements in
|
||||||
/// docs/components/style.md
|
/// docs/components/style.md
|
||||||
|
///
|
||||||
|
/// The error reporter is only required for processing custom variables.
|
||||||
pub fn lazily_compute_pseudo_element_style<E>(&self,
|
pub fn lazily_compute_pseudo_element_style<E>(&self,
|
||||||
guards: &StylesheetGuards,
|
guards: &StylesheetGuards,
|
||||||
element: &E,
|
element: &E,
|
||||||
|
@ -697,7 +704,8 @@ impl Stylist {
|
||||||
rule_inclusion: RuleInclusion,
|
rule_inclusion: RuleInclusion,
|
||||||
parent_style: &Arc<ComputedValues>,
|
parent_style: &Arc<ComputedValues>,
|
||||||
is_probe: bool,
|
is_probe: bool,
|
||||||
font_metrics: &FontMetricsProvider)
|
font_metrics: &FontMetricsProvider,
|
||||||
|
reporter: &ParseErrorReporter)
|
||||||
-> Option<Arc<ComputedValues>>
|
-> Option<Arc<ComputedValues>>
|
||||||
where E: TElement,
|
where E: TElement,
|
||||||
{
|
{
|
||||||
|
@ -706,18 +714,22 @@ impl Stylist {
|
||||||
self.compute_pseudo_element_style_with_inputs(&cascade_inputs,
|
self.compute_pseudo_element_style_with_inputs(&cascade_inputs,
|
||||||
guards,
|
guards,
|
||||||
parent_style,
|
parent_style,
|
||||||
font_metrics)
|
font_metrics,
|
||||||
|
reporter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a pseudo-element style lazily using the given CascadeInputs.
|
/// Computes a pseudo-element style lazily using the given CascadeInputs.
|
||||||
/// This can be used for truly lazy pseudo-elements or to avoid redoing
|
/// This can be used for truly lazy pseudo-elements or to avoid redoing
|
||||||
/// selector matching for eager pseudo-elements when we need to recompute
|
/// selector matching for eager pseudo-elements when we need to recompute
|
||||||
/// their style with a new parent style.
|
/// 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,
|
pub fn compute_pseudo_element_style_with_inputs(&self,
|
||||||
inputs: &CascadeInputs,
|
inputs: &CascadeInputs,
|
||||||
guards: &StylesheetGuards,
|
guards: &StylesheetGuards,
|
||||||
parent_style: &Arc<ComputedValues>,
|
parent_style: &Arc<ComputedValues>,
|
||||||
font_metrics: &FontMetricsProvider)
|
font_metrics: &FontMetricsProvider,
|
||||||
|
reporter: &ParseErrorReporter)
|
||||||
-> Option<Arc<ComputedValues>>
|
-> Option<Arc<ComputedValues>>
|
||||||
{
|
{
|
||||||
// We may have only visited rules in cases when we are actually
|
// We may have only visited rules in cases when we are actually
|
||||||
|
@ -748,7 +760,7 @@ impl Stylist {
|
||||||
Some(inherited_style),
|
Some(inherited_style),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
&create_error_reporter(),
|
reporter,
|
||||||
font_metrics,
|
font_metrics,
|
||||||
CascadeFlags::empty(),
|
CascadeFlags::empty(),
|
||||||
self.quirks_mode);
|
self.quirks_mode);
|
||||||
|
@ -780,7 +792,7 @@ impl Stylist {
|
||||||
Some(parent_style),
|
Some(parent_style),
|
||||||
visited_values,
|
visited_values,
|
||||||
None,
|
None,
|
||||||
&create_error_reporter(),
|
reporter,
|
||||||
font_metrics,
|
font_metrics,
|
||||||
CascadeFlags::empty(),
|
CascadeFlags::empty(),
|
||||||
self.quirks_mode);
|
self.quirks_mode);
|
||||||
|
@ -1342,10 +1354,12 @@ impl Stylist {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes styles for a given declaration with parent_style.
|
/// 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,
|
pub fn compute_for_declarations(&self,
|
||||||
guards: &StylesheetGuards,
|
guards: &StylesheetGuards,
|
||||||
parent_style: &Arc<ComputedValues>,
|
parent_style: &Arc<ComputedValues>,
|
||||||
declarations: Arc<Locked<PropertyDeclarationBlock>>)
|
declarations: Arc<Locked<PropertyDeclarationBlock>>,
|
||||||
|
reporter: &ParseErrorReporter)
|
||||||
-> Arc<ComputedValues> {
|
-> Arc<ComputedValues> {
|
||||||
use font_metrics::get_metrics_provider_for_product;
|
use font_metrics::get_metrics_provider_for_product;
|
||||||
|
|
||||||
|
@ -1367,7 +1381,7 @@ impl Stylist {
|
||||||
Some(parent_style),
|
Some(parent_style),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
&create_error_reporter(),
|
reporter,
|
||||||
&metrics,
|
&metrics,
|
||||||
CascadeFlags::empty(),
|
CascadeFlags::empty(),
|
||||||
self.quirks_mode))
|
self.quirks_mode))
|
||||||
|
|
|
@ -17,7 +17,7 @@ use style::data::{ElementData, ElementStyles, RestyleData};
|
||||||
use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
|
use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
|
||||||
use style::dom::{ShowSubtreeData, TElement, TNode};
|
use style::dom::{ShowSubtreeData, TElement, TNode};
|
||||||
use style::element_state::ElementState;
|
use style::element_state::ElementState;
|
||||||
use style::error_reporting::RustLogReporter;
|
use style::error_reporting::{create_error_reporter, NullReporter, ParseErrorReporter};
|
||||||
use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product};
|
use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product};
|
||||||
use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl};
|
use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl};
|
||||||
use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL};
|
use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL};
|
||||||
|
@ -44,6 +44,7 @@ use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRule
|
||||||
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
|
use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
|
||||||
use style::gecko_bindings::bindings::{nsACString, nsAString, nsCSSPropertyIDSetBorrowedMut};
|
use style::gecko_bindings::bindings::{nsACString, nsAString, nsCSSPropertyIDSetBorrowedMut};
|
||||||
use style::gecko_bindings::bindings::Gecko_AddPropertyToSet;
|
use style::gecko_bindings::bindings::Gecko_AddPropertyToSet;
|
||||||
|
use style::gecko_bindings::bindings::Gecko_GetDocumentLoader;
|
||||||
use style::gecko_bindings::bindings::Gecko_GetOrCreateFinalKeyframe;
|
use style::gecko_bindings::bindings::Gecko_GetOrCreateFinalKeyframe;
|
||||||
use style::gecko_bindings::bindings::Gecko_GetOrCreateInitialKeyframe;
|
use style::gecko_bindings::bindings::Gecko_GetOrCreateInitialKeyframe;
|
||||||
use style::gecko_bindings::bindings::Gecko_GetOrCreateKeyframeAtStart;
|
use style::gecko_bindings::bindings::Gecko_GetOrCreateKeyframeAtStart;
|
||||||
|
@ -172,19 +173,18 @@ unsafe fn dummy_url_data() -> &'static RefPtr<URLExtraData> {
|
||||||
RefPtr::from_ptr_ref(&DUMMY_URL_DATA)
|
RefPtr::from_ptr_ref(&DUMMY_URL_DATA)
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFAULT_ERROR_REPORTER: RustLogReporter = RustLogReporter;
|
|
||||||
|
|
||||||
fn create_shared_context<'a>(global_style_data: &GlobalStyleData,
|
fn create_shared_context<'a>(global_style_data: &GlobalStyleData,
|
||||||
guard: &'a SharedRwLockReadGuard,
|
guard: &'a SharedRwLockReadGuard,
|
||||||
per_doc_data: &'a PerDocumentStyleDataImpl,
|
per_doc_data: &'a PerDocumentStyleDataImpl,
|
||||||
traversal_flags: TraversalFlags,
|
traversal_flags: TraversalFlags,
|
||||||
snapshot_map: &'a ServoElementSnapshotTable)
|
snapshot_map: &'a ServoElementSnapshotTable,
|
||||||
|
reporter: &'a ParseErrorReporter)
|
||||||
-> SharedStyleContext<'a> {
|
-> SharedStyleContext<'a> {
|
||||||
SharedStyleContext {
|
SharedStyleContext {
|
||||||
stylist: &per_doc_data.stylist,
|
stylist: &per_doc_data.stylist,
|
||||||
options: global_style_data.options.clone(),
|
options: global_style_data.options.clone(),
|
||||||
guards: StylesheetGuards::same(guard),
|
guards: StylesheetGuards::same(guard),
|
||||||
error_reporter: &DEFAULT_ERROR_REPORTER,
|
error_reporter: reporter,
|
||||||
timer: Timer::new(),
|
timer: Timer::new(),
|
||||||
quirks_mode: per_doc_data.stylist.quirks_mode(),
|
quirks_mode: per_doc_data.stylist.quirks_mode(),
|
||||||
traversal_flags: traversal_flags,
|
traversal_flags: traversal_flags,
|
||||||
|
@ -192,6 +192,12 @@ fn create_shared_context<'a>(global_style_data: &GlobalStyleData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn loader_from_data(data: &PerDocumentStyleDataImpl) -> *mut Loader {
|
||||||
|
unsafe {
|
||||||
|
Gecko_GetDocumentLoader(data.stylist.device().pres_context())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn traverse_subtree(element: GeckoElement,
|
fn traverse_subtree(element: GeckoElement,
|
||||||
raw_data: RawServoStyleSetBorrowed,
|
raw_data: RawServoStyleSetBorrowed,
|
||||||
traversal_flags: TraversalFlags,
|
traversal_flags: TraversalFlags,
|
||||||
|
@ -210,11 +216,13 @@ fn traverse_subtree(element: GeckoElement,
|
||||||
|
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let guard = global_style_data.shared_lock.read();
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader_from_data(&per_doc_data));
|
||||||
let shared_style_context = create_shared_context(&global_style_data,
|
let shared_style_context = create_shared_context(&global_style_data,
|
||||||
&guard,
|
&guard,
|
||||||
&per_doc_data,
|
&per_doc_data,
|
||||||
traversal_flags,
|
traversal_flags,
|
||||||
snapshots);
|
snapshots,
|
||||||
|
&reporter);
|
||||||
|
|
||||||
|
|
||||||
let token = RecalcStyleOnly::pre_traverse(element,
|
let token = RecalcStyleOnly::pre_traverse(element,
|
||||||
|
@ -666,11 +674,13 @@ pub extern "C" fn Servo_StyleSet_GetBaseComputedValuesForElement(raw_data: RawSe
|
||||||
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let guard = global_style_data.shared_lock.read();
|
let guard = global_style_data.shared_lock.read();
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader_from_data(&doc_data));
|
||||||
let shared_context = create_shared_context(&global_style_data,
|
let shared_context = create_shared_context(&global_style_data,
|
||||||
&guard,
|
&guard,
|
||||||
&doc_data,
|
&doc_data,
|
||||||
TraversalFlags::empty(),
|
TraversalFlags::empty(),
|
||||||
unsafe { &*snapshots });
|
unsafe { &*snapshots },
|
||||||
|
&reporter);
|
||||||
let element = GeckoElement(element);
|
let element = GeckoElement(element);
|
||||||
let element_data = element.borrow_data().unwrap();
|
let element_data = element.borrow_data().unwrap();
|
||||||
let styles = &element_data.styles;
|
let styles = &element_data.styles;
|
||||||
|
@ -755,7 +765,7 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl
|
||||||
origin,
|
origin,
|
||||||
shared_lock,
|
shared_lock,
|
||||||
/* loader = */ None,
|
/* loader = */ None,
|
||||||
&RustLogReporter,
|
&NullReporter,
|
||||||
QuirksMode::NoQuirks,
|
QuirksMode::NoQuirks,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
|
@ -764,7 +774,7 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
|
pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
|
||||||
loader: *mut Loader,
|
css_loader: *mut Loader,
|
||||||
stylesheet: *mut ServoStyleSheet,
|
stylesheet: *mut ServoStyleSheet,
|
||||||
data: *const nsACString,
|
data: *const nsACString,
|
||||||
mode: SheetParsingMode,
|
mode: SheetParsingMode,
|
||||||
|
@ -783,10 +793,10 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
|
||||||
};
|
};
|
||||||
|
|
||||||
let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) };
|
let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) };
|
||||||
let loader = if loader.is_null() {
|
let loader = if css_loader.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(StylesheetLoader::new(loader, stylesheet, ptr::null_mut()))
|
Some(StylesheetLoader::new(css_loader, stylesheet, ptr::null_mut()))
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME(emilio): loader.as_ref() doesn't typecheck for some reason?
|
// FIXME(emilio): loader.as_ref() doesn't typecheck for some reason?
|
||||||
|
@ -798,7 +808,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(
|
||||||
|
|
||||||
Arc::new(StylesheetContents::from_str(
|
Arc::new(StylesheetContents::from_str(
|
||||||
input, url_data.clone(), origin,
|
input, url_data.clone(), origin,
|
||||||
&global_style_data.shared_lock, loader, &RustLogReporter,
|
&global_style_data.shared_lock, loader, &create_error_reporter(stylesheet, css_loader),
|
||||||
quirks_mode.into(), line_number_offset as u64)
|
quirks_mode.into(), line_number_offset as u64)
|
||||||
).into_strong()
|
).into_strong()
|
||||||
}
|
}
|
||||||
|
@ -1486,8 +1496,9 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
|
||||||
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP);
|
cascade_flags.insert(SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP);
|
||||||
}
|
}
|
||||||
let metrics = get_metrics_provider_for_product();
|
let metrics = get_metrics_provider_for_product();
|
||||||
|
let reporter = NullReporter;
|
||||||
data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, maybe_parent,
|
data.stylist.precomputed_values_for_pseudo(&guards, &pseudo, maybe_parent,
|
||||||
cascade_flags, &metrics)
|
cascade_flags, &metrics, &reporter)
|
||||||
.into_strong()
|
.into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,12 +1613,14 @@ fn get_pseudo_style(
|
||||||
Some(styles) => CascadeInputs::new_from_style(styles),
|
Some(styles) => CascadeInputs::new_from_style(styles),
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader_from_data(&doc_data));
|
||||||
doc_data.stylist
|
doc_data.stylist
|
||||||
.compute_pseudo_element_style_with_inputs(
|
.compute_pseudo_element_style_with_inputs(
|
||||||
&inputs,
|
&inputs,
|
||||||
&guards,
|
&guards,
|
||||||
inherited_styles,
|
inherited_styles,
|
||||||
&metrics)
|
&metrics,
|
||||||
|
&reporter)
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
debug_assert!(inherited_styles.is_none() ||
|
debug_assert!(inherited_styles.is_none() ||
|
||||||
|
@ -1629,6 +1642,7 @@ fn get_pseudo_style(
|
||||||
};
|
};
|
||||||
let guards = StylesheetGuards::same(guard);
|
let guards = StylesheetGuards::same(guard);
|
||||||
let metrics = get_metrics_provider_for_product();
|
let metrics = get_metrics_provider_for_product();
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader_from_data(&doc_data));
|
||||||
doc_data.stylist
|
doc_data.stylist
|
||||||
.lazily_compute_pseudo_element_style(
|
.lazily_compute_pseudo_element_style(
|
||||||
&guards,
|
&guards,
|
||||||
|
@ -1637,7 +1651,8 @@ fn get_pseudo_style(
|
||||||
rule_inclusion,
|
rule_inclusion,
|
||||||
base,
|
base,
|
||||||
is_probe,
|
is_probe,
|
||||||
&metrics)
|
&metrics,
|
||||||
|
&reporter)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1750,7 +1765,8 @@ fn parse_property_into(declarations: &mut SourcePropertyDeclaration,
|
||||||
value: *const nsACString,
|
value: *const nsACString,
|
||||||
data: *mut URLExtraData,
|
data: *mut URLExtraData,
|
||||||
parsing_mode: structs::ParsingMode,
|
parsing_mode: structs::ParsingMode,
|
||||||
quirks_mode: QuirksMode) -> Result<(), ()> {
|
quirks_mode: QuirksMode,
|
||||||
|
reporter: &ParseErrorReporter) -> Result<(), ()> {
|
||||||
use style_traits::ParsingMode;
|
use style_traits::ParsingMode;
|
||||||
let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
|
let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
|
||||||
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
|
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
|
||||||
|
@ -1761,7 +1777,7 @@ fn parse_property_into(declarations: &mut SourcePropertyDeclaration,
|
||||||
property_id,
|
property_id,
|
||||||
value,
|
value,
|
||||||
url_data,
|
url_data,
|
||||||
&RustLogReporter,
|
reporter,
|
||||||
parsing_mode,
|
parsing_mode,
|
||||||
quirks_mode)
|
quirks_mode)
|
||||||
}
|
}
|
||||||
|
@ -1770,13 +1786,15 @@ fn parse_property_into(declarations: &mut SourcePropertyDeclaration,
|
||||||
pub extern "C" fn Servo_ParseProperty(property: nsCSSPropertyID, value: *const nsACString,
|
pub extern "C" fn Servo_ParseProperty(property: nsCSSPropertyID, value: *const nsACString,
|
||||||
data: *mut URLExtraData,
|
data: *mut URLExtraData,
|
||||||
parsing_mode: structs::ParsingMode,
|
parsing_mode: structs::ParsingMode,
|
||||||
quirks_mode: nsCompatibility)
|
quirks_mode: nsCompatibility,
|
||||||
|
loader: *mut Loader)
|
||||||
-> RawServoDeclarationBlockStrong {
|
-> RawServoDeclarationBlockStrong {
|
||||||
let id = get_property_id_from_nscsspropertyid!(property,
|
let id = get_property_id_from_nscsspropertyid!(property,
|
||||||
RawServoDeclarationBlockStrong::null());
|
RawServoDeclarationBlockStrong::null());
|
||||||
let mut declarations = SourcePropertyDeclaration::new();
|
let mut declarations = SourcePropertyDeclaration::new();
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader);
|
||||||
match parse_property_into(&mut declarations, id, value, data,
|
match parse_property_into(&mut declarations, id, value, data,
|
||||||
parsing_mode, quirks_mode.into()) {
|
parsing_mode, quirks_mode.into(), &reporter) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let mut block = PropertyDeclarationBlock::new();
|
let mut block = PropertyDeclarationBlock::new();
|
||||||
|
@ -1795,7 +1813,7 @@ pub extern "C" fn Servo_ParseEasing(easing: *const nsAString,
|
||||||
use style::properties::longhands::transition_timing_function;
|
use style::properties::longhands::transition_timing_function;
|
||||||
|
|
||||||
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
|
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
|
||||||
let reporter = RustLogReporter;
|
let reporter = NullReporter;
|
||||||
let context = ParserContext::new(Origin::Author,
|
let context = ParserContext::new(Origin::Author,
|
||||||
url_data,
|
url_data,
|
||||||
&reporter,
|
&reporter,
|
||||||
|
@ -1872,13 +1890,16 @@ pub extern "C" fn Servo_MatrixTransform_Operate(matrix_operator: MatrixTransform
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_ParseStyleAttribute(data: *const nsACString,
|
pub extern "C" fn Servo_ParseStyleAttribute(data: *const nsACString,
|
||||||
raw_extra_data: *mut URLExtraData,
|
raw_extra_data: *mut URLExtraData,
|
||||||
quirks_mode: nsCompatibility)
|
quirks_mode: nsCompatibility,
|
||||||
|
loader: *mut Loader)
|
||||||
-> RawServoDeclarationBlockStrong {
|
-> RawServoDeclarationBlockStrong {
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let value = unsafe { data.as_ref().unwrap().as_str_unchecked() };
|
let value = unsafe { data.as_ref().unwrap().as_str_unchecked() };
|
||||||
let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
|
let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader);
|
||||||
Arc::new(global_style_data.shared_lock.wrap(
|
Arc::new(global_style_data.shared_lock.wrap(
|
||||||
GeckoElement::parse_style_attribute(value, url_data, quirks_mode.into()))).into_strong()
|
GeckoElement::parse_style_attribute(value, url_data, quirks_mode.into(), &reporter)))
|
||||||
|
.into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -2018,10 +2039,12 @@ pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: Ra
|
||||||
fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId,
|
fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId,
|
||||||
value: *const nsACString, is_important: bool, data: *mut URLExtraData,
|
value: *const nsACString, is_important: bool, data: *mut URLExtraData,
|
||||||
parsing_mode: structs::ParsingMode,
|
parsing_mode: structs::ParsingMode,
|
||||||
quirks_mode: QuirksMode) -> bool {
|
quirks_mode: QuirksMode,
|
||||||
|
loader: *mut Loader) -> bool {
|
||||||
let mut source_declarations = SourcePropertyDeclaration::new();
|
let mut source_declarations = SourcePropertyDeclaration::new();
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader);
|
||||||
match parse_property_into(&mut source_declarations, property_id, value, data,
|
match parse_property_into(&mut source_declarations, property_id, value, data,
|
||||||
parsing_mode, quirks_mode) {
|
parsing_mode, quirks_mode, &reporter) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let importance = if is_important { Importance::Important } else { Importance::Normal };
|
let importance = if is_important { Importance::Important } else { Importance::Normal };
|
||||||
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
||||||
|
@ -2037,9 +2060,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDecla
|
||||||
property: *const nsACString, value: *const nsACString,
|
property: *const nsACString, value: *const nsACString,
|
||||||
is_important: bool, data: *mut URLExtraData,
|
is_important: bool, data: *mut URLExtraData,
|
||||||
parsing_mode: structs::ParsingMode,
|
parsing_mode: structs::ParsingMode,
|
||||||
quirks_mode: nsCompatibility) -> bool {
|
quirks_mode: nsCompatibility,
|
||||||
|
loader: *mut Loader) -> bool {
|
||||||
set_property(declarations, get_property_id_from_property!(property, false),
|
set_property(declarations, get_property_id_from_property!(property, false),
|
||||||
value, is_important, data, parsing_mode, quirks_mode.into())
|
value, is_important, data, parsing_mode, quirks_mode.into(), loader)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -2047,9 +2071,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetPropertyById(declarations: RawServoD
|
||||||
property: nsCSSPropertyID, value: *const nsACString,
|
property: nsCSSPropertyID, value: *const nsACString,
|
||||||
is_important: bool, data: *mut URLExtraData,
|
is_important: bool, data: *mut URLExtraData,
|
||||||
parsing_mode: structs::ParsingMode,
|
parsing_mode: structs::ParsingMode,
|
||||||
quirks_mode: nsCompatibility) -> bool {
|
quirks_mode: nsCompatibility,
|
||||||
|
loader: *mut Loader) -> bool {
|
||||||
set_property(declarations, get_property_id_from_nscsspropertyid!(property, false),
|
set_property(declarations, get_property_id_from_nscsspropertyid!(property, false),
|
||||||
value, is_important, data, parsing_mode, quirks_mode.into())
|
value, is_important, data, parsing_mode, quirks_mode.into(), loader)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) {
|
fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) {
|
||||||
|
@ -2117,7 +2142,7 @@ pub extern "C" fn Servo_MediaList_SetText(list: RawServoMediaListBorrowed, text:
|
||||||
let mut input = ParserInput::new(&text);
|
let mut input = ParserInput::new(&text);
|
||||||
let mut parser = Parser::new(&mut input);
|
let mut parser = Parser::new(&mut input);
|
||||||
let url_data = unsafe { dummy_url_data() };
|
let url_data = unsafe { dummy_url_data() };
|
||||||
let reporter = RustLogReporter;
|
let reporter = NullReporter;
|
||||||
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
||||||
PARSING_MODE_DEFAULT,
|
PARSING_MODE_DEFAULT,
|
||||||
QuirksMode::NoQuirks);
|
QuirksMode::NoQuirks);
|
||||||
|
@ -2149,7 +2174,7 @@ pub extern "C" fn Servo_MediaList_AppendMedium(list: RawServoMediaListBorrowed,
|
||||||
new_medium: *const nsACString) {
|
new_medium: *const nsACString) {
|
||||||
let new_medium = unsafe { new_medium.as_ref().unwrap().as_str_unchecked() };
|
let new_medium = unsafe { new_medium.as_ref().unwrap().as_str_unchecked() };
|
||||||
let url_data = unsafe { dummy_url_data() };
|
let url_data = unsafe { dummy_url_data() };
|
||||||
let reporter = RustLogReporter;
|
let reporter = NullReporter;
|
||||||
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
||||||
PARSING_MODE_DEFAULT,
|
PARSING_MODE_DEFAULT,
|
||||||
QuirksMode::NoQuirks);
|
QuirksMode::NoQuirks);
|
||||||
|
@ -2163,7 +2188,7 @@ pub extern "C" fn Servo_MediaList_DeleteMedium(list: RawServoMediaListBorrowed,
|
||||||
old_medium: *const nsACString) -> bool {
|
old_medium: *const nsACString) -> bool {
|
||||||
let old_medium = unsafe { old_medium.as_ref().unwrap().as_str_unchecked() };
|
let old_medium = unsafe { old_medium.as_ref().unwrap().as_str_unchecked() };
|
||||||
let url_data = unsafe { dummy_url_data() };
|
let url_data = unsafe { dummy_url_data() };
|
||||||
let reporter = RustLogReporter;
|
let reporter = NullReporter;
|
||||||
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
|
||||||
PARSING_MODE_DEFAULT,
|
PARSING_MODE_DEFAULT,
|
||||||
QuirksMode::NoQuirks);
|
QuirksMode::NoQuirks);
|
||||||
|
@ -2529,7 +2554,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage(declarations:
|
||||||
|
|
||||||
let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
|
let url_data = unsafe { RefPtr::from_ptr_ref(&raw_extra_data) };
|
||||||
let string = unsafe { (*value).to_string() };
|
let string = unsafe { (*value).to_string() };
|
||||||
let error_reporter = RustLogReporter;
|
let error_reporter = NullReporter;
|
||||||
let context = ParserContext::new(Origin::Author, url_data, &error_reporter,
|
let context = ParserContext::new(Origin::Author, url_data, &error_reporter,
|
||||||
Some(CssRuleType::Style), PARSING_MODE_DEFAULT,
|
Some(CssRuleType::Style), PARSING_MODE_DEFAULT,
|
||||||
QuirksMode::NoQuirks);
|
QuirksMode::NoQuirks);
|
||||||
|
@ -2570,7 +2595,8 @@ pub extern "C" fn Servo_CSSSupports2(property: *const nsACString,
|
||||||
value,
|
value,
|
||||||
unsafe { DUMMY_URL_DATA },
|
unsafe { DUMMY_URL_DATA },
|
||||||
structs::ParsingMode_Default,
|
structs::ParsingMode_Default,
|
||||||
QuirksMode::NoQuirks
|
QuirksMode::NoQuirks,
|
||||||
|
&NullReporter,
|
||||||
).is_ok()
|
).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2582,7 +2608,7 @@ pub extern "C" fn Servo_CSSSupports(cond: *const nsACString) -> bool {
|
||||||
let cond = input.parse_entirely(|i| parse_condition_or_declaration(i));
|
let cond = input.parse_entirely(|i| parse_condition_or_declaration(i));
|
||||||
if let Ok(cond) = cond {
|
if let Ok(cond) = cond {
|
||||||
let url_data = unsafe { dummy_url_data() };
|
let url_data = unsafe { dummy_url_data() };
|
||||||
let reporter = RustLogReporter;
|
let reporter = NullReporter;
|
||||||
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Style),
|
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Style),
|
||||||
PARSING_MODE_DEFAULT,
|
PARSING_MODE_DEFAULT,
|
||||||
QuirksMode::NoQuirks);
|
QuirksMode::NoQuirks);
|
||||||
|
@ -2772,11 +2798,13 @@ pub extern "C" fn Servo_ResolveStyleLazily(element: RawGeckoElementBorrowed,
|
||||||
|
|
||||||
// We don't have the style ready. Go ahead and compute it as necessary.
|
// We don't have the style ready. Go ahead and compute it as necessary.
|
||||||
let mut result = None;
|
let mut result = None;
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader_from_data(&data));
|
||||||
let shared = create_shared_context(&global_style_data,
|
let shared = create_shared_context(&global_style_data,
|
||||||
&guard,
|
&guard,
|
||||||
&data,
|
&data,
|
||||||
traversal_flags,
|
traversal_flags,
|
||||||
unsafe { &*snapshots });
|
unsafe { &*snapshots },
|
||||||
|
&reporter);
|
||||||
let mut tlc = ThreadLocalStyleContext::new(&shared);
|
let mut tlc = ThreadLocalStyleContext::new(&shared);
|
||||||
let mut context = StyleContext {
|
let mut context = StyleContext {
|
||||||
shared: &shared,
|
shared: &shared,
|
||||||
|
@ -2857,6 +2885,8 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
|
||||||
let guard = global_style_data.shared_lock.read();
|
let guard = global_style_data.shared_lock.read();
|
||||||
let default_values = data.default_computed_values();
|
let default_values = data.default_computed_values();
|
||||||
|
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader_from_data(&data));
|
||||||
|
|
||||||
for (index, keyframe) in keyframes.iter().enumerate() {
|
for (index, keyframe) in keyframes.iter().enumerate() {
|
||||||
let ref mut animation_values = computed_keyframes[index];
|
let ref mut animation_values = computed_keyframes[index];
|
||||||
|
|
||||||
|
@ -2875,7 +2905,7 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
|
||||||
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let guard = declarations.read_with(&guard);
|
let guard = declarations.read_with(&guard);
|
||||||
|
|
||||||
for anim in guard.to_animation_value_iter(&mut context, &default_values) {
|
for anim in guard.to_animation_value_iter(&mut context, &default_values, &reporter) {
|
||||||
if !seen.has_animatable_longhand_bit(&anim.0) {
|
if !seen.has_animatable_longhand_bit(&anim.0) {
|
||||||
// This is safe since we immediately write to the uninitialized values.
|
// This is safe since we immediately write to the uninitialized values.
|
||||||
unsafe { animation_values.set_len((property_index + 1) as u32) };
|
unsafe { animation_values.set_len((property_index + 1) as u32) };
|
||||||
|
@ -2916,7 +2946,10 @@ pub extern "C" fn Servo_GetAnimationValues(declarations: RawServoDeclarationBloc
|
||||||
|
|
||||||
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
let guard = declarations.read_with(&guard);
|
let guard = declarations.read_with(&guard);
|
||||||
for (index, anim) in guard.to_animation_value_iter(&mut context, &default_values).enumerate() {
|
let reporter = create_error_reporter(ptr::null_mut(), loader_from_data(&data));
|
||||||
|
for (index, anim) in guard.to_animation_value_iter(&mut context,
|
||||||
|
&default_values,
|
||||||
|
&reporter).enumerate() {
|
||||||
unsafe { animation_values.set_len((index + 1) as u32) };
|
unsafe { animation_values.set_len((index + 1) as u32) };
|
||||||
animation_values[index].set_arc_leaky(Arc::new(anim.1));
|
animation_values[index].set_arc_leaky(Arc::new(anim.1));
|
||||||
}
|
}
|
||||||
|
@ -2943,10 +2976,14 @@ pub extern "C" fn Servo_AnimationValue_Compute(element: RawGeckoElementBorrowed,
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
let guard = global_style_data.shared_lock.read();
|
let guard = global_style_data.shared_lock.read();
|
||||||
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader_from_data(&data));
|
||||||
// We only compute the first element in declarations.
|
// We only compute the first element in declarations.
|
||||||
match declarations.read_with(&guard).declarations().first() {
|
match declarations.read_with(&guard).declarations().first() {
|
||||||
Some(&(ref decl, imp)) if imp == Importance::Normal => {
|
Some(&(ref decl, imp)) if imp == Importance::Normal => {
|
||||||
let animation = AnimationValue::from_declaration(decl, &mut context, default_values);
|
let animation = AnimationValue::from_declaration(decl,
|
||||||
|
&mut context,
|
||||||
|
default_values,
|
||||||
|
&reporter);
|
||||||
animation.map_or(RawServoAnimationValueStrong::null(), |value| {
|
animation.map_or(RawServoAnimationValueStrong::null(), |value| {
|
||||||
Arc::new(value).into_strong()
|
Arc::new(value).into_strong()
|
||||||
})
|
})
|
||||||
|
@ -3200,7 +3237,8 @@ pub extern "C" fn Servo_StyleSet_GetCounterStyleRule(raw_data: RawServoStyleSetB
|
||||||
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(
|
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(
|
||||||
raw_data: RawServoStyleSetBorrowed,
|
raw_data: RawServoStyleSetBorrowed,
|
||||||
parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
||||||
declarations: RawServoDeclarationBlockBorrowed
|
declarations: RawServoDeclarationBlockBorrowed,
|
||||||
|
loader: *mut Loader
|
||||||
) -> ServoComputedValuesStrong {
|
) -> ServoComputedValuesStrong {
|
||||||
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
let doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||||
|
@ -3214,9 +3252,11 @@ pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(
|
||||||
|
|
||||||
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
|
||||||
|
|
||||||
|
let reporter = create_error_reporter(ptr::null_mut(), loader);
|
||||||
doc_data.stylist.compute_for_declarations(&guards,
|
doc_data.stylist.compute_for_declarations(&guards,
|
||||||
parent_style,
|
parent_style,
|
||||||
declarations.clone()).into_strong()
|
declarations.clone(),
|
||||||
|
&reporter).into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue