Commit cd7fe3ac authored by kouhei@chromium.org's avatar kouhei@chromium.org

SVG: Items inserted into list should be made a tear-off.

Before this patch, static SVGPropertyTearOff items inserted into a SVGListTearOff were not marked as a tear-off.
For such items, |svgAttributeChanged| was not dispatched to its context element, and view was not updated when its value changed.

This patch fixes the issue by converting a static tear-off inserted into a list to a dynamic tear-off.

Also this patch fixes an issue that a tearoff returned from replaceItem/removeItem was still attached to the list.

BUG=380546, 380176

Review URL: https://codereview.chromium.org/321403004

git-svn-id: svn://svn.chromium.org/blink/trunk@176284 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 079954a3
(GraphicsLayer
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(repaint rects
(rect 58.00 45.00 50.00 27.00)
(rect 58.00 45.00 50.00 17.00)
(rect 23.00 62.00 85.00 10.00)
(rect 23.00 8.00 85.00 24.00)
(rect 23.00 8.00 80.00 24.00)
)
)
)
)
(GraphicsLayer
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(repaint rects
(rect 28.00 38.00 10.00 10.00)
(rect 28.00 38.00 10.00 10.00)
(rect 18.00 18.00 20.00 30.00)
(rect 18.00 18.00 10.00 10.00)
)
)
)
)
<!DOCTYPE html>
<svg width="100" height="100">
<rect id="ref" x="20" y="30" width="10" height="10" fill="red"></rect>
<rect id="move" x="10" y="10" width="10" height="10" fill="green"></rect>
</svg>
<script src="../../fast/repaint/resources/text-based-repaint.js"></script>
<script>
testIsAsync = true;
window.onload = runRepaintTest;
function repaintTest() {
var transform = document.querySelector('svg').createSVGTransform();
transform.matrix.e = 10;
document.querySelector('#move').transform.baseVal.appendItem(transform);
requestAnimationFrame(function() {
transform.matrix.f = 20;
if (window.testRunner)
finishRepaintTest();
});
}
</script>
(GraphicsLayer
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(repaint rects
(rect 58.00 45.00 50.00 26.00)
(rect 58.00 45.00 50.00 16.00)
(rect 23.00 61.00 85.00 10.00)
(rect 23.00 8.00 85.00 23.00)
(rect 23.00 8.00 80.00 23.00)
)
)
)
)
<!DOCTYPE html>
<style>
@font-face {
font-family: 'myahem';
src: url(../../resources/Ahem.ttf);
}
text {
font-family: 'myahem';
}
</style>
<svg width="100" height="100">
<text id="ref" x="15 65" y="10 20" fill="red">A B C</text>
<text id="target" x="15" y="10 20" fill="green">A B C</text>
<text id="source" x="50" y="50 60" fill="blue">X Y Z</text>
</svg>
<script src="../../fast/repaint/resources/text-based-repaint.js"></script>
<script>
testIsAsync = true;
window.onload = runRepaintTest;
function repaintTest() {
var moved = document.querySelector('#source').y.baseVal.removeItem(1);
document.querySelector('#target').x.baseVal.appendItem(moved);
requestAnimationFrame(function() {
moved.value = 65;
if (window.testRunner)
finishRepaintTest();
});
}
</script>
(GraphicsLayer
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(repaint rects
(rect 18.00 18.00 30.00 20.00)
(rect 18.00 18.00 20.00 20.00)
)
)
)
)
<!DOCTYPE html>
<svg width="100" height="100">
<polygon id="ref" points="20,10 10,30 30,30 40,10" fill="red"></polygon>
<polygon id="target" points="20,10 10,30 30,30" fill="green"></polygon>
<polygon id="source" points="20,20" fill="blue"></polygon>
</svg>
<script src="../../fast/repaint/resources/text-based-repaint.js"></script>
<script>
testIsAsync = true;
window.onload = runRepaintTest;
function repaintTest() {
var moved = document.querySelector('#source').points.removeItem(0);
document.querySelector('#target').points.appendItem(moved);
requestAnimationFrame(function() {
moved.x = 40;
moved.y = 10;
if (window.testRunner)
finishRepaintTest();
});
}
</script>
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#ifndef SVGPathSegListTearOff_h #ifndef SVGPathSegListTearOff_h
#define SVGPathSegListTearOff_h #define SVGPathSegListTearOff_h
#include "SVGNames.h"
#include "core/svg/SVGPathSegList.h" #include "core/svg/SVGPathSegList.h"
#include "core/svg/properties/SVGListPropertyTearOffHelper.h" #include "core/svg/properties/SVGListPropertyTearOffHelper.h"
...@@ -43,9 +44,12 @@ public: ...@@ -43,9 +44,12 @@ public:
// FIXME: Currently SVGPathSegitself is a tear-off. // FIXME: Currently SVGPathSegitself is a tear-off.
typedef SVGPathSeg ItemTearOffType; typedef SVGPathSeg ItemTearOffType;
static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem) static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem, SVGElement* contextElement, const QualifiedName& attributeName)
{ {
return passNewItem; ASSERT(attributeName == SVGNames::dAttr);
RefPtr<ItemTearOffType> newItem = passNewItem;
newItem->setContextElement(contextElement);
return newItem.release();
} }
static PassRefPtr<ItemTearOffType> createTearOff(PassRefPtr<ItemPropertyType> passValue, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName&) static PassRefPtr<ItemTearOffType> createTearOff(PassRefPtr<ItemPropertyType> passValue, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName&)
......
...@@ -44,7 +44,7 @@ public: ...@@ -44,7 +44,7 @@ public:
typedef ItemProperty ItemPropertyType; typedef ItemProperty ItemPropertyType;
typedef typename ItemPropertyType::TearOffType ItemTearOffType; typedef typename ItemPropertyType::TearOffType ItemTearOffType;
static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem) static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem, SVGElement* contextElement, const QualifiedName& attributeName)
{ {
RefPtr<ItemTearOffType> newItem = passNewItem; RefPtr<ItemTearOffType> newItem = passNewItem;
...@@ -54,13 +54,14 @@ public: ...@@ -54,13 +54,14 @@ public:
if (newItem->isImmutable() if (newItem->isImmutable()
|| (newItem->contextElement() && !newItem->target()->ownerList())) { || (newItem->contextElement() && !newItem->target()->ownerList())) {
// We have to copy the incoming |newItem|, // We have to copy the incoming |newItem|,
// Otherwise we'll end up having two tearoffs that operate on the same SVGProperty. Consider the example above: // Otherwise we'll end up having two tearoffs that operate on the same SVGProperty. Consider the example below:
// SVGRectElements SVGAnimatedLength 'width' property baseVal points to the same tear off object // SVGRectElements SVGAnimatedLength 'width' property baseVal points to the same tear off object
// that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would
// mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that. // mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that.
return newItem->target()->clone(); return newItem->target()->clone();
} }
newItem->attachToSVGElementAttribute(contextElement, attributeName);
return newItem->target(); return newItem->target();
} }
...@@ -202,9 +203,9 @@ protected: ...@@ -202,9 +203,9 @@ protected:
{ {
} }
static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem) PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem)
{ {
return ItemTraits::getValueForInsertionFromTearOff(passNewItem); return ItemTraits::getValueForInsertionFromTearOff(passNewItem, toDerived()->contextElement(), toDerived()->attributeName());
} }
PassRefPtr<ItemTearOffType> createItemTearOff(PassRefPtr<ItemPropertyType> value) PassRefPtr<ItemTearOffType> createItemTearOff(PassRefPtr<ItemPropertyType> value)
...@@ -212,7 +213,10 @@ protected: ...@@ -212,7 +213,10 @@ protected:
if (!value) if (!value)
return nullptr; return nullptr;
return ItemTraits::createTearOff(value, toDerived()->contextElement(), toDerived()->propertyIsAnimVal(), toDerived()->attributeName()); if (value->ownerList() == toDerived()->target())
return ItemTraits::createTearOff(value, toDerived()->contextElement(), toDerived()->propertyIsAnimVal(), toDerived()->attributeName());
return ItemTraits::createTearOff(value, 0, PropertyIsNotAnimVal, nullQName());
} }
private: private:
......
...@@ -83,6 +83,15 @@ public: ...@@ -83,6 +83,15 @@ public:
return m_attributeName; return m_attributeName;
} }
void attachToSVGElementAttribute(SVGElement* contextElement, const QualifiedName& attributeName)
{
ASSERT(!isImmutable());
ASSERT(contextElement);
ASSERT(attributeName != nullQName());
m_contextElement = contextElement;
m_attributeName = attributeName;
}
virtual AnimatedPropertyType type() const = 0; virtual AnimatedPropertyType type() const = 0;
protected: protected:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment