chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_METRICS_SENDER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_METRICS_SENDER_H_

#include <compare>

#include "third_party/blink/public/mojom/loader/navigation_predictor.mojom-blink.h"
#include "third_party/blink/public/mojom/preloading/anchor_element_interaction_host.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/platform/allow_discouraged_type.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

class Document;
class HTMLAnchorElement;
class IntersectionObserver;
class IntersectionObserverEntry;
class PointerEvent;

// AnchorElementMetricsSender is responsible to send anchor element metrics to
// the browser process for a given document.
//
// AnchorElementMetricsSenders are created for documents in main frames. Any
// same-origin iframes reuse the AnchorElementMetricsSender of their main frame.
// Cross-origin iframes do not use any AnchorElementMetricsSender.
//
// The high level approach is:
// 1) When HTMLAnchorElements are inserted into the DOM,
//    AnchorElementMetricsSender::AddAnchorElement is called and a reference to
//    the element is stored. The first time this happens, the sender is created,
//    which registers itself for lifecycle callbacks.
// 2) If any elements enter the viewport, the intersection observer will call
//    AnchorElementMetricsSender::UpdateVisibleAnchors. Elements are collected
//    in entered_viewport_messages_ and will be reported after the next layout.
// 3) On the next layout, AnchorElementMetricsSender::DidFinishLifecycleUpdate
//    is called, and it goes over the collected anchor elements. Elements that
//    are visible are reported to the browser via ReportNewAnchorElements. We
//    also may add an element to the intersection observer that watches for
//    elements entering/leaving the viewport. The anchor elements collected in
//    AnchorElementMetricsSender are all dropped. In particular, this drops
//    elements that are not visible. They will never be reported even if they
//    become visible later, unless the are reinserted into the DOM. This is not
//    ideal, but simpler, keeps resource usage low, and seems to work well
//    enough on the sites I've looked at. Also, elements that entered the
//    viewport will be reported using ReportAnchorElementsEnteredViewport. We
//    stop observing lifecycle changes until the next anchor being added or
//    entering/existing the viewport, when we again wait for the next layout.
class CORE_EXPORT AnchorElementMetricsSender final
    : public GarbageCollected<AnchorElementMetricsSender>,
      public LocalFrameView::LifecycleNotificationObserver,
      public Supplement<Document> {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_ANCHOR_ELEMENT_METRICS_SENDER_H_