Uname: Linux webm016.cluster127.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
Software: Apache
PHP version: 7.4.33 [ PHP INFO ] PHP os: Linux
Server Ip: 54.36.31.145
Your Ip: 216.73.216.182
User: homesquasz (91404) | Group: users (100)
Safe Mode: OFF
Disable Function:
_dyuweyrj4,_dyuweyrj4r,dl

name : Filterizr.ts
import { FILTERIZR_STATE } from '../config';
import { Filter } from '../types';
import { RawOptions, Destructible, Dimensions } from '../types/interfaces';
import { getHTMLElement, debounce } from '../utils';
import EventReceiver from '../EventReceiver';
import FilterizrOptions, { defaultOptions } from '../FilterizrOptions';
import FilterControls from '../FilterControls';
import FilterContainer from '../FilterContainer';
import FilterItems from '../FilterItems';
import FilterItem from '../FilterItem';
import Spinner from '../Spinner';
import makeLayoutPositions from '../makeLayoutPositions';
import installAsJQueryPlugin from './installAsJQueryPlugin';

const imagesLoaded = require('imagesloaded');

export default class Filterizr implements Destructible {
  /**
   * Main Filterizr classes exported as static members
   */
  public static FilterContainer = FilterContainer;
  public static FilterItem = FilterItem;
  public static defaultOptions = defaultOptions;
  /**
   * Static method that receives the jQuery object and extends
   * its prototype with a .filterizr method.
   */
  public static installAsJQueryPlugin: Function = installAsJQueryPlugin;

  public options: FilterizrOptions;

  private windowEventReceiver: EventReceiver;
  private filterContainer: FilterContainer;
  private filterControls?: FilterControls;
  private imagesHaveLoaded: boolean;
  private spinner?: Spinner;

  public constructor(
    selectorOrNode: string | HTMLElement = '.filtr-container',
    userOptions: RawOptions = {}
  ) {
    this.options = new FilterizrOptions(userOptions);

    const {
      areControlsEnabled,
      controlsSelector,
      isSpinnerEnabled,
    } = this.options;

    this.windowEventReceiver = new EventReceiver(window);
    this.filterContainer = new FilterContainer(
      getHTMLElement(selectorOrNode),
      this.options
    );
    this.imagesHaveLoaded = !this.filterContainer.node.querySelectorAll('img')
      .length;

    if (areControlsEnabled) {
      this.filterControls = new FilterControls(this, controlsSelector);
    }
    if (isSpinnerEnabled) {
      this.spinner = new Spinner(this.filterContainer, this.options);
    }

    this.initialize();
  }

  private get filterItems(): FilterItems {
    return this.filterContainer.filterItems;
  }

  /**
   * Filters the items in the grid by a category
   * @param category by which to filter
   */
  public filter(category: Filter): void {
    const { filterContainer } = this;

    filterContainer.trigger('filteringStart');
    filterContainer.filterizrState = FILTERIZR_STATE.FILTERING;

    category = Array.isArray(category)
      ? category.map((c): string => c.toString())
      : category.toString();

    this.options.filter = category;
    this.render();
  }

  public destroy(): void {
    const { windowEventReceiver, filterControls, filterContainer } = this;
    filterContainer.destroy();
    windowEventReceiver.destroy();
    if (this.options.areControlsEnabled && filterControls) {
      filterControls.destroy();
    }
  }

  /**
   * Inserts a new FilterItem into the grid
   */
  public async insertItem(node: HTMLElement): Promise<void> {
    const { filterContainer } = this;
    filterContainer.insertItem(node);
    await this.waitForImagesToLoad();
    this.render();
  }

  /**
   * Removes a FilterItem from the grid
   */
  public removeItem(node: HTMLElement): void {
    const { filterContainer } = this;
    filterContainer.removeItem(node);
    this.render();
  }

  /**
   * Sorts the FilterItems in the grid
   * @param sortAttr the attribute by which to perform the sort
   * @param sortOrder ascending or descending
   */
  public sort(
    sortAttr: string = 'index',
    sortOrder: 'asc' | 'desc' = 'asc'
  ): void {
    const { filterContainer, filterItems } = this;
    filterContainer.trigger('sortingStart');
    filterContainer.filterizrState = FILTERIZR_STATE.SORTING;
    filterItems.sort(sortAttr, sortOrder);
    this.render();
  }

