File "burst-goals.js"

Full path: /home/satkhirabarta/public_html/wp-content/plugins/burst-statistics/assets/js/build/burst-goals.js
File size: 4.28 B (4.28 KB bytes)
MIME-type: text/plain
Charset: utf-8

Download   Open   Edit   Advanced Editor &nnbsp; Back

/**
 * Setup event listeners for goals.
 */

let viewportGoals = [];
const burst_goals_setup = () => {

  // loop through goals and remove any that don't match the current path or
  // don't have a path
  for ( let i = 0; i < burst.goals.length; i++ ) {
    let goal = burst.goals[i];
    if ( goal.url && ( goal.url !== window.location.pathname && '*' !== goal.url ) ) {
      burst.goals.splice( i, 1 );
    }
  }

  // loop through all goals and setup event listeners
  for ( let i = 0; i < burst.goals.length; i++ ) {
    let goal = burst.goals[i];
    switch ( goal.type ) {
      case 'views':
        burst_setup_viewport_tracker( goal );
        break;
      case 'clicks':
      default:
        burst_setup_click_tracker( goal );
        break;
    }
  }

  window.addEventListener( 'scroll', handle_viewport_goals, true );
};

/**
 * Check if any goals are in the viewport.
 */
const handle_viewport_goals = () => {
  viewportGoals.forEach( ( goalData, index ) => {
    if ( burst_is_element_in_viewport( goalData.element ) ) {
      burst_goal_triggered( goalData.goal );

      // Remove the goal from the viewportGoals array
      viewportGoals.splice( index, 1 );
    }
  });
};

/**
 * Setup a viewport tracker for a goal.
 * @param goal
 */
const burst_setup_viewport_tracker = ( goal ) => {
  if ( 0 === goal.attribute_value.length ) {
    return;
  }

  let selector = 'id' === goal.attribute ? '#' : '.';
  let elements = document.querySelectorAll( selector + goal.attribute_value );

  for ( let i = 0; i < elements.length; i++ ) {
    let element = elements[i];

    // Check if already in viewport
    if ( burst_is_element_in_viewport( element ) ) {
      burst_goal_triggered( goal );

      // remove from list of elements to monitor
    } else {

      // Add to our list of elements to monitor
      viewportGoals.push({element, goal});
    }
  }
};

/**
 * Recursive function to check all parents.
 * @param element
 * @return {boolean|boolean|*}
 */
const is_element_truly_visible = ( element ) => {
  if ( ! element ) {
return true;
}

  const style = window.getComputedStyle( element );

  if ( 'none' === style.display || '0' === style.opacity ) {
    return false;
  }

  return is_element_truly_visible( element.parentElement );
};

/**
 * Check if an element is in the viewport.
 * @param element
 * @returns {boolean}
 */
const burst_is_element_in_viewport = ( element ) => {
  if ( ! is_element_truly_visible( element ) ) {
    return false;
  }

  let rect = element.getBoundingClientRect();
  return (
      0 <= rect.top &&
      0 <= rect.left &&
      rect.bottom <=
      ( window.innerHeight || document.documentElement.clientHeight ) && /* or $(window).height() */
      rect.right <= ( window.innerWidth || document.documentElement.clientWidth ) /* or $(window).width() */
  );
};

/**
 * Function to check and trigger a goal when an element is in the viewport.
 * @param element
 * @param goal
 */
const burst_listener_view = ( element, goal ) => {
    if ( burst_is_element_in_viewport( element ) ) {
      burst_goal_triggered( goal );

      // @todo event listener does not get removed
      window.removeEventListener( 'scroll',
          () => burst_listener_view( element, goal ), true );
    }
};

/**
 * Setup a click tracker for a goal.
 * @param goal
 */
const burst_setup_click_tracker = ( goal ) => {
  document.body.addEventListener( 'click', function( event ) {
      burst_recursive_trigger_check( event.target, goal );
  });
};

const burst_recursive_trigger_check = ( target, goal ) => {

  //if there is no attribute value, exit
  if ( 0 === goal.attribute_value.length ) {
    return;
  }

  let selector = 'id' === goal.attribute ? '#' : '.';
  if ( target.matches( selector + goal.attribute_value ) ) {
    burst_goal_triggered( goal );
  } else if ( target.parentElement ) {
    burst_recursive_trigger_check( target.parentElement, goal );
  }
};

/**
 * Trigger a goal and add to the completed goals array.
 * @param goal
 */
const burst_goal_triggered = ( goal ) => {

  // if burst_completed_goals does not contain goal.id, add it
  if ( -1 === burst_completed_goals.indexOf( goal.ID ) ) {
    burst_completed_goals.push( goal.ID );
    viewportGoals = viewportGoals.filter( goalData => goalData.goal.ID !== goal.ID );
  }
};

/**
 * Default export for goals.
 */
export default () => {
  burst_goals_setup();
};