Bug 1294299 part 9 - Implement Clone for ServoDeclarationBlock. r=heycam
MozReview-Commit-ID: 5y2h26j87Sz
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -185,26 +185,20 @@ nsGenericHTMLElement::CopyInnerTo(Elemen
const nsAttrValue *value = mAttrsAndChildren.AttrAt(i);
nsAutoString valStr;
value->ToString(valStr);
if (name->Equals(nsGkAtoms::style, kNameSpaceID_None) &&
value->Type() == nsAttrValue::eCSSDeclaration) {
DeclarationBlock* decl = value->GetCSSDeclarationValue();
- if (decl->IsServo()) {
- MOZ_CRASH("stylo: clone not implemented");
- continue;
- }
-
// We can't just set this as a string, because that will fail
// to reparse the string into style data until the node is
// inserted into the document. Clone the Rule instead.
- RefPtr<css::Declaration>
- declClone = new css::Declaration(*decl->AsGecko());
+ RefPtr<DeclarationBlock> declClone = decl->Clone();
rv = aDst->SetInlineStyleDeclaration(declClone, &valStr, false);
NS_ENSURE_SUCCESS(rv, rv);
continue;
}
rv = aDst->SetAttr(name->NamespaceID(), name->LocalName(),
--- a/layout/style/DeclarationBlock.h
+++ b/layout/style/DeclarationBlock.h
@@ -36,16 +36,18 @@ protected:
: DeclarationBlock(aCopy.mType) {}
public:
MOZ_DECL_STYLO_METHODS(css::Declaration, ServoDeclarationBlock)
inline MozExternalRefCountType AddRef();
inline MozExternalRefCountType Release();
+ inline already_AddRefed<DeclarationBlock> Clone() const;
+
/**
* Return whether |this| may be modified.
*/
bool IsMutable() const {
return !mImmutable;
}
/**
--- a/layout/style/DeclarationBlockInlines.h
+++ b/layout/style/DeclarationBlockInlines.h
@@ -21,16 +21,28 @@ DeclarationBlock::AddRef()
}
MozExternalRefCountType
DeclarationBlock::Release()
{
MOZ_STYLO_FORWARD(Release, ())
}
+already_AddRefed<DeclarationBlock>
+DeclarationBlock::Clone() const
+{
+ RefPtr<DeclarationBlock> result;
+ if (IsGecko()) {
+ result = new css::Declaration(*AsGecko());
+ } else {
+ result = new ServoDeclarationBlock(*AsServo());
+ }
+ return result.forget();
+}
+
void
DeclarationBlock::ToString(nsAString& aString) const
{
MOZ_STYLO_FORWARD(ToString, (aString))
}
uint32_t
DeclarationBlock::Count() const
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -59,16 +59,18 @@ SERVO_BINDING_FUNC(Servo_RestyleWithAdde
RawServoDeclarationBlockBorrowed declarations,
ServoComputedValuesBorrowed previous_style)
// Style attribute
SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, RawServoDeclarationBlockStrong,
const nsACString* data)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_CreateEmpty,
RawServoDeclarationBlockStrong)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_Clone, RawServoDeclarationBlockStrong,
+ RawServoDeclarationBlockBorrowed declarations)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_AddRef, void,
RawServoDeclarationBlockBorrowed declarations)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_Release, void,
RawServoDeclarationBlockBorrowed declarations)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_Equals, bool,
RawServoDeclarationBlockBorrowed a,
RawServoDeclarationBlockBorrowed b)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetCssText, void,
--- a/layout/style/ServoDeclarationBlock.h
+++ b/layout/style/ServoDeclarationBlock.h
@@ -12,16 +12,20 @@
namespace mozilla {
class ServoDeclarationBlock final : public DeclarationBlock
{
public:
ServoDeclarationBlock()
: ServoDeclarationBlock(Servo_DeclarationBlock_CreateEmpty().Consume()) {}
+ ServoDeclarationBlock(const ServoDeclarationBlock& aCopy)
+ : DeclarationBlock(aCopy)
+ , mRaw(Servo_DeclarationBlock_Clone(aCopy.mRaw).Consume()) {}
+
NS_INLINE_DECL_REFCOUNTING(ServoDeclarationBlock)
static already_AddRefed<ServoDeclarationBlock>
FromCssText(const nsAString& aCssText);
RawServoDeclarationBlock* const* RefRaw() const {
static_assert(sizeof(RefPtr<RawServoDeclarationBlock>) ==
sizeof(RawServoDeclarationBlock*),
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -923,16 +923,21 @@ extern "C" {
pub fn Servo_ParseStyleAttribute(data: *const nsACString_internal)
-> RawServoDeclarationBlockStrong;
}
extern "C" {
pub fn Servo_DeclarationBlock_CreateEmpty()
-> RawServoDeclarationBlockStrong;
}
extern "C" {
+ pub fn Servo_DeclarationBlock_Clone(declarations:
+ RawServoDeclarationBlockBorrowed)
+ -> RawServoDeclarationBlockStrong;
+}
+extern "C" {
pub fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed,
b: RawServoDeclarationBlockBorrowed)
-> bool;
}
extern "C" {
pub fn Servo_DeclarationBlock_GetCssText(declarations:
RawServoDeclarationBlockBorrowed,
result: *mut nsAString_internal);
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -422,16 +422,23 @@ pub extern "C" fn Servo_ParseStyleAttrib
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_CreateEmpty() -> RawServoDeclarationBlockStrong {
Arc::new(RwLock::new(PropertyDeclarationBlock { declarations: vec![], important_count: 0 })).into_strong()
}
#[no_mangle]
+pub extern "C" fn Servo_DeclarationBlock_Clone(declarations: RawServoDeclarationBlockBorrowed)
+ -> RawServoDeclarationBlockStrong {
+ let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
+ Arc::new(RwLock::new(declarations.read().clone())).into_strong()
+}
+
+#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: RawServoDeclarationBlockBorrowed) {
unsafe { RwLock::<PropertyDeclarationBlock>::addref(declarations) };
}
#[no_mangle]
pub extern "C" fn Servo_DeclarationBlock_Release(declarations: RawServoDeclarationBlockBorrowed) {
unsafe { RwLock::<PropertyDeclarationBlock>::release(declarations) };
}