<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import UIKit
import SnapKit

private let ToolbarBaseAnimationDuration: CGFloat = 0.2

class BraveBrowserScrollController: NSObject {
  enum ScrollDirection {
    case Up
    case Down
  }

  enum ToolbarState {
    case Collapsed
    case Visible
    case Animating
  }

  weak var browser: Browser? {
    willSet {
      self.scrollView?.delegate = nil
      self.scrollView?.removeGestureRecognizer(panGesture)
    }

    didSet {
      guard let scrollView = self.scrollView else { return }
      scrollView.addGestureRecognizer(panGesture)
      scrollView.delegate = self
      setupInsetsForTransparentBars(show: true)
    }
  }

  weak var header: UIView?
  weak var footer: UIView?
  weak var urlBar: URLBarView?
  weak var snackBars: UIView?

  var footerBottomConstraint: Constraint?
  // TODO: Since SnapKit hasn't added support yet (Swift 2.0/iOS 9) for handling layoutGuides,
  // this constraint uses the system abstraction instead of SnapKit's Constraint class
  var headerTopConstraint: NSLayoutConstraint?
  var toolbarsShowing: Bool { return headerTopOffset == 0 }

  private var headerTopOffset: CGFloat = 0 {
    didSet {
      headerTopConstraint?.constant = headerTopOffset
      header?.superview?.setNeedsLayout()
    }
  }

  private var footerBottomOffset: CGFloat = 0 {
    didSet {
      footerBottomConstraint?.updateOffset(footerBottomOffset)
      footer?.superview?.setNeedsLayout()
    }
  }

  private lazy var panGesture: UIPanGestureRecognizer = {
    let panGesture = UIPanGestureRecognizer(target: self, action: "handlePan:")
    panGesture.maximumNumberOfTouches = 1
    panGesture.delegate = self
    return panGesture
  }()

  private var scrollView: UIScrollView? { return browser?.webView?.scrollView }
  private var contentOffset: CGPoint { return scrollView?.contentOffset ?? CGPointZero }
  private var contentHeight: CGFloat {
    let height = browser?.webView?.sizeThatFits(CGSizeMake(1, 1)).height
    return height ?? 0.0
  }
  private var scrollViewHeight: CGFloat { return scrollView?.frame.height ?? 0 }
  private var headerFrame: CGRect { return header?.frame ?? CGRectZero }
  private var footerFrame: CGRect { return footer?.frame ?? CGRectZero }
  private var snackBarsFrame: CGRect { return snackBars?.frame ?? CGRectZero }

  private var lastContentOffset: CGFloat = 0
  private var scrollDirection: ScrollDirection = .Down
  private var toolbarState: ToolbarState = .Visible

  override init() {
    super.init()
  }

  func showToolbars(animated animated: Bool, completion: ((finished: Bool) -> Void)? = nil) {
    if (toolbarState == .Visible) {
      return
    }

    let durationRatio = abs(headerTopOffset / headerFrame.height)
    let actualDuration = NSTimeInterval(ToolbarBaseAnimationDuration * durationRatio)
    self.animateToolbarsWithOffsets(
      animated: animated,
      duration: actualDuration,
      headerOffset: 0,
      footerOffset: 0,
      changeInsets: true,
      alpha: 1,
      completion: completion)
  }

  func hideToolbars(animated animated: Bool, completion: ((finished: Bool) -> Void)? = nil) {
    if (toolbarState == .Collapsed) {
      return
    }

    toolbarState = .Collapsed
    let durationRatio = abs((headerFrame.height + headerTopOffset) / headerFrame.height)
    let actualDuration = NSTimeInterval(ToolbarBaseAnimationDuration * durationRatio)
    self.animateToolbarsWithOffsets(
      animated: animated,
      duration: actualDuration,
      headerOffset: -headerFrame.height,
      footerOffset: footerFrame.height - snackBarsFrame.height,
      changeInsets: true,
      alpha: 0,
      completion: completion)
  }

