<commit_before>import { Directive, ElementRef, Renderer2, Input } from '@angular/core';

/**
 * Angular Lazy Loading Images Directive
 *
 * Directive to easily allow to lazy load the images
 * that your application/PWA contains using MutationObserver
 * and the praised IntersectionObserver.
 *
 * How does it work?
 *
 * You only need to include the directive in the container node
 * that holds all the images you want to lazy load. It supports
 * <img> tags, as well as background images in any HTML node.
 *
 * Example
 *
 * <div class="container" ngx-lazy-load>
 *  <img attr.data-src="img/logo.png">
 *  <div class="thumbnail" attr.data-background-src="{{ background_image }}"></div>
 * </div>
 */
@Directive({
  selector: '[ngx-lazy-load]' // Attribute selector
})
export class LazyLoadingDirective {

  @Input('ngx-lazy-load') intersectionObserverConfig: Object;

  intersectionObserverSupported: Boolean = false;
  intersectionObserver: IntersectionObserver;
  rootElement: HTMLElement;
  renderer: Renderer2;

  constructor(element: ElementRef, renderer: Renderer2) {
    this.intersectionObserverSupported = 'IntersectionObserver' in window;
    this.rootElement = element.nativeElement;
    this.renderer = renderer;
  }

  ngOnInit() {
    this.registerIntersectionObserver();

    this.observeDOMChanges(this.rootElement, () => {
      const imagesFoundInDOM = this.getAllImagesToLazyLoad(this.rootElement);

      // Why can't I use rest operator instead forEach?
      // this.intersectionObserver.observe(...imagesFoundInDOM);

      imagesFoundInDOM.forEach((element: HTMLElement) => this.intersectionObserver.observe(element));
    });
  }

  registerIntersectionObserver() {
    if (!this.intersectionObserverSupported) {
      // Load polyfill for unsupported Browsers
      console.error('IntersectionObserver is not supported in this browser');

      // Insection Observer Polyfill
      // https://github.com/WICG/IntersectionObserver/tree/gh-pages/polyfill
      // The browser hangs up when importing this code, don't know why

      // https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver
    }

    this.intersectionObserver = new IntersectionObserver(
      images => images.forEach(image => this.onIntersectionChange(image)),
      this.intersectionObserverConfig instanceof Object ? this.intersectionObserverConfig : undefined
    );

    return this.intersectionObserver;
  }

  observeDOMChanges(rootElement: HTMLElement, onChange: Function) {
    // Create a Mutation Observer instance
    const observer = new MutationObserver(mutations => onChange(mutations));

    // Observer Configuration
    const observerConfig = {
      attributes: true,
      characterData: true,
      childList: true
    };

    // Observe Directive DOM Node
    observer.observe(rootElement, observerConfig);

    return observer;
  }

  getAllImagesToLazyLoad(pageNode: HTMLElement) {
    let images = [];
    let imagesToLazyLoad = pageNode.querySelectorAll('img[data-src], [data-background-src]');

    for (let i = 0; i < imagesToLazyLoad.length; i++) {
      images.push(imagesToLazyLoad[i]);
    }

    return images;
  }

  onIntersectionChange(image: any) {
    if (!image.isIntersecting) {
      return;<commit_msg>Directive: Latest Changes<commit_after>import { Directive, ElementRef, Renderer2, Input, NgZone } from '@angular/core';
import 'intersection-observer';

/**
 * Angular Lazy Loading Images Directive
 *
 * Directive to easily allow to lazy load the images
 * that your application/PWA contains using MutationObserver
 * and the praised IntersectionObserver.
 *
 * How does it work?
 *
 * You only need to include the directive in the container node
 * that holds all the images you want to lazy load. It supports
 * <img> tags, as well as background images in any HTML node.
 *
 * Example
 *
 * <div class="container" image-lazy-load>
 *  <img attr.data-src="img/logo.png">
 *  <div class="thumbnail" attr.data-background-src="{{ background_image }}"></div>
 * </div>
 */
@Directive({
  selector: '[image-lazy-load]' // Attribute selector
})
export class LazyLoadingDirective {

  @Input('image-lazy-load') intersectionObserverConfig: Object;

  intersectionObserverSupported: Boolean = false;
  intersectionObserver: IntersectionObserver;
  rootElement: HTMLElement;

  constructor(element: ElementRef, public renderer: Renderer2, public ngZone: NgZone) {
    this.intersectionObserverSupported = 'IntersectionObserver' in window;
    this.rootElement = element.nativeElement;
  }

  init() {
    this.registerIntersectionObserver();

    this.observeDOMChanges(this.rootElement, () => {
      const imagesFoundInDOM = this.getAllImagesToLazyLoad(this.rootElement);
      imagesFoundInDOM.forEach((image: HTMLElement) => this.intersectionObserver.observe(image));
    });
  }

  ngOnInit() {
    this.ngZone.runOutsideAngular(() => this.init());
  }

  registerIntersectionObserver() {
    this.intersectionObserver = new IntersectionObserver(
      images => images.forEach(image => this.onIntersectionChange(image)),
      this.intersectionObserverConfig instanceof Object ? this.intersectionObserverConfig : undefined
    );

    return this.intersectionObserver;
  }

  observeDOMChanges(rootElement: HTMLElement, onChange: Function) {
    // Create a Mutation Observer instance
    const observer = new MutationObserver(mutations => onChange(mutations));

    // Observer Configuration
    const observerConfig = {
      attributes: true,
      characterData: true,
      childList: true
    };

    // Observe Directive DOM Node
    observer.observe(rootElement, observerConfig);

    return observer;
  }

  getAllImagesToLazyLoad(pageNode: HTMLElement) {
    return Array.from(pageNode.querySelectorAll('img[data-src], [data-background-src]'));
  }

  onIntersectionChange(image: any) {
    if (!image.isIntersecting) {
      return;
{'fraction_non_alphanumeric': 0.10670059372349448, 'fraction_numerical': 0.0011874469889737065, 'mean_word_length': 3.9966101694915253, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 26, 'https://': 2, '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': '4027011', 'n_tokens_mistral': 1680, 'n_tokens_neox': 1642, 'n_words': 415}