Bug 1294299 part 12 - Implemnet setter of properties. r=SimonSapin,heycam
MozReview-Commit-ID: 4tGUowsn6AK
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -85,16 +85,20 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
RawServoDeclarationBlockBorrowed declarations,
uint32_t index, nsAString* result)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetPropertyValue, void,
RawServoDeclarationBlockBorrowed declarations,
nsIAtom* property, bool is_custom, nsAString* value)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetPropertyIsImportant, bool,
RawServoDeclarationBlockBorrowed declarations,
nsIAtom* property, bool is_custom)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetProperty, bool,
+ RawServoDeclarationBlockBorrowed declarations,
+ nsIAtom* property, bool is_custom,
+ nsACString* value, bool is_important)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemoveProperty, void,
RawServoDeclarationBlockBorrowed declarations,
nsIAtom* property, bool is_custom)
// CSS supports()
SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
const nsACString* name, const nsACString* value)
--- a/layout/style/ServoDeclarationBlock.h
+++ b/layout/style/ServoDeclarationBlock.h
@@ -21,16 +21,17 @@ public:
: DeclarationBlock(aCopy)
, mRaw(Servo_DeclarationBlock_Clone(aCopy.mRaw).Consume()) {}
NS_INLINE_DECL_REFCOUNTING(ServoDeclarationBlock)
static already_AddRefed<ServoDeclarationBlock>
FromCssText(const nsAString& aCssText);
+ RawServoDeclarationBlock* Raw() const { return mRaw; }
RawServoDeclarationBlock* const* RefRaw() const {
static_assert(sizeof(RefPtr<RawServoDeclarationBlock>) ==
sizeof(RawServoDeclarationBlock*),
"RefPtr should just be a pointer");
return reinterpret_cast<RawServoDeclarationBlock* const*>(&mRaw);
}
void ToString(nsAString& aResult) const {
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -293,21 +293,28 @@ nsDOMCSSDeclaration::ParsePropertyValue(
// For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
// Attribute setting code, which leads in turn to BeginUpdate. We
// need to start the update now so that the old rule doesn't get used
// between when we mutate the declaration and when we set the new
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
- nsCSSParser cssParser(env.mCSSLoader);
bool changed;
- cssParser.ParseProperty(aPropID, aPropValue,
- env.mSheetURI, env.mBaseURI, env.mPrincipal,
- decl->AsGecko(), &changed, aIsImportant);
+ if (decl->IsGecko()) {
+ nsCSSParser cssParser(env.mCSSLoader);
+ cssParser.ParseProperty(aPropID, aPropValue,
+ env.mSheetURI, env.mBaseURI, env.mPrincipal,
+ decl->AsGecko(), &changed, aIsImportant);
+ } else {
+ nsIAtom* atom = nsCSSProps::AtomForProperty(aPropID);
+ NS_ConvertUTF16toUTF8 value(aPropValue);
+ changed = Servo_DeclarationBlock_SetProperty(
+ decl->AsServo()->Raw(), atom, false, &value, aIsImportant);
+ }
if (!changed) {
// Parsing failed -- but we don't throw an exception for that.
return NS_OK;
}
return SetCSSDeclaration(decl);
}
@@ -332,23 +339,29 @@ nsDOMCSSDeclaration::ParseCustomProperty
// For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
// Attribute setting code, which leads in turn to BeginUpdate. We
// need to start the update now so that the old rule doesn't get used
// between when we mutate the declaration and when we set the new
// rule (see stack in bug 209575).
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
RefPtr<DeclarationBlock> decl = olddecl->EnsureMutable();
- nsCSSParser cssParser(env.mCSSLoader);
bool changed;
- cssParser.ParseVariable(Substring(aPropertyName,
- CSS_CUSTOM_NAME_PREFIX_LENGTH),
- aPropValue, env.mSheetURI,
- env.mBaseURI, env.mPrincipal, decl->AsGecko(),
- &changed, aIsImportant);
+ auto propName = Substring(aPropertyName, CSS_CUSTOM_NAME_PREFIX_LENGTH);
+ if (decl->IsGecko()) {
+ nsCSSParser cssParser(env.mCSSLoader);
+ cssParser.ParseVariable(propName, aPropValue, env.mSheetURI,
+ env.mBaseURI, env.mPrincipal, decl->AsGecko(),
+ &changed, aIsImportant);
+ } else {
+ RefPtr<nsIAtom> atom = NS_Atomize(propName);
+ NS_ConvertUTF16toUTF8 value(aPropValue);
+ changed = Servo_DeclarationBlock_SetProperty(
+ decl->AsServo()->Raw(), atom, true, &value, aIsImportant);
+ }
if (!changed) {
// Parsing failed -- but we don't throw an exception for that.
return NS_OK;
}
return SetCSSDeclaration(decl);
}
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -972,16 +972,24 @@ extern "C" {
pub fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations:
RawServoDeclarationBlockBorrowed,
property:
*mut nsIAtom,
is_custom: bool)
-> bool;
}
extern "C" {
+ pub fn Servo_DeclarationBlock_SetProperty(declarations:
+ RawServoDeclarationBlockBorrowed,
+ property: *mut nsIAtom,
+ is_custom: bool,
+ value: *mut nsACString_internal,
+ is_important: bool) -> bool;
+}
+extern "C" {
pub fn Servo_DeclarationBlock_RemoveProperty(declarations:
RawServoDeclarationBlockBorrowed,
property: *mut nsIAtom,
is_custom: bool);
}
extern "C" {
pub fn Servo_CSSSupports(name: *const nsACString_internal,
value: *const nsACString_internal) -> bool;
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -534,16 +534,38 @@ pub extern "C" fn Servo_DeclarationBlock
pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed,
property: *mut nsIAtom, is_custom: bool) -> bool {
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
let property = get_property_name_from_atom(property, is_custom);
declarations.read().property_priority(&property).important()
}
#[no_mangle]
+pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed,
+ property: *mut nsIAtom, is_custom: bool,
+ value: *mut nsACString, is_important: bool) -> bool {
+ let property = get_property_name_from_atom(property, is_custom);
+ let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
+ // FIXME Needs real URL and ParserContextExtraData.
+ let base_url = &*DUMMY_BASE_URL;
+ let extra_data = ParserContextExtraData::default();
+ if let Ok(decls) = parse_one_declaration(&property, value, &base_url,
+ Box::new(StdoutErrorReporter), extra_data) {
+ let mut declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations).write();
+ let importance = if is_important { Importance::Important } else { Importance::Normal };
+ for decl in decls.into_iter() {
+ declarations.set_parsed_declaration(decl, importance);
+ }
+ true
+ } else {
+ false
+ }
+}
+
+#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_RemoveProperty(declarations: RawServoDeclarationBlockBorrowed,
property: *mut nsIAtom, is_custom: bool) {
let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
let property = get_property_name_from_atom(property, is_custom);
declarations.write().remove_property(&property);
}
#[no_mangle]