Commit 879fbd02 authored by atotic's avatar atotic Committed by Commit bot

Fix svg contentrect location

I was not computing entry.contetRect location correctly for <svg> elements.
It should be 0,0

BUG=641364

Review-Url: https://codereview.chromium.org/2305893002
Cr-Commit-Position: refs/heads/master@{#417450}
parent 7db92305
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="./resources/resizeTestHelper.js"></script> <script src="./resources/resizeTestHelper.js"></script>
<p>ResizeObserver svg tests</p> <p>ResizeObserver svg tests</p>
<svg height="430" width="500"> <svg height="430" width="500" >
<circle cx="10" cy="10" r="5" style="fill:orange;stroke:black;stroke-width:1" /> <circle cx="10" cy="10" r="5" style="fill:orange;stroke:black;stroke-width:1" />
<ellipse cx="10" cy="30" rx="5" ry="5" style="fill:orange;stroke:black;stroke-width:1"/> <ellipse cx="10" cy="30" rx="5" ry="5" style="fill:orange;stroke:black;stroke-width:1"/>
<foreignObject cy="50" width="100" height="20"> <foreignObject cy="50" width="100" height="20">
...@@ -290,6 +290,27 @@ function test9() { ...@@ -290,6 +290,27 @@ function test9() {
]); ]);
return helper.start(); return helper.start();
} }
function test10() {
let target = document.querySelector('svg');
let helper = new ResizeTestHelper(
"test10: observe svg:svg, top/left is 0 even with padding",
[
{
setup: observer => {
observer.observe(target);
},
notify: (entries, observer) => {
assert_equals(entries.length, 1);
assert_equals(entries[0].contentRect.top, 0);
assert_equals(entries[0].contentRect.left, 0);
}
}
]);
return helper.start();
}
let guard = async_test('guard'); let guard = async_test('guard');
test0() test0()
.then(() => { return test1(); }) .then(() => { return test1(); })
...@@ -301,6 +322,7 @@ test0() ...@@ -301,6 +322,7 @@ test0()
.then(() => { return test7(); }) .then(() => { return test7(); })
.then(() => { return test8(); }) .then(() => { return test8(); })
.then(() => { return test9(); }) .then(() => { return test9(); })
.then(() => { return test10(); })
.then(() => { guard.done(); }); .then(() => { guard.done(); });
</script> </script>
...@@ -21,15 +21,15 @@ ResizeObservation::ResizeObservation(Element* target, ResizeObserver* observer) ...@@ -21,15 +21,15 @@ ResizeObservation::ResizeObservation(Element* target, ResizeObserver* observer)
m_observer->elementSizeChanged(); m_observer->elementSizeChanged();
} }
void ResizeObservation::setObservationSize(const LayoutSize& size) bool ResizeObservation::observationSizeOutOfSync()
{ {
m_observationSize = size; return m_elementSizeChanged && m_observationSize != computeTargetSize();
m_elementSizeChanged = false;
} }
bool ResizeObservation::observationSizeOutOfSync() const void ResizeObservation::setObservationSize(const LayoutSize& observationSize)
{ {
return m_elementSizeChanged && m_observationSize != ResizeObservation::getTargetSize(m_target); m_observationSize = observationSize;
m_elementSizeChanged = false;
} }
size_t ResizeObservation::targetDepth() size_t ResizeObservation::targetDepth()
...@@ -40,20 +40,29 @@ size_t ResizeObservation::targetDepth() ...@@ -40,20 +40,29 @@ size_t ResizeObservation::targetDepth()
return depth; return depth;
} }
LayoutSize ResizeObservation::getTargetSize(Element* target) // static LayoutSize ResizeObservation::computeTargetSize() const
{ {
if (target) { if (m_target) {
if (target->isSVGElement() && toSVGElement(target)->isSVGGraphicsElement()) { if (m_target->isSVGElement() && toSVGElement(m_target)->isSVGGraphicsElement()) {
SVGGraphicsElement& svg = toSVGGraphicsElement(*target); SVGGraphicsElement& svg = toSVGGraphicsElement(*m_target);
return LayoutSize(svg.getBBox().size()); return LayoutSize(svg.getBBox().size());
} }
LayoutBox* layout = target->layoutBox(); LayoutBox* layout = m_target->layoutBox();
if (layout) if (layout)
return layout->contentSize(); return layout->contentSize();
} }
return LayoutSize(); return LayoutSize();
} }
LayoutPoint ResizeObservation::computeTargetLocation() const
{
if (m_target && !m_target->isSVGElement()) {
if (LayoutBox* layout = m_target->layoutBox())
return LayoutPoint(layout->paddingLeft(), layout->paddingTop());
}
return LayoutPoint();
}
void ResizeObservation::elementSizeChanged() void ResizeObservation::elementSizeChanged()
{ {
m_elementSizeChanged = true; m_elementSizeChanged = true;
......
...@@ -21,12 +21,13 @@ public: ...@@ -21,12 +21,13 @@ public:
Element* target() const { return m_target; } Element* target() const { return m_target; }
size_t targetDepth(); size_t targetDepth();
void setObservationSize(const LayoutSize&);
// True if observationSize differs from target's current size. // True if observationSize differs from target's current size.
bool observationSizeOutOfSync() const; bool observationSizeOutOfSync();
void setObservationSize(const LayoutSize&);
void elementSizeChanged(); void elementSizeChanged();
static LayoutSize getTargetSize(Element* target); LayoutSize computeTargetSize() const;
LayoutPoint computeTargetLocation() const;
DECLARE_TRACE(); DECLARE_TRACE();
......
...@@ -98,9 +98,12 @@ void ResizeObserver::deliverObservations() ...@@ -98,9 +98,12 @@ void ResizeObserver::deliverObservations()
HeapVector<Member<ResizeObserverEntry>> entries; HeapVector<Member<ResizeObserverEntry>> entries;
for (auto& observation : m_activeObservations) { for (auto& observation : m_activeObservations) {
auto entry = new ResizeObserverEntry(observation->target()); LayoutPoint location = observation->computeTargetLocation();
LayoutSize size = observation->computeTargetSize();
observation->setObservationSize(size);
auto entry = new ResizeObserverEntry(observation->target(),
LayoutRect(location, size));
entries.append(entry); entries.append(entry);
observation->setObservationSize(entry->contentSize());
} }
m_callback->handleEvent(entries, this); m_callback->handleEvent(entries, this);
clearObservations(); clearObservations();
......
...@@ -11,23 +11,13 @@ ...@@ -11,23 +11,13 @@
namespace blink { namespace blink {
class ResizeObservation;
ResizeObserverEntry::ResizeObserverEntry(Element* target) ResizeObserverEntry::ResizeObserverEntry(Element* target, const LayoutRect& contentRect)
: m_target(target) : m_target(target)
{ {
FloatSize size = FloatSize(ResizeObservation::getTargetSize(m_target)); m_contentRect = ClientRect::create(FloatRect(
FloatPoint location; FloatPoint(contentRect.location()),
LayoutBox* layout = m_target ? m_target->layoutBox() : nullptr; FloatSize(contentRect.size())));
if (layout) {
location = FloatPoint(layout->paddingLeft(), layout->paddingTop());
}
m_contentRect = ClientRect::create(FloatRect(location, size));
}
LayoutSize ResizeObserverEntry::contentSize() const
{
return LayoutSize(m_contentRect->width(), m_contentRect->height());
} }
DEFINE_TRACE(ResizeObserverEntry) DEFINE_TRACE(ResizeObserverEntry)
......
...@@ -12,18 +12,18 @@ namespace blink { ...@@ -12,18 +12,18 @@ namespace blink {
class Element; class Element;
class ClientRect; class ClientRect;
class LayoutRect;
class LayoutSize; class LayoutSize;
class ResizeObserverEntry final : public GarbageCollected<ResizeObserverEntry>, public ScriptWrappable { class ResizeObserverEntry final : public GarbageCollected<ResizeObserverEntry>, public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
public: public:
explicit ResizeObserverEntry(Element* target); ResizeObserverEntry(Element* target, const LayoutRect& contentRect);
Element* target() const { return m_target; } Element* target() const { return m_target; }
// FIXME(atotic): should return DOMRectReadOnly once https://crbug.com/388780 lands // FIXME(atotic): should return DOMRectReadOnly once https://crbug.com/388780 lands
ClientRect* contentRect() const { return m_contentRect; } ClientRect* contentRect() const { return m_contentRect; }
LayoutSize contentSize() const;
DECLARE_VIRTUAL_TRACE(); DECLARE_VIRTUAL_TRACE();
......
...@@ -83,12 +83,12 @@ TEST_F(ResizeObserverUnitTest, ResizeObservationSize) ...@@ -83,12 +83,12 @@ TEST_F(ResizeObserverUnitTest, ResizeObservationSize)
ASSERT_TRUE(svgObservation->observationSizeOutOfSync()); ASSERT_TRUE(svgObservation->observationSizeOutOfSync());
// Target size is correct // Target size is correct
LayoutSize size = ResizeObservation::getTargetSize(domTarget); LayoutSize size = domObservation->computeTargetSize();
ASSERT_EQ(size.width(), 100); ASSERT_EQ(size.width(), 100);
ASSERT_EQ(size.height(), 100); ASSERT_EQ(size.height(), 100);
domObservation->setObservationSize(size); domObservation->setObservationSize(size);
size = ResizeObservation::getTargetSize(svgTarget); size = svgObservation->computeTargetSize();
ASSERT_EQ(size.width(), 200); ASSERT_EQ(size.width(), 200);
ASSERT_EQ(size.height(), 200); ASSERT_EQ(size.height(), 200);
svgObservation->setObservationSize(size); svgObservation->setObservationSize(size);
......
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