  override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
//    if keyPath == "contentSize" {
//      if !checkScrollHeightIsLargeEnoughForScrolling() && !toolbarsShowing {
//        showToolbars(animated: true, completion: nil)
//      }
//    }
  }


  func setupInsetsForTransparentBars(show show: Bool) {
    let insetHeight = show ? CGFloat(UIConstants.ToolbarHeight) : 0
    guard let scrollView = self.scrollView else { return }
    if (scrollView.contentInset.top != insetHeight) {<commit_msg>Ensuring toolbar doesn't hide if the content is too small to scroll. google news seems to be working<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import UIKit
import SnapKit

private let ToolbarBaseAnimationDuration: CGFloat = 0.2

class BraveBrowserScrollController: NSObject {
  enum ScrollDirection {
    case Up
    case Down
  }

  enum ToolbarState {
    case Collapsed
    case Visible
    case Animating
  }

  weak var browser: Browser? {
    willSet {
      self.scrollView?.delegate = nil
      self.scrollView?.removeGestureRecognizer(panGesture)
    }

    didSet {
      guard let scrollView = self.scrollView else { return }
      scrollView.addGestureRecognizer(panGesture)
      scrollView.delegate = self
    }
  }

  weak var header: UIView?
  weak var footer: UIView?
  weak var urlBar: URLBarView?
  weak var snackBars: UIView?

  var footerBottomConstraint: Constraint?
  // TODO: Since SnapKit hasn't added support yet (Swift 2.0/iOS 9) for handling layoutGuides,
  // this constraint uses the system abstraction instead of SnapKit's Constraint class
  var headerTopConstraint: NSLayoutConstraint?
  var toolbarsShowing: Bool { return headerTopOffset == 0 }

  private var headerTopOffset: CGFloat = 0 {
    didSet {
      headerTopConstraint?.constant = headerTopOffset
      header?.superview?.setNeedsLayout()
    }
  }

  private var footerBottomOffset: CGFloat = 0 {
    didSet {
      footerBottomConstraint?.updateOffset(footerBottomOffset)
      footer?.superview?.setNeedsLayout()
    }
  }

  private lazy var panGesture: UIPanGestureRecognizer = {
    let panGesture = UIPanGestureRecognizer(target: self, action: "handlePan:")
    panGesture.maximumNumberOfTouches = 1
    panGesture.delegate = self
    return panGesture
  }()

  private var scrollView: UIScrollView? { return browser?.webView?.scrollView }
  private var contentOffset: CGPoint { return scrollView?.contentOffset ?? CGPointZero }
  private var contentHeight: CGFloat {
    let height = browser?.webView?.sizeThatFits(CGSizeMake(1, 1)).height
    return height ?? 0.0
  }
  private var scrollViewHeight: CGFloat { return scrollView?.frame.height ?? 0 }
  private var headerFrame: CGRect { return header?.frame ?? CGRectZero }
  private var footerFrame: CGRect { return footer?.frame ?? CGRectZero }
  private var snackBarsFrame: CGRect { return snackBars?.frame ?? CGRectZero }

  private var lastContentOffset: CGFloat = 0
  private var scrollDirection: ScrollDirection = .Down
  private var toolbarState: ToolbarState = .Visible

  override init() {
    super.init()
  }

  func showToolbars(animated animated: Bool, completion: ((finished: Bool) -> Void)? = nil) {
    if (toolbarState == .Visible) {
      return
    }

    let durationRatio = abs(headerTopOffset / headerFrame.height)
    let actualDuration = NSTimeInterval(ToolbarBaseAnimationDuration * durationRatio)
    self.animateToolbarsWithOffsets(
      animated: animated,
      duration: actualDuration,
      headerOffset: 0,
      footerOffset: 0,
      changeInsets: true,
      alpha: 1,
      completion: completion)
  }

  func hideToolbars(animated animated: Bool, completion: ((finished: Bool) -> Void)? = nil) {
    if (toolbarState == .Collapsed) {
      return
    }

    toolbarState = .Collapsed
    let durationRatio = abs((headerFrame.height + headerTopOffset) / headerFrame.height)
    let actualDuration = NSTimeInterval(ToolbarBaseAnimationDuration * durationRatio)
    self.animateToolbarsWithOffsets(
      animated: animated,
      duration: actualDuration,
      headerOffset: -headerFrame.height,
      footerOffset: footerFrame.height - snackBarsFrame.height,
      changeInsets: true,
      alpha: 0,
      completion: completion)
  }

  override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    if keyPath == "contentSize" {
      if browserIsLoading() ||
        scrollViewHeight >= contentHeight {
        setupInsetsForTransparentBars(show: true)
      }
    }
  }


  func setupInsetsForTransparentBars(show show: Bool) {
    let insetHeight = show ? CGFloat(UIConstants.ToolbarHeight) : 0
    guard let scrollView = self.scrollView else { return }
    if (scrollView.contentInset.top != insetHeight) {
{'fraction_non_alphanumeric': 0.08640591729239046, 'fraction_numerical': 0.005379356718592402, 'mean_word_length': 3.592897581060216, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2137079', 'n_tokens_mistral': 2729, 'n_tokens_neox': 2532, 'n_words': 720}