<commit_before>import { Injectable, Inject } from '@angular/core';
import { Location, PlatformLocation, ViewportScroller } from '@angular/common';
import { DOCUMENT } from '@angular/common';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

export const topMargin = 16;
/**
 * A service that scrolls document elements into view
 */
@Injectable()
export class ScrollService {

  private _topOffset: number | null;
  private _topOfPageElement: Element;

  // true when popState event has been fired.
  popStateFired = false;
  // scroll position which has to be restored after the popState event
  scrollPosition: [number, number] = [0, 0];
  // true when the browser supports `scrollTo`, `scrollX`, `scrollY` and `scrollRestoration`
  supportManualScrollRestoration: boolean;

  // Offset from the top of the document to bottom of any static elements
  // at the top (e.g. toolbar) + some margin
  get topOffset() {
    if (!this._topOffset) {
      const toolbar = this.document.querySelector('.app-toolbar');
      this._topOffset = (toolbar && toolbar.clientHeight || 0) + topMargin;
    }
    return this._topOffset!;
  }

  get topOfPageElement() {
    if (!this._topOfPageElement) {
      this._topOfPageElement = this.document.getElementById('top-of-page') || this.document.body;
    }
    return this._topOfPageElement;
  }

  constructor(
      @Inject(DOCUMENT) private document: any,
      private platformLocation: PlatformLocation,
      private viewportScroller: ViewportScroller,
      private location: Location) {
    // On resize, the toolbar might change height, so "invalidate" the top offset.
    fromEvent(window, 'resize').subscribe(() => this._topOffset = null);

    fromEvent(window, 'scroll')
      .pipe(debounceTime(250)).subscribe(() => this.updateScrollPositionInHistory());

    try {
      this.supportManualScrollRestoration = !!window && !!window.scrollTo && 'scrollX' in window
        && 'scrollY' in window && !!history && !!history.scrollRestoration;
    } catch {
      this.supportManualScrollRestoration = false;
    }

    // Change scroll restoration strategy to `manual` if it's supported
    if (this.supportManualScrollRestoration) {
      history.scrollRestoration = 'manual';
      // we have to detect forward and back navigation thanks to popState event
      this.location.subscribe(event => {
        // the type is `hashchange` when the fragment identifier of the URL has changed. It allows us to go to position<commit_msg>fix(docs-infra): remove the try catch in the test of the browser's capacities (#28368)<commit_after>import { Injectable, Inject } from '@angular/core';
import { Location, PlatformLocation, ViewportScroller } from '@angular/common';
import { DOCUMENT } from '@angular/common';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

export const topMargin = 16;
/**
 * A service that scrolls document elements into view
 */
@Injectable()
export class ScrollService {

  private _topOffset: number | null;
  private _topOfPageElement: Element;

  // true when popState event has been fired.
  popStateFired = false;
  // scroll position which has to be restored after the popState event
  scrollPosition: [number, number] = [0, 0];
  // true when the browser supports `scrollTo`, `scrollX`, `scrollY` and `scrollRestoration`
  supportManualScrollRestoration: boolean;

  // Offset from the top of the document to bottom of any static elements
  // at the top (e.g. toolbar) + some margin
  get topOffset() {
    if (!this._topOffset) {
      const toolbar = this.document.querySelector('.app-toolbar');
      this._topOffset = (toolbar && toolbar.clientHeight || 0) + topMargin;
    }
    return this._topOffset!;
  }

  get topOfPageElement() {
    if (!this._topOfPageElement) {
      this._topOfPageElement = this.document.getElementById('top-of-page') || this.document.body;
    }
    return this._topOfPageElement;
  }

  constructor(
      @Inject(DOCUMENT) private document: any,
      private platformLocation: PlatformLocation,
      private viewportScroller: ViewportScroller,
      private location: Location) {
    // On resize, the toolbar might change height, so "invalidate" the top offset.
    fromEvent(window, 'resize').subscribe(() => this._topOffset = null);

    fromEvent(window, 'scroll')
      .pipe(debounceTime(250)).subscribe(() => this.updateScrollPositionInHistory());

    this.supportManualScrollRestoration = !!window && 'scrollTo' in window && 'scrollX' in window
      && 'scrollY' in window && !!history && 'scrollRestoration' in history;

    // Change scroll restoration strategy to `manual` if it's supported
    if (this.supportManualScrollRestoration) {
      history.scrollRestoration = 'manual';
      // we have to detect forward and back navigation thanks to popState event
      this.location.subscribe(event => {
        // the type is `hashchange` when the fragment identifier of the URL has changed. It allows us to go to position
{'fraction_non_alphanumeric': 0.10838323353293414, 'fraction_numerical': 0.004191616766467066, 'mean_word_length': 3.7814885496183206, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '6522600', 'n_tokens_mistral': 1412, 'n_tokens_neox': 1359, 'n_words': 453}