mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 05:15:45 +00:00
Bug 1466963: Provide a before-mutation closure to C++. r=xidorn,smaug
MozReview-Commit-ID: H2jwIeZoiBZ
This commit is contained in:
parent
f33e5c0e87
commit
0fbd75e65f
@ -2663,7 +2663,8 @@ CreateDeclarationForServo(nsCSSPropertyID aProperty,
|
||||
data,
|
||||
ParsingMode::Default,
|
||||
aDocument->GetCompatibilityMode(),
|
||||
aDocument->CSSLoader());
|
||||
aDocument->CSSLoader(),
|
||||
{ });
|
||||
}
|
||||
|
||||
return servoDeclarations.forget();
|
||||
|
@ -1202,7 +1202,8 @@ MappedAttrParser::ParseMappedAttrValue(nsAtom* aMappedAttrName,
|
||||
mElement->NodePrincipal());
|
||||
changed = Servo_DeclarationBlock_SetPropertyById(
|
||||
mDecl->Raw(), propertyID, &value, false, data,
|
||||
ParsingMode::AllowUnitlessLength, mElement->OwnerDoc()->GetCompatibilityMode(), mLoader);
|
||||
ParsingMode::AllowUnitlessLength,
|
||||
mElement->OwnerDoc()->GetCompatibilityMode(), mLoader, { });
|
||||
|
||||
if (changed) {
|
||||
// The normal reporting of use counters by the nsCSSParser won't happen
|
||||
|
@ -207,18 +207,20 @@ public:
|
||||
}
|
||||
|
||||
// Returns whether the property was removed.
|
||||
bool RemoveProperty(const nsAString& aProperty)
|
||||
bool RemoveProperty(const nsAString& aProperty,
|
||||
DeclarationBlockMutationClosure aClosure = { })
|
||||
{
|
||||
AssertMutable();
|
||||
NS_ConvertUTF16toUTF8 property(aProperty);
|
||||
return Servo_DeclarationBlock_RemoveProperty(mRaw, &property);
|
||||
return Servo_DeclarationBlock_RemoveProperty(mRaw, &property, aClosure);
|
||||
}
|
||||
|
||||
// Returns whether the property was removed.
|
||||
bool RemovePropertyByID(nsCSSPropertyID aProperty)
|
||||
bool RemovePropertyByID(nsCSSPropertyID aProperty,
|
||||
DeclarationBlockMutationClosure aClosure = { })
|
||||
{
|
||||
AssertMutable();
|
||||
return Servo_DeclarationBlock_RemovePropertyById(mRaw, aProperty);
|
||||
return Servo_DeclarationBlock_RemovePropertyById(mRaw, aProperty, aClosure);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -510,6 +510,12 @@ SERVO_BINDING_FUNC(Servo_AnimationValue_Compute,
|
||||
ComputedStyleBorrowed style,
|
||||
RawServoStyleSetBorrowed raw_data)
|
||||
|
||||
// There's no reason we couldn't expose more stuff here, but GetCssText is
|
||||
// pretty much all we'd ever want.
|
||||
SERVO_BINDING_FUNC(Servo_UnlockedDeclarationBlock_GetCssText, void,
|
||||
const RawServoUnlockedDeclarationBlock* declarations,
|
||||
nsAString* result)
|
||||
|
||||
// Style attribute
|
||||
SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
|
||||
const nsACString* data,
|
||||
@ -552,7 +558,8 @@ SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetProperty, bool,
|
||||
RawGeckoURLExtraData* data,
|
||||
mozilla::ParsingMode parsing_mode,
|
||||
nsCompatibility quirks_mode,
|
||||
mozilla::css::Loader* loader)
|
||||
mozilla::css::Loader* loader,
|
||||
DeclarationBlockMutationClosure)
|
||||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetPropertyToAnimationValue, bool,
|
||||
RawServoDeclarationBlockBorrowed declarations,
|
||||
RawServoAnimationValueBorrowed animation_value)
|
||||
@ -563,13 +570,16 @@ SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetPropertyById, bool,
|
||||
RawGeckoURLExtraData* data,
|
||||
mozilla::ParsingMode parsing_mode,
|
||||
nsCompatibility quirks_mode,
|
||||
mozilla::css::Loader* loader)
|
||||
mozilla::css::Loader* loader,
|
||||
DeclarationBlockMutationClosure)
|
||||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemoveProperty, bool,
|
||||
RawServoDeclarationBlockBorrowed declarations,
|
||||
const nsACString* property)
|
||||
const nsACString* property,
|
||||
DeclarationBlockMutationClosure)
|
||||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemovePropertyById, bool,
|
||||
RawServoDeclarationBlockBorrowed declarations,
|
||||
nsCSSPropertyID property)
|
||||
nsCSSPropertyID property,
|
||||
DeclarationBlockMutationClosure)
|
||||
SERVO_BINDING_FUNC(Servo_DeclarationBlock_HasCSSWideKeyword, bool,
|
||||
RawServoDeclarationBlockBorrowed declarations,
|
||||
nsCSSPropertyID property)
|
||||
|
@ -83,6 +83,22 @@ typedef nsTArray<nsCSSPropertyID> RawGeckoCSSPropertyIDList;
|
||||
typedef mozilla::gfx::Float RawGeckoGfxMatrix4x4[16];
|
||||
typedef mozilla::dom::StyleChildrenIterator RawGeckoStyleChildrenIterator;
|
||||
|
||||
// A struct which to be used as an opaque pointer to a DeclarationBlock that has
|
||||
// been read.
|
||||
//
|
||||
// This is effectively a *const PropertyDeclarationBlock in Rust.
|
||||
struct RawServoUnlockedDeclarationBlock;
|
||||
|
||||
// A callback that can be sent via FFI which will be invoked _right before_
|
||||
// being mutated, and at most once.
|
||||
struct DeclarationBlockMutationClosure
|
||||
{
|
||||
// The callback function, first argument is the unlocked servo declaration
|
||||
// block, second is `data`.
|
||||
void (*function)(const RawServoUnlockedDeclarationBlock*, void*) = nullptr;
|
||||
void* data = nullptr;
|
||||
};
|
||||
|
||||
// We have these helper types so that we can directly generate
|
||||
// things like &T or Borrowed<T> on the Rust side in the function, providing
|
||||
// additional safety benefits.
|
||||
@ -136,7 +152,7 @@ struct MOZ_MUST_USE_TYPE ComputedStyleStrong
|
||||
DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR(type_)
|
||||
|
||||
// This is a reference to a reference of RawServoDeclarationBlock, which
|
||||
// corresponds to Option<&Arc<RawServoDeclarationBlock>> in Servo side.
|
||||
// corresponds to Option<&Arc<Locked<RawServoDeclarationBlock>>> in Servo side.
|
||||
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoDeclarationBlockStrong)
|
||||
DECL_OWNED_REF_TYPE_FOR(RawServoAuthorStyles)
|
||||
DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawServoAuthorStyles)
|
||||
|
@ -210,6 +210,7 @@ whitelist-vars = [
|
||||
]
|
||||
whitelist-types = [
|
||||
"RawGecko.*",
|
||||
"DeclarationBlockMutationClosure",
|
||||
"mozilla::AnimationPropertySegment",
|
||||
"mozilla::AnonymousCounterStyle",
|
||||
"mozilla::AtomArray",
|
||||
@ -465,6 +466,8 @@ structs-types = [
|
||||
"mozilla::OriginFlags",
|
||||
"mozilla::UniquePtr",
|
||||
"ServoRawOffsetArc",
|
||||
"DeclarationBlockMutationClosure",
|
||||
"RawServoUnlockedDeclarationBlock",
|
||||
"nsIContent",
|
||||
"nsINode",
|
||||
"nsIDocument",
|
||||
|
@ -290,7 +290,7 @@ nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSPropertyID aPropID,
|
||||
NS_ConvertUTF16toUTF8 value(aPropValue);
|
||||
return Servo_DeclarationBlock_SetPropertyById(
|
||||
decl->Raw(), aPropID, &value, aIsImportant, env.mUrlExtraData,
|
||||
ParsingMode::Default, env.mCompatMode, env.mLoader);
|
||||
ParsingMode::Default, env.mCompatMode, env.mLoader, /* aClosure = */ { });
|
||||
});
|
||||
}
|
||||
|
||||
@ -308,7 +308,7 @@ nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName,
|
||||
NS_ConvertUTF16toUTF8 value(aPropValue);
|
||||
return Servo_DeclarationBlock_SetProperty(
|
||||
decl->Raw(), &property, &value, aIsImportant, env.mUrlExtraData,
|
||||
ParsingMode::Default, env.mCompatMode, env.mLoader);
|
||||
ParsingMode::Default, env.mCompatMode, env.mLoader, /* aClosure = */ { });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,8 @@ static void ServoSetPropertyByIdBench(const nsACString& css) {
|
||||
data,
|
||||
ParsingMode::Default,
|
||||
eCompatibility_FullStandards,
|
||||
nullptr
|
||||
nullptr,
|
||||
{ }
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -81,7 +82,8 @@ static void ServoGetPropertyValueById() {
|
||||
data,
|
||||
ParsingMode::Default,
|
||||
eCompatibility_FullStandards,
|
||||
nullptr
|
||||
nullptr,
|
||||
{ }
|
||||
);
|
||||
|
||||
for (int i = 0; i < GETPROPERTY_REPETITIONS; i++) {
|
||||
|
@ -89,7 +89,7 @@ use style::gecko_bindings::bindings::nsTimingFunctionBorrowed;
|
||||
use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
|
||||
use style::gecko_bindings::structs;
|
||||
use style::gecko_bindings::structs::{CallerType, CSSPseudoElementType, CompositeOperation};
|
||||
use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets};
|
||||
use style::gecko_bindings::structs::{DeclarationBlockMutationClosure, Loader, LoaderReusableStyleSheets};
|
||||
use style::gecko_bindings::structs::{RawServoStyleRule, ComputedStyleStrong, RustString};
|
||||
use style::gecko_bindings::structs::{SheetParsingMode, nsAtom, nsCSSPropertyID};
|
||||
use style::gecko_bindings::structs::{StyleSheet as DomStyleSheet, SheetLoadData, SheetLoadDataHolder};
|
||||
@ -166,6 +166,21 @@ use style_traits::{CssType, CssWriter, ParsingMode, StyleParseErrorKind, ToCss};
|
||||
use super::error_reporter::ErrorReporter;
|
||||
use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader};
|
||||
|
||||
trait ClosureHelper {
|
||||
fn invoke(&self, decls: &PropertyDeclarationBlock);
|
||||
}
|
||||
|
||||
impl ClosureHelper for DeclarationBlockMutationClosure {
|
||||
#[inline]
|
||||
fn invoke(&self, decls: &PropertyDeclarationBlock) {
|
||||
if let Some(function) = self.function.as_ref() {
|
||||
unsafe {
|
||||
function(decls as *const _ as *const _, self.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For Gecko->Servo function calls, we need to redeclare the same signature that was declared in
|
||||
* the C header in Gecko. In order to catch accidental mismatches, we run rust-bindgen against
|
||||
@ -3394,13 +3409,25 @@ pub extern "C" fn Servo_DeclarationBlock_Equals(
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclarationBlockBorrowed,
|
||||
result: *mut nsAString) {
|
||||
pub unsafe extern "C" fn Servo_DeclarationBlock_GetCssText(
|
||||
declarations: RawServoDeclarationBlockBorrowed,
|
||||
result: *mut nsAString,
|
||||
) {
|
||||
read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| {
|
||||
decls.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
|
||||
decls.to_css(&mut *result).unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn Servo_UnlockedDeclarationBlock_GetCssText(
|
||||
declarations: *const structs::RawServoUnlockedDeclarationBlock,
|
||||
result: *mut nsAString,
|
||||
) {
|
||||
let decls = &*(declarations as *const PropertyDeclarationBlock);
|
||||
decls.to_css(&mut *result).unwrap()
|
||||
}
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue(
|
||||
declarations: RawServoDeclarationBlockBorrowed,
|
||||
@ -3529,24 +3556,34 @@ fn set_property(
|
||||
data: *mut URLExtraData,
|
||||
parsing_mode: structs::ParsingMode,
|
||||
quirks_mode: QuirksMode,
|
||||
loader: *mut Loader
|
||||
loader: *mut Loader,
|
||||
before_change_closure: DeclarationBlockMutationClosure,
|
||||
) -> bool {
|
||||
let mut source_declarations = SourcePropertyDeclaration::new();
|
||||
let reporter = ErrorReporter::new(ptr::null_mut(), loader, data);
|
||||
match parse_property_into(&mut source_declarations, property_id, value, data,
|
||||
parsing_mode, quirks_mode, &reporter) {
|
||||
Ok(()) => {
|
||||
let importance = if is_important { Importance::Important } else { Importance::Normal };
|
||||
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
||||
decls.extend(
|
||||
source_declarations.drain(),
|
||||
importance,
|
||||
DeclarationSource::CssOm
|
||||
)
|
||||
})
|
||||
},
|
||||
Err(_) => false,
|
||||
let result = parse_property_into(
|
||||
&mut source_declarations,
|
||||
property_id,
|
||||
value,
|
||||
data,
|
||||
parsing_mode,
|
||||
quirks_mode,
|
||||
&reporter,
|
||||
);
|
||||
|
||||
if result.is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let importance = if is_important { Importance::Important } else { Importance::Normal };
|
||||
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
||||
before_change_closure.invoke(&*decls);
|
||||
decls.extend(
|
||||
source_declarations.drain(),
|
||||
importance,
|
||||
DeclarationSource::CssOm
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -3559,6 +3596,7 @@ pub unsafe extern "C" fn Servo_DeclarationBlock_SetProperty(
|
||||
parsing_mode: structs::ParsingMode,
|
||||
quirks_mode: nsCompatibility,
|
||||
loader: *mut Loader,
|
||||
before_change_closure: DeclarationBlockMutationClosure,
|
||||
) -> bool {
|
||||
set_property(
|
||||
declarations,
|
||||
@ -3569,6 +3607,7 @@ pub unsafe extern "C" fn Servo_DeclarationBlock_SetProperty(
|
||||
parsing_mode,
|
||||
quirks_mode.into(),
|
||||
loader,
|
||||
before_change_closure,
|
||||
)
|
||||
}
|
||||
|
||||
@ -3596,6 +3635,7 @@ pub unsafe extern "C" fn Servo_DeclarationBlock_SetPropertyById(
|
||||
parsing_mode: structs::ParsingMode,
|
||||
quirks_mode: nsCompatibility,
|
||||
loader: *mut Loader,
|
||||
before_change_closure: DeclarationBlockMutationClosure,
|
||||
) -> bool {
|
||||
set_property(
|
||||
declarations,
|
||||
@ -3606,15 +3646,19 @@ pub unsafe extern "C" fn Servo_DeclarationBlock_SetPropertyById(
|
||||
parsing_mode,
|
||||
quirks_mode.into(),
|
||||
loader,
|
||||
before_change_closure,
|
||||
)
|
||||
}
|
||||
|
||||
fn remove_property(
|
||||
declarations: RawServoDeclarationBlockBorrowed,
|
||||
property_id: PropertyId
|
||||
property_id: PropertyId,
|
||||
before_change_closure: DeclarationBlockMutationClosure,
|
||||
) -> bool {
|
||||
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
||||
decls.remove_property(&property_id, |_| {})
|
||||
decls.remove_property(&property_id, |decls| {
|
||||
before_change_closure.invoke(decls)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -3622,16 +3666,26 @@ fn remove_property(
|
||||
pub unsafe extern "C" fn Servo_DeclarationBlock_RemoveProperty(
|
||||
declarations: RawServoDeclarationBlockBorrowed,
|
||||
property: *const nsACString,
|
||||
before_change_closure: DeclarationBlockMutationClosure,
|
||||
) -> bool {
|
||||
remove_property(declarations, get_property_id_from_property!(property, false))
|
||||
remove_property(
|
||||
declarations,
|
||||
get_property_id_from_property!(property, false),
|
||||
before_change_closure,
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_DeclarationBlock_RemovePropertyById(
|
||||
declarations: RawServoDeclarationBlockBorrowed,
|
||||
property: nsCSSPropertyID
|
||||
property: nsCSSPropertyID,
|
||||
before_change_closure: DeclarationBlockMutationClosure,
|
||||
) -> bool {
|
||||
remove_property(declarations, get_property_id_from_nscsspropertyid!(property, false))
|
||||
remove_property(
|
||||
declarations,
|
||||
get_property_id_from_nscsspropertyid!(property, false),
|
||||
before_change_closure,
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
Loading…
Reference in New Issue
Block a user