Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1106)

Unified Diff: third_party/WebKit/Source/core/dom/Element.cpp

Issue 1449623002: IntersectionObserver: second cut. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Clarify the tear-down path for observers and observations. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/dom/Element.cpp
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 2351061beffa6fe31b4f88515be7642791eec300..e7cea98d1ff7ddf1a5ae3aad026037b54b2b795b 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -59,6 +59,7 @@
#include "core/dom/ExceptionCode.h"
#include "core/dom/FirstLetterPseudoElement.h"
#include "core/dom/Fullscreen.h"
+#include "core/dom/IntersectionObserver.h"
#include "core/dom/LayoutTreeBuilder.h"
#include "core/dom/MutationObserverInterestGroup.h"
#include "core/dom/MutationRecord.h"
@@ -105,6 +106,8 @@
#include "core/html/HTMLTemplateElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/layout/LayoutInline.h"
+#include "core/layout/LayoutPart.h"
#include "core/layout/LayoutTextFragment.h"
#include "core/layout/LayoutView.h"
#include "core/loader/DocumentLoader.h"
@@ -170,6 +173,8 @@ Element::~Element()
{
ASSERT(needsAttach());
+ disconnectIntersectionObservations();
+
#if !ENABLE(OILPAN)
if (hasRareData()) {
elementRareData()->clearShadow();
@@ -1449,8 +1454,14 @@ Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertio
if (!insertionPoint->isInTreeScope())
return InsertionDone;
- if (hasRareData())
- elementRareData()->clearClassListValueForQuirksMode();
+ if (hasRareData()) {
+ ElementRareData* rareData = elementRareData();
+ rareData->clearClassListValueForQuirksMode();
+ if (rareData->hasIntersectionObservation()) {
+ for (auto& observation: rareData->intersectionObservations())
+ observation->setActive(observation->observer()->checkTargetHierarchy(this));
eae 2015/11/16 23:34:44 If I read this correctly this iterates over all ob
szager1 2015/11/19 19:15:38 In this case, "active" means that |this| is a desc
+ }
+ }
if (isUpgradedCustomElement() && inDocument())
CustomElement::didAttach(this, document());
@@ -1528,6 +1539,12 @@ void Element::removedFrom(ContainerNode* insertionPoint)
if (ElementAnimations* elementAnimations = data->elementAnimations())
elementAnimations->cssAnimations().cancel();
+
+ if (data->hasIntersectionObservation()) {
+ for (auto& observation: data->intersectionObservations()) {
eae 2015/11/16 23:34:44 data->deactiveAllObservations()?
szager1 2015/11/19 19:15:38 Done in forthcoming patch.
+ observation->setActive(false);
+ }
+ }
}
}
@@ -3569,6 +3586,78 @@ bool Element::supportsStyleSharing() const
return true;
}
+WeakPtr<Element> Element::createWeakPtr()
+{
+ return ensureElementRareData().createWeakPtr(this);
+}
+
+void Element::addIntersectionObservation(IntersectionObservation& observation)
+{
+ ensureElementRareData().intersectionObservations().add(adoptRef(&observation));
+}
+
+void Element::removeIntersectionObservation(IntersectionObservation& observation)
+{
+ if (!hasRareData() || !elementRareData()->hasIntersectionObservation())
+ return;
+ elementRareData()->intersectionObservations().remove(adoptRef(&observation));
+}
+
+void Element::disconnectIntersectionObservations()
+{
+ if (!hasRareData() || !elementRareData()->hasIntersectionObservation())
+ return;
+ Vector<RefPtrWillBeRawPtr<IntersectionObservation>> toRemove;
+ for (auto& observation: elementRareData()->intersectionObservations())
+ toRemove.append(observation);
+ for (auto& observation: toRemove) {
+ if (observation->observer()->root() == this)
+ observation->observer()->disconnect();
+ else
+ observation->disconnect();
+ }
+}
+
+bool Element::computeIntersection(Element* root, LayoutRect& targetRect, LayoutRect& rootRect, LayoutRect& intersectionRect)
+{
+ // TODO: support zero-size targetRect
eae 2015/11/16 23:34:44 How would you intersect with a zero-sized target?
szager1 2015/11/19 19:15:38 The proposal is that we would calculate clipping b
+ intersectionRect = targetRect = toLayoutBoxModelObject(layoutObject())->visualOverflowRect();
+
+ if (root) {
+ ASSERT(root->isInTreeScope());
+ ASSERT(isDescendantOf(root));
+ // TODO: Support SVG
+ if (!root->layoutObject()->isBoxModelObject())
+ return false;
+ rootRect = toLayoutBoxModelObject(root->layoutObject())->visualOverflowRect();
+ layoutObject()->mapRectToPaintInvalidationBacking(toLayoutBoxModelObject(root->layoutObject()), intersectionRect, nullptr);
eae 2015/11/16 23:34:44 This doesn't seem right, what are you trying to do
szager1 2015/11/19 19:15:37 My understanding is that mapRectToPaintInvalidatio
+
+ // Convert rects to frame coordinates.
+ targetRect.moveBy(LayoutPoint(layoutObject()->localToAbsolute()));
+ LayoutPoint rootOffset = LayoutPoint(root->layoutObject()->localToAbsolute());
+ intersectionRect.moveBy(rootOffset);
+ rootRect.moveBy(rootOffset);
+ } else {
+ Element* target = this;
+ LocalFrame* frame = document().frame();
+ while (target) {
+ targetRect.moveBy(LayoutPoint(target->layoutObject()->localToAbsolute()));
+ Document& document = target->document();
+ LayoutView* layoutView = document.layoutView();
+ ASSERT(layoutView);
+ // TODO: does intersectionRect need to be adjusted for frame border?
+ target->layoutObject()->mapRectToPaintInvalidationBacking(layoutView, intersectionRect, nullptr);
+ frame = document.frame();
+ ASSERT(frame);
+ target = toElement(frame->ownerLayoutObject()->node());
+ }
+ rootRect = LayoutRect(frame->view()->scrollableArea()->visibleContentRect());
+ intersectionRect = intersection(intersectionRect, rootRect);
+ }
+
+ return true;
+}
+
DEFINE_TRACE(Element)
{
#if ENABLE(OILPAN)

Powered by Google App Engine
This is Rietveld 408576698