// Copyright 2018 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.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SHIFT_TRACKER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SHIFT_TRACKER_H_

#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
#include "third_party/blink/renderer/core/layout/layout_shift_region.h"
#include "third_party/blink/renderer/core/scroll/scroll_types.h"
#include "third_party/blink/renderer/core/timing/layout_shift.h"
#include "third_party/blink/renderer/platform/geometry/region.h"
#include "third_party/blink/renderer/platform/graphics/dom_node_id.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"

namespace blink {

class LayoutBox;
class LayoutObject;
class LayoutText;
class LocalFrameView;
class PropertyTreeStateOrAlias;
class TracedValue;
class WebInputEvent;

// Tracks "layout shifts" from layout objects changing their visual location
// between animation frames. See https://github.com/WICG/layout-instability.
class CORE_EXPORT LayoutShiftTracker final
    : public GarbageCollected<LayoutShiftTracker> {
 public:
  explicit LayoutShiftTracker(LocalFrameView*);
  ~LayoutShiftTracker() = default;

  bool NeedsToTrack(const LayoutObject&) const;

  // |old_rect| and |new_rect| are border box rects, united with layout overflow
  // rects if the box has layout overflow and doesn't clip overflow, in the
  // local transform space (property_tree_state.Transform()). |old_paint_offset|
  // and |new_paint_offset| are the offsets of the border box rect in the local
  // transform space, which are the same as |old_rect.offset| and
  // |new_rect.offset| respectively if the rects are border box rects.
  // As we don't save the old property tree state, the caller should adjust
  // |old_rect| and |old_paint_offset| so that we can calculate the correct old
  // visual representation and old starting point in the initial containing
  // block and the viewport with the new property tree state in most cases.
  // The adjustment should include the deltas of 2d translations and scrolls,
  // and LayoutShiftTracker can determine stability by including (by default)
  // or excluding |translation_delta| and/or |scroll_delta|.
  //
  // See renderer/core/layout/layout-shift-tracker-old-paint-offset.md for
  // more details about |old_paint_offset|.
  void NotifyBoxPrePaint(const LayoutBox& box,
                         const PropertyTreeStateOrAlias& property_tree_state,
                         const PhysicalRect& old_rect,
                         const PhysicalRect& new_rect,
                         const PhysicalOffset& old_paint_offset,
                         const FloatSize& translation_delta,
                         const FloatSize& scroll_delta,
                         const PhysicalOffset& new_paint_offset);

  void NotifyTextPrePaint(const LayoutText& text,
                          const PropertyTreeStateOrAlias& property_tree_state,
                          const LogicalOffset& old_starting_point,
                          const LogicalOffset& new_starting_point,
                          const PhysicalOffset& old_paint_offset,
                          const FloatSize& translation_delta,
                          const FloatSize& scroll_delta,
                          const PhysicalOffset& new_paint_offset,
                          const LayoutUnit logical_height);

  void NotifyPrePaintFinished();
  void NotifyInput(const WebInputEvent&);
  void NotifyScroll(mojom::blink::ScrollType, ScrollOffset delta);
  void NotifyViewportSizeChanged();
  void NotifyFindInPageInput();
  void NotifyChangeEvent();
  bool IsActive() const { return is_active_; }
  double Score() const { return score_; }
  double WeightedScore() const { return weighted_score_; }
  float OverallMaxDistance() const { return overall_max_distance_; }
  bool ObservedInputOrScroll() const { return observed_input_or_scroll_; }
  void Dispose() { timer_.Stop(); }
  base::TimeTicks MostRecentInputTimestamp() {
    return most_recent_input_timestamp_;
  }
  void Trace(Visitor* visitor) const;

  // Saves and restores geometry on layout boxes when a layout tree is rebuilt
  // by Node::ReattachLayoutTree.
  class ReattachHookScope {
    STACK_ALLOCATED();

   public:
    explicit ReattachHookScope(const Node&);
    ~ReattachHookScope();

    ReattachHookScope(const ReattachHookScope&) = delete;
    ReattachHookScope& operator=(const ReattachHookScope&) = delete;

    static void NotifyDetach(const Node&);
    static void NotifyAttach(const Node&);

   private:
    ReattachHookScope* outer_;
    static ReattachHookScope* top_;
    struct Geometry {
      PhysicalOffset paint_offset;
      LayoutSize size;
      PhysicalRect visual_overflow_rect;
      bool has_paint_offset_translation;
    };
    HeapHashMap<Member<const Node>, Geometry> geometries_before_detach_;
  };

  class CORE_EXPORT ContainingBlockScope {
    USING_FAST_MALLOC(ContainingBlockScope);

   public:
    // |old_size| and |new_size| are the border box sizes.
    // |old_rect| and |new_rect| have the same definition as in
    // NotifyBoxPrePaint().
    ContainingBlockScope(const PhysicalSize& old_size,
                         const PhysicalSize& new_size,
                         const PhysicalRect& old_rect,
                         const PhysicalRect& new_rect)
        : outer_(top_),
          old_size_(old_size),
          new_size_(new_size),
          old_rect_(old_rect),
          new_rect_(new_rect) {
      top_ = this;
    }
    ~ContainingBlockScope() {
      DCHECK_EQ(top_, this);
      top_ = outer_;
    }

    ContainingBlockScope(const ContainingBlockScope&) = delete;
    ContainingBlockScope& operator=(const ContainingBlockScope&) = delete;

   private:
    friend class LayoutShiftTracker;
    ContainingBlockScope* outer_;
    static ContainingBlockScope* top_;
    PhysicalSize old_size_;
    PhysicalSize new_size_;
    PhysicalRect old_rect_;
    PhysicalRect new_rect_;
  };

 private:
  void ObjectShifted(const LayoutObject&,
                     const PropertyTreeStateOrAlias&,
                     const PhysicalRect& old_rect,
                     const PhysicalRect& new_rect,
                     const FloatPoint& old_starting_point,
                     const FloatSize& translation_delta,
                     const FloatSize& scroll_offset_delta,
                     const FloatPoint& new_starting_point);

  void ReportShift(double score_delta, double weighted_score_delta);
  void TimerFired(TimerBase*) {}
  std::unique_ptr<TracedValue> PerFrameTraceData(double score_delta,
                                                 double weighted_score_delta,
                                                 bool input_detected) const;
  void AttributionsToTracedValue(TracedValue&) const;
  double SubframeWeightingFactor() const;
  void SetLayoutShiftRects(const Vector<IntRect>& int_rects);
  void UpdateInputTimestamp(base::TimeTicks timestamp);
  LayoutShift::AttributionList CreateAttributionList() const;
  void SubmitPerformanceEntry(double score_delta, bool input_detected) const;
  void NotifyPrePaintFinishedInternal();
  double LastInputTimestamp() const;
  void UpdateTimerAndInputTimestamp();

  Member<LocalFrameView> frame_view_;
  bool is_active_;
  bool enable_m90_improvements_;

  // The document cumulative layout shift (DCLS) score for this LocalFrame,
  // unweighted, with move distance applied.
  double score_;

  // The cumulative layout shift score for this LocalFrame, with each increase
  // weighted by the extent to which the LocalFrame visibly occupied the main
  // frame at the time the shift occurred, e.g. x0.5 if the subframe occupied
  // half of the main frame's reported size; see SubframeWeightingFactor().
  double weighted_score_;

  // Stores information related to buffering layout shifts after pointerdown.
  // We accumulate score deltas in this object until we know whether the
  // pointerdown should be treated as a tap (triggering layout shift exclusion)
  // or a scroll (not triggering layout shift exclusion).  Once the correct
  // treatment is known, the pending layout shifts are reported appropriately
  // and the PointerdownPendingData object is reset.
  struct PointerdownPendingData {
    PointerdownPendingData()
        : saw_pointerdown(false), score_delta(0), weighted_score_delta(0) {}
    bool saw_pointerdown;
    double score_delta;
    double weighted_score_delta;
  };

  PointerdownPendingData pointerdown_pending_data_;

  // The per-animation-frame impact region.
  LayoutShiftRegion region_;

  // Tracks the short period after an input event during which we ignore shifts
  // for the purpose of cumulative scoring, and report them to the web perf API
  // with hadRecentInput == true.
  HeapTaskRunnerTimer<LayoutShiftTracker> timer_;

  // The maximum distance any layout object has moved in the current animation
  // frame.
  float frame_max_distance_;

  // The maximum distance any layout object has moved, across all animation
  // frames.
  float overall_max_distance_;

  // Sum of all scroll deltas that occurred in the current animation frame.
  // TODO(wangxianzhu): Remove when enabling CLSM90Improvements permanently.
  ScrollOffset frame_scroll_delta_;

  // Whether either a user input or document scroll have been observed during
  // the session. (This is only tracked so UkmPageLoadMetricsObserver to report
  // LayoutInstability.CumulativeShiftScore.MainFrame.BeforeInputOrScroll. It's
  // not related to input exclusion or the LayoutShift::had_recent_input_ bit.)
  bool observed_input_or_scroll_;

  // Most recent timestamp of a user input event that has been observed.
  // User input includes window resizing but not scrolling.
  base::TimeTicks most_recent_input_timestamp_;
  bool most_recent_input_timestamp_initialized_;

  struct Attribution {
    DOMNodeId node_id;
    IntRect old_visual_rect;
    IntRect new_visual_rect;

    Attribution();
    Attribution(DOMNodeId node_id,
                IntRect old_visual_rect,
                IntRect new_visual_rect);

    explicit operator bool() const;
    bool Encloses(const Attribution&) const;
    bool MoreImpactfulThan(const Attribution&) const;
    int Area() const;
  };

  void MaybeRecordAttribution(const Attribution&);

  // Nodes that have contributed to the impact region for the current frame.
  std::array<Attribution, LayoutShift::kMaxAttributions> attributions_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_SHIFT_TRACKER_H_
