Commit 03e20c08 authored by atotic's avatar atotic Committed by Commit bot

ResizeObserver pt3: observation computation

This patch fills in ResizeObservation functionality:
- computing/setting observation size
- determining target depth

ResizeObservation::getTargetSize is static because it will also
get used by ResizeObserverEntry

I've also included basic C++ tests.

BUG=612962

Review-Url: https://codereview.chromium.org/2173203002
Cr-Commit-Position: refs/heads/master@{#407736}
parent cbb49e60
......@@ -4,18 +4,54 @@
#include "core/observer/ResizeObservation.h"
#include "core/dom/Element.h"
#include "core/layout/LayoutBox.h"
#include "core/observer/ResizeObserver.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGGraphicsElement.h"
namespace blink {
ResizeObservation::ResizeObservation(Element* target, ResizeObserver* observer)
: m_target(target)
, m_observer(observer)
, m_observationSize(0, 0)
{
DCHECK(m_target);
}
void ResizeObservation::setObservationSize(const LayoutSize& size)
{
m_observationSize = size;
}
bool ResizeObservation::observationSizeOutOfSync() const
{
return m_observationSize != ResizeObservation::getTargetSize(m_target);
}
size_t ResizeObservation::targetDepth()
{
unsigned depth = 0;
for (Element* parent = m_target; parent; parent = parent->parentElement())
++depth;
return depth;
}
LayoutSize ResizeObservation::getTargetSize(Element* target) // static
{
if (target) {
if (target->isSVGElement() && toSVGElement(target)->isSVGGraphicsElement()) {
SVGGraphicsElement& svg = toSVGGraphicsElement(*target);
return LayoutSize(svg.getBBox().size());
}
LayoutBox* layout = target->layoutBox();
if (layout)
return layout->contentSize();
}
return LayoutSize();
}
DEFINE_TRACE(ResizeObservation)
{
visitor->trace(m_target);
......
......@@ -15,18 +15,25 @@ class Element;
class ResizeObserver;
// ResizeObservation represents an element that is being observed.
class ResizeObservation final : public GarbageCollected<ResizeObservation> {
class CORE_EXPORT ResizeObservation final : public GarbageCollected<ResizeObservation> {
public:
ResizeObservation(Element* target, ResizeObserver*);
Element* target() const { return m_target; }
size_t targetDepth();
void setObservationSize(const LayoutSize&);
// True if observationSize differs from target's current size.
bool observationSizeOutOfSync() const;
static LayoutSize getTargetSize(Element* target);
DECLARE_TRACE();
private:
WeakMember<Element> m_target;
Member<ResizeObserver> m_observer;
// Target size sent in last observation notification.
LayoutSize m_observationSize;
};
} // namespace blink
......
......@@ -18,7 +18,7 @@ class ResizeObservation;
// ResizeObserver represents ResizeObserver javascript api:
// https://github.com/WICG/ResizeObserver/
class ResizeObserver final : public GarbageCollectedFinalized<ResizeObserver>, public ScriptWrappable {
class CORE_EXPORT ResizeObserver final : public GarbageCollectedFinalized<ResizeObserver>, public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();
public:
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/observer/ResizeObserver.h"
#include "core/observer/ResizeObservation.h"
#include "core/observer/ResizeObserverCallback.h"
#include "platform/testing/UnitTestHelpers.h"
#include "web/WebViewImpl.h"
#include "web/tests/sim/SimCompositor.h"
#include "web/tests/sim/SimDisplayItemList.h"
#include "web/tests/sim/SimRequest.h"
#include "web/tests/sim/SimTest.h"
#include "wtf/CurrentTime.h"
namespace blink {
namespace {
class TestResizeObserverCallback : public ResizeObserverCallback {
public:
TestResizeObserverCallback(Document& document)
: m_document(document)
, m_callCount(0)
{ }
void handleEvent(const HeapVector<Member<ResizeObserverEntry>>& entries, ResizeObserver*) override
{
m_callCount++;
}
ExecutionContext* getExecutionContext() const { return m_document; }
int callCount() const { return m_callCount; }
DEFINE_INLINE_TRACE() {
ResizeObserverCallback::trace(visitor);
visitor->trace(m_document);
}
private:
Member<Document> m_document;
int m_callCount;
};
} // namespace
/* Testing:
* getTargetSize
* setTargetSize
* oubservationSizeOutOfSync == false
* modify target size
* oubservationSizeOutOfSync == true
*/
class ResizeObservationUnitTest : public SimTest { };
TEST_F(ResizeObservationUnitTest, ObserveSchedulesFrame)
{
SimRequest mainResource("https://example.com/", "text/html");
loadURL("https://example.com/");
mainResource.start();
mainResource.write(
"<div id='domTarget' style='width:100px;height:100px'>yo</div>"
"<svg height='200' width='200'>"
"<circle id='svgTarget' cx='100' cy='100' r='100'/>"
"</svg>"
);
mainResource.finish();
ResizeObserverCallback* callback = new TestResizeObserverCallback(document());
ResizeObserver* observer = ResizeObserver::create(document(), callback);
Element* domTarget = document().getElementById("domTarget");
Element* svgTarget = document().getElementById("svgTarget");
ResizeObservation* domObservation = new ResizeObservation(domTarget, observer);
ResizeObservation* svgObservation = new ResizeObservation(svgTarget, observer);
// Initial observation is out of sync
ASSERT_TRUE(domObservation->observationSizeOutOfSync());
ASSERT_TRUE(svgObservation->observationSizeOutOfSync());
// Target size is correct
LayoutSize size = ResizeObservation::getTargetSize(domTarget);
ASSERT_EQ(size.width(), 100);
ASSERT_EQ(size.height(), 100);
domObservation->setObservationSize(size);
size = ResizeObservation::getTargetSize(svgTarget);
ASSERT_EQ(size.width(), 200);
ASSERT_EQ(size.height(), 200);
svgObservation->setObservationSize(size);
// Target size is in sync
ASSERT_FALSE(domObservation->observationSizeOutOfSync());
// Target depths
ASSERT_EQ(svgObservation->targetDepth() - domObservation->targetDepth(), (size_t)1);
}
} // namespace blink
......@@ -265,6 +265,7 @@
'tests/PrerenderingTest.cpp',
'tests/ProgrammaticScrollTest.cpp',
'tests/LayoutGeometryMapTest.cpp',
'tests/ResizeObserverTest.cpp',
'tests/RootScrollerTest.cpp',
'tests/ScreenWakeLockTest.cpp',
'tests/ScrollingCoordinatorTest.cpp',
......
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