  /**
   * Searches through the FilterItems for a given string and adds an additional filter layer.
   */
  public search(searchTerm: string = this.options.get().searchTerm): void {
    this.options.searchTerm = searchTerm.toLowerCase();
    this.render();
  }

  /**
   * Shuffles the FilterItems in the grid, making sure their positions have changed.
   */
  public shuffle(): void {
    const { filterContainer, filterItems } = this;
    filterContainer.trigger('shufflingStart');
    filterContainer.filterizrState = FILTERIZR_STATE.SHUFFLING;
    filterItems.shuffle();
    this.render();
  }

  /**
   * Updates the perferences of the users for rendering the Filterizr grid,
   * additionally performs error checking on the new options passed.
   * @param newOptions to override the defaults.
   */
  public setOptions(newOptions: RawOptions): void {
    const { filterContainer, filterItems } = this;
    const animationPropIsSet =
      'animationDuration' in newOptions ||
      'delay' in newOptions ||
      'delayMode' in newOptions;

    if (newOptions.callbacks || animationPropIsSet) {
      // Remove old callbacks before setting the new ones in the options
      filterContainer.unbindEvents();
    }

    this.options.set(newOptions);

    if (newOptions.easing || animationPropIsSet) {
      filterItems.styles.updateTransitionStyle();
    }

    if (newOptions.callbacks || animationPropIsSet) {
      filterContainer.bindEvents();
    }

    if ('searchTerm' in newOptions) {
      this.search(newOptions.searchTerm);
    }

    if (
      'filter' in newOptions ||
      'multifilterLomultifilterLogicalOperator' in newOptions
    ) {
      this.filter(this.options.filter);
    }

    if ('gutterPixels' in newOptions) {
      this.filterContainer.styles.updatePaddings();
      this.filterItems.styles.updateWidthWithTransitionsDisabled();
      this.render();
    }
  }

  /**
   * Performs multifiltering with AND/OR logic.
   * @param toggledFilter the filter to toggle
   */
  public toggleFilter(toggledFilter: string): void {
    this.options.toggleFilter(toggledFilter);
    this.filter(this.options.filter);
  }

  private render(): void {
    const { filterContainer, filterItems, options } = this;
    const itemsToFilterIn = filterItems.getFiltered(options.filter);

    filterItems.styles.resetDisplay();

    filterItems.getFilteredOut(options.filter).forEach((filterItem): void => {
      filterItem.filterOut();
    });

    const { containerHeight, itemsPositions } = makeLayoutPositions(
      filterContainer.dimensions.width,
      itemsToFilterIn.map(({ dimensions }): Dimensions => dimensions),
      this.options.get()
    );
    filterContainer.setHeight(containerHeight);

    itemsToFilterIn.forEach((filterItem, index): void => {
      filterItem.filterIn(itemsPositions[index]);
    });
  }

  /**
   * Initialization sequence of Filterizr when the grid is first loaded
   */
  private async initialize(): Promise<void> {
    const { filterContainer, filterItems, spinner } = this;
    this.bindEvents();
    await this.waitForImagesToLoad();
    if (this.options.isSpinnerEnabled) {
      // The spinner will first fade out (opacity: 0) before being removed
      await spinner.destroy();
    }
    // Enable animations after the initial render, to let
    // the items assume their positions before animating
    this.render();
    await filterItems.styles.enableTransitions();
    filterContainer.trigger('init');
  }

  private bindEvents(): void {
    const { filterItems, windowEventReceiver } = this;
    windowEventReceiver.on('resize', debounce(
      (): void => {
        filterItems.styles.updateWidthWithTransitionsDisabled();
        this.render();
      },
      50,
      false
    ) as EventListener);
  }

  /**
   * Resolves when the images of the grid have finished loading into the DOM
   */
  private async waitForImagesToLoad(): Promise<void> {
    const { imagesHaveLoaded, filterContainer } = this;
    if (imagesHaveLoaded) {
      return Promise.resolve();
    }
    return new Promise((resolve): void => {
      imagesLoaded(filterContainer.node, (): void => {
        this.imagesHaveLoaded = true;
        resolve();
      });
    });
  }
}
© 2026 GrazzMean