1 // Copyright 2020 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_FRAME_TRACKER_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_FRAME_TRACKER_H_ 7 8 #include "third_party/blink/renderer/core/core_export.h" 9 #include "third_party/blink/renderer/platform/geometry/int_point.h" 10 #include "third_party/blink/renderer/platform/wtf/deque.h" 11 12 namespace blink { 13 14 // Keeps track of the viewport position of a frame. 15 // 16 // This is for catching ads that don't follow the Better Ads Standard -- 17 // https://www.betterads.org/desktop-large-sticky-ad/. 18 // 19 // The heuristic for "sticky" is as follows: 20 // 21 // Given the latest two pairs of main frame scroll offset and frame's position 22 // wrt viewport (a.k.a. viewport offset), if the two main frame scroll offsets 23 // differ while the viewport offsets are the same, the frame is considered 24 // sticky. 25 // 26 // In addition, we store the latest 10 (|kNumScrollEvents|) main frame scroll 27 // offsets and viewport offsets, and keep comparing their range. For the latest 28 // 10 recordings, if the frame has a viewport offsets range smaller than 0.5 29 // (|kStickyFrameOffsetsRangeToScrollOffsetsRangeThreshold|) of the main frame 30 // scroll offsets range, then it's considered sticky as well. 31 // 32 // Right now we only consider offsets on the vertical dimension. The 33 // implementation can be extended to cover both dimensions if needed. 34 class CORE_EXPORT StickyFrameTracker { 35 public: 36 // Returns whether the |frame_size| is considered large compared to 37 // |main_frame_viewport_size|. 38 static bool IsLarge(const IntSize& main_frame_viewport_size, 39 const IntSize& frame_size); 40 41 StickyFrameTracker() = default; 42 StickyFrameTracker(const StickyFrameTracker&) = delete; 43 ~StickyFrameTracker() = default; 44 45 // Called when the frame's position with respect to the viewport may have 46 // changed. Returns whether the frame is sticky. |main_frame_scroll_offset| 47 // is the scroll position in the main page. |viewport_offset| is the position 48 // of the top-left corner of this frame (every StickyFrameTracker will only be 49 // tracking one frame) relative to the browser viewport. 50 bool UpdateStickyStatus(const IntPoint& main_frame_scroll_offset, 51 const IntPoint& viewport_offset); 52 53 private: 54 void SetSticky(); 55 56 bool is_sticky_ = false; 57 Deque<int> viewport_offsets_; 58 Deque<int> main_frame_scroll_offsets_; 59 }; 60 61 } // namespace blink 62 63 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_STICKY_FRAME_TRACKER_H_ 64