Bug 866411 - copy animation effects when cloning a use element r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D188886
This commit is contained in:
Robert Longson 2023-09-25 20:31:29 +00:00
Родитель c8cba7bbad
Коммит 34595a606a
5 изменённых файлов: 51 добавлений и 3 удалений

Просмотреть файл

@ -1393,6 +1393,7 @@ Document::Document(const char* aContentType)
mUserHasInteracted(false),
mHasUserInteractionTimerScheduled(false),
mShouldResistFingerprinting(false),
mCloningForSVGUse(false),
mXMLDeclarationBits(0),
mOnloadBlockCount(0),
mWriteLevel(0),
@ -13668,6 +13669,9 @@ void Document::ScheduleSVGUseElementShadowTreeUpdate(
void Document::DoUpdateSVGUseElementShadowTrees() {
MOZ_ASSERT(!mSVGUseElementsNeedingShadowTreeUpdate.IsEmpty());
MOZ_ASSERT(!mCloningForSVGUse);
mCloningForSVGUse = true;
do {
const auto useElementsToUpdate = ToTArray<nsTArray<RefPtr<SVGUseElement>>>(
mSVGUseElementsNeedingShadowTreeUpdate);
@ -13684,6 +13688,8 @@ void Document::DoUpdateSVGUseElementShadowTrees() {
useElement->UpdateShadowTree();
}
} while (!mSVGUseElementsNeedingShadowTreeUpdate.IsEmpty());
mCloningForSVGUse = false;
}
void Document::NotifyMediaFeatureValuesChanged() {

Просмотреть файл

@ -3688,6 +3688,9 @@ class Document : public nsINode,
bool UserHasInteracted() { return mUserHasInteracted; }
void ResetUserInteractionTimer();
// Whether we're cloning the contents of an SVG use element.
bool CloningForSVGUse() const { return mCloningForSVGUse; }
// This should be called when this document receives events which are likely
// to be user interaction with the document, rather than the byproduct of
// interaction with the browser (i.e. a keypress to scroll the view port,
@ -4872,6 +4875,9 @@ class Document : public nsINode,
// Whether we should resist fingerprinting.
bool mShouldResistFingerprinting : 1;
// Whether we're cloning the contents of an SVG use element.
bool mCloningForSVGUse : 1;
uint8_t mXMLDeclarationBits;
// NOTE(emilio): Technically, this should be a StyleColorSchemeFlags, but we

Просмотреть файл

@ -206,7 +206,8 @@ nsresult SVGElement::CopyInnerTo(mozilla::dom::Element* aDest) {
// If our destination is a print document, copy all the relevant length values
// etc so that they match the state of the original node.
if (aDest->OwnerDoc()->IsStaticDocument()) {
if (aDest->OwnerDoc()->IsStaticDocument() ||
aDest->OwnerDoc()->CloningForSVGUse()) {
LengthAttributesInfo lengthInfo = GetLengthInfo();
dest->GetLengthInfo().CopyAllFrom(lengthInfo);
if (SVGGeometryProperty::ElementMapsLengthsToStyle(this)) {

Просмотреть файл

@ -94,6 +94,9 @@ namespace SVGT = SVGGeometryProperty::Tags;
void SVGUseElement::ProcessAttributeChange(int32_t aNamespaceID,
nsAtom* aAttribute) {
if (OwnerDoc()->CloningForSVGUse()) {
return;
}
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::width || aAttribute == nsGkAtoms::height) {
const bool hadValidDimensions = HasValidDimensions();
@ -407,8 +410,7 @@ void SVGUseElement::UpdateShadowTree() {
RefPtr<Element> newElement;
auto UpdateShadowTree = mozilla::MakeScopeExit([&]() {
nsIContent* firstChild = shadow->GetFirstChild();
if (firstChild) {
if (nsIContent* firstChild = shadow->GetFirstChild()) {
MOZ_ASSERT(!firstChild->GetNextSibling());
shadow->RemoveChildNode(firstChild, /* aNotify = */ true);
}

Просмотреть файл

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:h="http://www.w3.org/1999/xhtml">
<title>cloning a SVGGraphicsElement</title>
<metadata>
<h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#InterfaceSVGGraphicsElement"/>
</metadata>
<h:script src="/resources/testharness.js"/>
<h:script src="/resources/testharnessreport.js"/>
<rect id="r" x="10">
<set id="set" begin="indefinite" attributeName="x" to="20" dur="15ms" fill="freeze"/>
</rect>
<script><![CDATA[
let el = document.getElementById("r");
let set = document.getElementById("set");
test(function() {
let clone = el.cloneNode();
assert_equals(clone.x.animVal.value, clone.x.baseVal.value);
}, 'check animVal equals baseVal by default');
async_test(t => {
set.beginElement();
set.addEventListener("beginEvent", t.step_func_done(function () {
assert_approx_equals(el.x.animVal.value, 20, 0.001);
let clone = el.cloneNode();
assert_approx_equals(clone.x.animVal.value, 10, 0.001);
}));
}, 'check clone does not copy the animated value');
]]></script>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB