%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /var/www/html/node_modules/react-cookie-consent/src/
Upload File :
Create Path :
Current File : //var/www/html/node_modules/react-cookie-consent/src/index.js

import React, { Component } from "react";
import PropTypes from "prop-types";
import Cookies from "js-cookie";

export const OPTIONS = {
  TOP: "top",
  BOTTOM: "bottom",
  NONE: "none",
};

export const SAME_SITE_OPTIONS = {
  STRICT: "strict",
  LAX: "lax",
  NONE: "none",
};

export const VISIBLE_OPTIONS = {
  HIDDEN: "hidden",
  SHOW: "show",
  BY_COOKIE_VALUE: "byCookieValue",
};

/**
 * Returns the value of the consent cookie
 * Retrieves the regular value first and if not found the legacy one according
 * to: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
 * @param {*} name optional name of the cookie
 */
export const getCookieConsentValue = (name = defaultCookieConsentName) => {
  const cookieValue = Cookies.get(name);

  // if the cookieValue is undefined check for the legacy cookie
  if (cookieValue === undefined) {
    return Cookies.get(getLegacyCookieName(name));
  }
  return cookieValue;
};

/**
 * Reset the consent cookie
 * Remove the cookie on browser in order to allow user to change their consent
 * @param {*} name optional name of the cookie
 */
export const resetCookieConsentValue = (name = defaultCookieConsentName) => {
  Cookies.remove(name);
};

/**
 * Get the legacy cookie name by the regular cookie name
 * @param {string} name of cookie to get
 */
const getLegacyCookieName = (name) => {
  return `${name}-legacy`;
};

/**
 * Default name of the cookie which is set by CookieConsent
 */
const defaultCookieConsentName = "CookieConsent";

/**
 * A function to wrap elements with a "wrapper" on a condition
 * @param {object} wrappingOptions
 *  condition == boolean condition, when to wrap
 *  wrapper == style to wrap. e.g <div>{children}</div>
 *  children == react passes whatever is between tags as children. Don't supply this yourself.
 */
const ConditionalWrapper = ({ condition, wrapper, children }) => {
  return condition ? wrapper(children) : children;
};

class CookieConsent extends Component {
  constructor(props) {
    super(props);

    this.state = {
      visible: false,
      style: {
        alignItems: "baseline",
        background: "#353535",
        color: "white",
        display: "flex",
        flexWrap: "wrap",
        justifyContent: "space-between",
        left: "0",
        position: "fixed",
        width: "100%",
        zIndex: "999",
      },
      buttonStyle: {
        background: "#ffd42d",
        border: "0",
        borderRadius: "0px",
        boxShadow: "none",
        color: "black",
        cursor: "pointer",
        flex: "0 0 auto",
        padding: "5px 10px",
        margin: "15px",
      },
      declineButtonStyle: {
        background: "#c12a2a",
        border: "0",
        borderRadius: "0px",
        boxShadow: "none",
        color: "#e5e5e5",
        cursor: "pointer",
        flex: "0 0 auto",
        padding: "5px 10px",
        margin: "15px",
      },
      contentStyle: {
        flex: "1 0 300px",
        margin: "15px",
      },
      overlayStyle: {
        position: "fixed",
        left: 0,
        top: 0,
        width: "100%",
        height: "100%",
        zIndex: "999",
        backgroundColor: "rgba(0,0,0,0.3)",
      },
    };
  }

  componentDidMount() {
    const { debug } = this.props;

    // if cookie undefined or debug
    if (this.getCookieValue() === undefined || debug) {
      this.setState({ visible: true });
      // if acceptOnScroll is set to true and (cookie is undefined or debug is set to true), add a listener.
      if (this.props.acceptOnScroll) {
        window.addEventListener("scroll", this.handleScroll, { passive: true });
      }
    }
  }

  componentWillUnmount() {
    // remove listener if still set
    this.removeScrollListener();
  }

  /**
   * Set a persistent accept cookie
   */
  accept(acceptedByScrolling = false) {
    const { cookieName, cookieValue, hideOnAccept, onAccept } = this.props;

    this.setCookie(cookieName, cookieValue);

    onAccept(acceptedByScrolling ?? false);

    if (hideOnAccept) {
      this.setState({ visible: false });
      this.removeScrollListener();
    }
  }

  /**
   * Handle a click on the overlay
   */
  overlayClick() {
    const { acceptOnOverlayClick, onOverlayClick } = this.props;
    if (acceptOnOverlayClick) {
      this.accept();
    }
    onOverlayClick();
  }

  /**
   * Set a persistent decline cookie
   */
  decline() {
    const { cookieName, declineCookieValue, hideOnDecline, onDecline, setDeclineCookie } =
      this.props;

    if (setDeclineCookie) {
      this.setCookie(cookieName, declineCookieValue);
    }

    onDecline();

    if (hideOnDecline) {
      this.setState({ visible: false });
    }
  }

  /**
   * Function to set the consent cookie based on the provided variables
   * Sets two cookies to handle incompatible browsers, more details:
   * https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
   */
  setCookie(cookieName, cookieValue) {
    const { extraCookieOptions, expires, sameSite } = this.props;
    let { cookieSecurity } = this.props;

    if (cookieSecurity === undefined) {
      cookieSecurity = location ? location.protocol === "https:" : true;
    }

    const cookieOptions = { expires, ...extraCookieOptions, sameSite, secure: cookieSecurity };

    // Fallback for older browsers where can not set SameSite=None, SEE: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
    if (sameSite === SAME_SITE_OPTIONS.NONE) {
      Cookies.set(getLegacyCookieName(cookieName), cookieValue, cookieOptions);
    }

    // set the regular cookie
    Cookies.set(cookieName, cookieValue, cookieOptions);
  }

  /**
   * Returns the value of the consent cookie
   * Retrieves the regular value first and if not found the legacy one according
   * to: https://web.dev/samesite-cookie-recipes/#handling-incompatible-clients
   */
  getCookieValue() {
    const { cookieName } = this.props;
    return getCookieConsentValue(cookieName);
  }

  /**
   * checks whether scroll has exceeded set amount and fire accept if so.
   */
  handleScroll = () => {
    const { acceptOnScrollPercentage } = this.props;

    // (top / height) - height * 100
    const rootNode = document.documentElement,
      body = document.body,
      top = "scrollTop",
      height = "scrollHeight";

    const percentage =
      ((rootNode[top] || body[top]) /
        ((rootNode[height] || body[height]) - rootNode.clientHeight)) *
      100;

    if (percentage > acceptOnScrollPercentage) {
      this.accept(true);
    }
  };

  removeScrollListener = () => {
    const { acceptOnScroll } = this.props;
    if (acceptOnScroll) {
      window.removeEventListener("scroll", this.handleScroll);
    }
  };

  render() {
    // If the bar shouldn't be visible don't render anything.
    switch (this.props.visible) {
      case VISIBLE_OPTIONS.HIDDEN:
        return null;
      case VISIBLE_OPTIONS.BY_COOKIE_VALUE:
        if (!this.state.visible) {
          return null;
        }
        break;
      default:
        break;
    }

    const {
      location,
      style,
      buttonStyle,
      declineButtonStyle,
      contentStyle,
      disableStyles,
      buttonText,
      declineButtonText,
      containerClasses,
      contentClasses,
      buttonClasses,
      buttonWrapperClasses,
      declineButtonClasses,
      buttonId,
      declineButtonId,
      disableButtonStyles,
      enableDeclineButton,
      flipButtons,
      ButtonComponent,
      overlay,
      overlayClasses,
      overlayStyle,
      ariaAcceptLabel,
      ariaDeclineLabel,
      customContainerAttributes,
      customContentAttributes,
      customButtonProps,
    } = this.props;

    let myStyle = {};
    let myButtonStyle = {};
    let myDeclineButtonStyle = {};
    let myContentStyle = {};
    let myOverlayStyle = {};

    if (disableStyles) {
      // if styles are disabled use the provided styles (or none)
      myStyle = Object.assign({}, style);
      myButtonStyle = Object.assign({}, buttonStyle);
      myDeclineButtonStyle = Object.assign({}, declineButtonStyle);
      myContentStyle = Object.assign({}, contentStyle);
      myOverlayStyle = Object.assign({}, overlayStyle);
    } else {
      // if styles aren't disabled merge them with the styles that are provided (or use default styles)
      myStyle = Object.assign({}, { ...this.state.style, ...style });
      myContentStyle = Object.assign({}, { ...this.state.contentStyle, ...contentStyle });
      myOverlayStyle = Object.assign({}, { ...this.state.overlayStyle, ...overlayStyle });

      // switch to disable JUST the button styles
      if (disableButtonStyles) {
        myButtonStyle = Object.assign({}, buttonStyle);
        myDeclineButtonStyle = Object.assign({}, declineButtonStyle);
      } else {
        myButtonStyle = Object.assign({}, { ...this.state.buttonStyle, ...buttonStyle });
        myDeclineButtonStyle = Object.assign(
          {},
          { ...this.state.declineButtonStyle, ...declineButtonStyle }
        );
      }
    }

    // syntactic sugar to enable user to easily select top / bottom
    switch (location) {
      case OPTIONS.TOP:
        myStyle.top = "0";
        break;

      case OPTIONS.BOTTOM:
        myStyle.bottom = "0";
        break;
    }

    const buttonsToRender = [];

    // add decline button
    enableDeclineButton &&
      buttonsToRender.push(
        <ButtonComponent
          key="declineButton"
          style={myDeclineButtonStyle}
          className={declineButtonClasses}
          id={declineButtonId}
          aria-label={ariaDeclineLabel}
          onClick={() => {
            this.decline();
          }}
        >
          {declineButtonText}
        </ButtonComponent>
      );

    // add accept button
    buttonsToRender.push(
      <ButtonComponent
        {...customButtonProps}
        key="acceptButton"
        style={myButtonStyle}
        className={buttonClasses}
        id={buttonId}
        aria-label={ariaAcceptLabel}
        onClick={() => {
          this.accept();
        }}
      >
        {buttonText}
      </ButtonComponent>
    );

    if (flipButtons) {
      buttonsToRender.reverse();
    }

    return (
      <ConditionalWrapper
        condition={overlay}
        wrapper={(children) => (
          <div
            style={myOverlayStyle}
            className={overlayClasses}
            onClick={() => {
              this.overlayClick();
            }}
          >
            {children}
          </div>
        )}
      >
        <div className={`${containerClasses}`} style={myStyle} {...customContainerAttributes}>
          <div style={myContentStyle} className={contentClasses} {...customContentAttributes}>
            {this.props.children}
          </div>
          <div className={`${buttonWrapperClasses}`}>
            {buttonsToRender.map((button) => {
              return button;
            })}
          </div>
        </div>
      </ConditionalWrapper>
    );
  }
}

CookieConsent.propTypes = {
  location: PropTypes.oneOf(Object.keys(OPTIONS).map((key) => OPTIONS[key])),
  visible: PropTypes.oneOf(Object.keys(VISIBLE_OPTIONS).map((key) => VISIBLE_OPTIONS[key])),
  sameSite: PropTypes.oneOf(Object.keys(SAME_SITE_OPTIONS).map((key) => SAME_SITE_OPTIONS[key])),
  style: PropTypes.object,
  buttonStyle: PropTypes.object,
  declineButtonStyle: PropTypes.object,
  contentStyle: PropTypes.object,
  children: PropTypes.any, // eslint-disable-line react/forbid-prop-types
  disableStyles: PropTypes.bool,
  hideOnAccept: PropTypes.bool,
  hideOnDecline: PropTypes.bool,
  onAccept: PropTypes.func,
  onDecline: PropTypes.func,
  buttonText: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.element]),
  declineButtonText: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.element]),
  cookieName: PropTypes.string,
  cookieValue: PropTypes.oneOfType([PropTypes.string, PropTypes.bool, PropTypes.number]),
  declineCookieValue: PropTypes.oneOfType([PropTypes.string, PropTypes.bool, PropTypes.number]),
  setDeclineCookie: PropTypes.bool,
  debug: PropTypes.bool,
  expires: PropTypes.number,
  containerClasses: PropTypes.string,
  contentClasses: PropTypes.string,
  buttonClasses: PropTypes.string,
  buttonWrapperClasses: PropTypes.string,
  declineButtonClasses: PropTypes.string,
  buttonId: PropTypes.string,
  declineButtonId: PropTypes.string,
  extraCookieOptions: PropTypes.object,
  disableButtonStyles: PropTypes.bool,
  enableDeclineButton: PropTypes.bool,
  flipButtons: PropTypes.bool,
  ButtonComponent: PropTypes.elementType,
  cookieSecurity: PropTypes.bool,
  overlay: PropTypes.bool,
  overlayClasses: PropTypes.string,
  overlayStyle: PropTypes.object,
  onOverlayClick: PropTypes.func,
  acceptOnOverlayClick: PropTypes.bool,
  ariaAcceptLabel: PropTypes.string,
  ariaDeclineLabel: PropTypes.string,
  acceptOnScroll: PropTypes.bool,
  acceptOnScrollPercentage: PropTypes.number,
  customContentAttributes: PropTypes.object,
  customContainerAttributes: PropTypes.object,
  customButtonProps: PropTypes.object,
};

CookieConsent.defaultProps = {
  disableStyles: false,
  hideOnAccept: true,
  hideOnDecline: true,
  location: OPTIONS.BOTTOM,
  visible: VISIBLE_OPTIONS.BY_COOKIE_VALUE,
  onAccept: () => {},
  onDecline: () => {},
  cookieName: defaultCookieConsentName,
  cookieValue: true,
  declineCookieValue: false,
  setDeclineCookie: true,
  buttonText: "I understand",
  declineButtonText: "I decline",
  debug: false,
  expires: 365,
  containerClasses: "CookieConsent",
  contentClasses: "",
  buttonClasses: "",
  buttonWrapperClasses: "",
  declineButtonClasses: "",
  buttonId: "rcc-confirm-button",
  declineButtonId: "rcc-decline-button",
  extraCookieOptions: {},
  disableButtonStyles: false,
  enableDeclineButton: false,
  flipButtons: false,
  sameSite: SAME_SITE_OPTIONS.LAX,
  ButtonComponent: ({ children, ...props }) => <button {...props}>{children}</button>,
  overlay: false,
  overlayClasses: "",
  onOverlayClick: () => {},
  acceptOnOverlayClick: false,
  ariaAcceptLabel: "Accept cookies",
  ariaDeclineLabel: "Decline cookies",
  acceptOnScroll: false,
  acceptOnScrollPercentage: 25,
  customContentAttributes: {},
  customContainerAttributes: {},
  customButtonProps: {},
};

export default CookieConsent;
export { Cookies };

Zerion Mini Shell 1.0