<?php

/**
 * Class for "Optimization"
 */

if (!defined('ABSPATH')) {
	exit;
} // Exit if accessed directly

if (!class_exists('Liquid_Optimization')) :
	/**
	 * Liquid Disable Unused Scripts
	 */
	class Liquid_Optimization extends Liquid_Base
	{

		/**
		 * Current Page ID
		 * @var $page_id
		 */
		public $page_id;


		/**
		 * Used Shortcodes
		 * @var $tags
		 */
		public $tags;

		/**
		 * @method __construct
		 */
		public function __construct()
		{
			$theme_option = get_option('liquid_one_opt');

			if (isset($theme_option['enable-hub-optimization']) && $theme_option['enable-hub-optimization'] === 'on') {
				$this->tags = [];
				$this->init_hooks();
			}
		}

		/**
		 * Init Hooks and Filters
		 *
		 * @method init_hooks
		 */
		private function init_hooks()
		{
			if (is_admin() || (function_exists('vc_is_inline') && vc_is_inline())) {
				$this->add_action('save_post', 'save_post', 10, 2);
			} else {
				$this->add_action('wp', 'wp');
				$this->add_filter('the_content', 'check_content', 0);
				$this->add_action('wp_enqueue_scripts', 'wp_enqueue_scripts');

				$this->add_action('wp_head', 'buffer_start', 0);
				$this->add_action('wp_footer', 'buffer_end', 99);

				$this->add_action('vc_base_register_front_css', 'vc_base_register_front_css');
				$this->add_action('wp_head', 'wp_head', 0);

				$this->add_filter('do_shortcode_tag', 'do_shortcode_tag', 10, 2);
				$this->add_action('shutdown', 'shutdown');

				$this->add_filter('load_shortcodes', 'load_shortcodes');
			}

			/**
			 * Hub Purge Cache
			 */
			if (is_admin()) {
				$this->add_action('admin_bar_menu', 'add_item', 100);
				$this->add_action('admin_footer', 'cache_purge_action_js');
				$this->add_action('wp_ajax_hub_cache_purge', 'hub_cache_purge_callback');
			}
		}

		/**
		 * Optimize Shortodes list
		 * @param $shortcodes
		 * @return array|mixed|string[]
		 */
		public function load_shortcodes($shortcodes)
		{
			global $post;

			if (!is_a($post, 'WP_Post') || liquid_helper()->get_page_id_by_url() == 0) {
				return $shortcodes;
			}

			$used_shortcodes = get_post_meta($post->ID, '_used_shortcodes', true);

			$tag_names = ['misc'];

			if ($used_shortcodes) {

				foreach ($used_shortcodes as $shortcode) {

					$shortcode = str_replace('ld_button', 'ld_1button', $shortcode);
					$shortcode = str_replace('ld_cf7', 'ld_contact-form', $shortcode);
					$shortcode = str_replace('ld_', '', $shortcode);
					$shortcode = str_replace('vc_', '', $shortcode);
					$shortcode = str_replace('_', '-', $shortcode);
					$shortcode = str_replace('imgage', 'image', $shortcode);
					$shortcode = str_replace('single-portfolio', 'pf-single', $shortcode);
					$shortcode = str_replace('imgtxt-slider', 'image-text-slider', $shortcode);

					if (array_search($shortcode, $shortcodes) !== false) {
						$tag_names[] = $shortcode;
					}
				}

				if (array_search('header-button', $shortcodes) !== false) {
					$tag_names[] = '1button';
				}

				if (array_search('header-custom-menu', $shortcodes) !== false) {
					$tag_names[] = 'custom-menu';
				}

				$shortcodes = array_unique($tag_names);
			}

			return $shortcodes;
		}

		/**
		 * Add Shortcode name to global array
		 * @param $output
		 * @param $tag
		 * @return string
		 */
		public function do_shortcode_tag($output, $tag)
		{
			$this->tags = array_merge($this->tags, [$tag]);

			return $output;
		}

		/**
		 * Add shortcodes to meta by Page ID
		 */
		public function shutdown()
		{
			if (empty(get_post_meta($this->page_id, '_used_shortcodes', true))) {
				update_post_meta($this->page_id, '_used_shortcodes', array_unique($this->tags));
			}
		}

		/**
		 * Add New Button to Top Admin bar
		 * @param $admin_bar
		 */
		public function add_item($admin_bar)
		{
			$admin_bar->add_menu(array('id' => 'hub-purge-cache', 'title' => 'Hub Purge Cache', 'href' => '#'));
		}

		/**
		 * Add Javascript to Admin Area
		 */
		public function cache_purge_action_js()
		{ ?>
			<script type="text/javascript">
				jQuery("li#wp-admin-bar-hub-purge-cache .ab-item").on("click", function(e) {
					e.preventDefault();

					var data = {
						'action': 'hub_cache_purge',
					};

					jQuery.post(ajaxurl, data, function(response) {
						alert(response.data);
					});

				});
			</script> <?php
					}

					/**
					 * Ajax request
					 */
					public function hub_cache_purge_callback()
					{
						self::purge_cache();
						wp_send_json_success('Cache Purged Success');
					}

					/**
					 * Purge Cache
					 */
					public
					static function purge_cache()
					{
						global $wpdb;

						$wpdb->delete($wpdb->postmeta, ['meta_key' => '_post_content']);
						$wpdb->delete($wpdb->postmeta, ['meta_key' => '_post_scripts']);
						$wpdb->delete($wpdb->postmeta, ['meta_key' => '_used_shortcodes']);
					}

					/**
					 * Hook wp_head
					 */
					public
					function wp_head()
					{
						$href = function_exists('vc_asset_url') ? vc_asset_url('css/js_composer.min.css') . '?ver=' . WPB_VC_VERSION : '';
						if (!empty($href)) {
							echo '<link rel="stylesheet" id="js_composer_front-css" href="' . $href . '" type="text/css" media="all">';
						}
					}

					/**
					 * Deregister script
					 */
					public
					function vc_base_register_front_css()
					{
						wp_deregister_style('js_composer_front');
					}

					/**
					 * @param $buffer
					 *
					 * @method callback
					 *
					 * @return string
					 */
					public
					function callback($buffer)
					{
						return $this->the_content($buffer);
					}

					/**
					 * @method buffer_start
					 */
					public
					function buffer_start()
					{
						if ('publish' === get_post_status() && !isset($_GET['preview'])) {
							ob_start([$this, 'callback']);
						}
					}

					/**
					 * @method buffer_end
					 */
					public
					function buffer_end()
					{
						if ('publish' === get_post_status() && !isset($_GET['preview'])) {
							ob_end_flush();
						}
					}

					/**
					 * @method wp
					 */
					public
					function wp()
					{
						$this->page_id = get_the_ID();
					}

					/**
					 * WP Enqueue Scripts
					 *
					 * @method wp_enqueue_scripts
					 */
					public
					function wp_enqueue_scripts()
					{
						if (!has_blocks()) {
							wp_dequeue_style('wp-block-library');
							wp_dequeue_style('wp-block-library-theme');
							wp_dequeue_style('wc-block-style');
						}
					}

					/**
					 * Hook Save Post
					 *
					 * @param $post_ID
					 * @param $post
					 *
					 * @method save_post
					 */
					public
					function save_post($post_ID, $post)
					{

						if ('revision' === $post->post_type) {
							return;
						}

						if (class_exists('WPBMap')) {
							WPBMap::addAllMappedShortcodes();
						}

						add_filter('wp_get_attachment_image_attributes', 'liquid_filter_gallery_img_atts', 10, 2);

						global $shortcode_tags;

						$content = $post->post_content;
						$ignore_html = false;

						if (false === strpos($content, '[')) {
							return;
						}

						if (empty($shortcode_tags) || !is_array($shortcode_tags)) {
							return;
						}

						if (!isset($GLOBALS['post']) && isset($_POST['post_id'])) {
							$GLOBALS['post'] = get_post($_POST['post_id']);
						}

						$tagnames = [
							'vc_row',
							'vc_row_inner',
							'vc_column',
							'vc_column_inner',
							'vc_single_image',
							'vc_column_text',
							'vc_separator',

							'ld_accordion',
							'ld_animated_frame',
							'ld_animated_frames_container',
							'ld_asymmetric_slider',

							'ld_bananas',
							'ld_bananas_banner',
							//				'ld_button',

							'ld_carousel',
							'ld_carousel_3d',
							'ld_carousel_falcate',
							'ld_carousel_gallery',
							//				'ld_carousel_marquee',
							//				'ld_carousel_stack',
							//				'ld_carousel_tab',

							'ld_content_box',
							'ld_countdown',
							'ld_counter',
							'ld_custom_menu',

							//              'ld_blog',
							'ld_simple_menu',
							'ld_simple_heading',

							'ld_header_row',
							'ld_header_column',
							'ld_header_image',
							'ld_header_menu',
							'ld_header_button',
							'ld_header_scroll_indicator',

							'ld_d_banner',
							'ld_d_depth_banner',
							'ld_distorse_gallery',

							'ld_fancy_heading',
							//				'ld_flipbox',
							'ld_freakin_image',
							'ld_fullproj',

							'ld_google_map',

							'ld_highlight',
							'ld_hotspots',

							'ld_icon',
							'ld_icon_box',
							'ld_icon_box_circle',
							'ld_icon_box_circle_item',
							'ld_image_overlay_text',
							'ld_image_text_slider',
							'ld_imgtxt_slider',
							'ld_image_trail',
							'ld_images_comparison',
							'ld_images_group_container',
							'ld_images_group_element',

							'ld_list',

							'ld_megamenu_row',
							'ld_megamenu_row_inner',
							'ld_megamenu_column',
							'ld_megamenu_column_inner',

							'ld_masked_image',
							'ld_media',
							'ld_media_element',
							'ld_message',
							'ld_milestone',
							'ld_modal_window',

							'ld_newsletter',

							'ld_particles',
							'ld_pointer_tooltip',
							'ld_price_table',
							'ld_process_box',
							'ld_process_box_container',
							'ld_progressbar',
							'ld_promo',

							'ld_roadmap',
							'ld_roadmap_item',

							'ld_section_title',
							'ld_single_portfolio_meta',
							'ld_single_portfolio_nav',
							'ld_single_portfolio_related',
							'ld_single_portfolio_cover',
							'ld_single_portfolio_title',
							'ld_shop_banner',
							//				'ld_slideshow',
							//				'ld_slideshow_2',
							'ld_social_icons',
							'ld_spacer',
							'ld_span',

							//				'ld_tabs',
							'ld_team_member',
							'ld_team_members_circular',
							'ld_testi_carousel',
							'ld_testimonial',
							'ld_timeline',
							'ld_timeline_item',
							'ld_tooltiped_image',
							'ld_typewriter',
						];

						foreach ($shortcode_tags as $tag => $shortcode) {

							if (array_search($tag, $tagnames) === false) {
								unset($shortcode_tags[$tag]);
							}
						}

						$tagnames = array_intersect(array_keys($shortcode_tags), $tagnames);

						if (empty($tagnames)) {
							return;
						}

						$content = str_replace('<p>', '', str_replace('</p>', '', $content));

						if (liquid_helper()->get_option('enable-hub-header-cache') === 'off' && in_array(get_post_type($post), ['liquid-header', 'liquid-mega-menu'])) {
							return;
						}

						if (get_post_type($post) === 'liquid-header') {
							$content = str_replace('[vc_row ', '[ld_header_row ', $content);
							$content = str_replace('[vc_row]', '[ld_header_row]', $content);
							$content = str_replace('[/vc_row]', '[/ld_header_row]', $content);

							$content = str_replace('[vc_column ', '[ld_header_column ', $content);
							$content = str_replace('[vc_column]', '[ld_header_column]', $content);
							$content = str_replace('[/vc_column]', '[/ld_header_column]', $content);

							ob_start();
							liquid_action('after_header_tag');
							$content .= ob_get_clean();
						}

						if (get_post_type($post) === 'liquid-mega-menu') {

							$content = str_replace('[vc_row_inner]', '[ld_megamenu_row_inner]', $content);
							$content = str_replace('[vc_row_inner ', '[ld_megamenu_row_inner ', $content);
							$content = str_replace('[/vc_row_inner]', '[/ld_megamenu_row_inner]', $content);

							$content = str_replace('[vc_column_inner ', '[ld_megamenu_column_inner ', $content);
							$content = str_replace('[vc_column_inner]', '[ld_megamenu_column_inner]', $content);
							$content = str_replace('[/vc_column_inner]', '[/ld_megamenu_column_inner] ', $content);

							$content = str_replace('[vc_row]', '[ld_megamenu_row]', $content);
							$content = str_replace('[vc_row ', '[ld_megamenu_row ', $content);
							$content = str_replace('[/vc_row]', '[/ld_megamenu_row]', $content);

							$content = str_replace('[vc_column ', '[ld_megamenu_column ', $content);
							$content = str_replace('[vc_column]', '[ld_megamenu_column]', $content);
							$content = str_replace('[/vc_column]', '[/ld_megamenu_column] ', $content);
						}

						$content = do_shortcodes_in_html_tags($content, $ignore_html, $tagnames);

						$pattern = get_shortcode_regex($tagnames);
						$content = preg_replace_callback("/$pattern/", 'do_shortcode_tag', $content);

						$content = unescape_invalid_shortcodes($content);
						update_post_meta($post_ID, '_post_content', stripslashes($content));
					}

					/**
					 * Check generate HTML content
					 *
					 * @param string $content
					 *
					 * @method check_content
					 *
					 * @return mixed|string
					 */
					public
					function check_content(string $content)
					{

						if ('publish' !== get_post_status() || isset($_GET['preview'])) {
							return $content;
						}

						if (get_the_ID() !== $this->page_id) {
							return $content;
						}

						$post_ID = $this->page_id;

						$scripts_from_meta = get_post_meta($post_ID, '_post_scripts', true);
						$content_from_meta = get_post_meta($post_ID, '_post_content', true);

						if (is_array($scripts_from_meta)) {
							foreach ($scripts_from_meta as $handle) {
								wp_enqueue_script($handle);
							}
						}

						if ($content_from_meta) {
							remove_action('the_content', 'wpautop');
							remove_action('the_content', 'wptexturize');

							$content = $content_from_meta;
						}

						return $content;
					}

					/**
					 * Filter for the_content
					 *
					 * @method init_hooks
					 *
					 * @param string $content
					 *
					 * @return string
					 */
					public
					function the_content(string $content)
					{

						$regex = "/\<script(.*?)?\>(.|\\n)*?\<\/script\>/i";

						preg_match_all($regex, $content, $scripts);

						foreach ($scripts[0] as $old_script) {
							if (strpos($old_script, 'type="text/template"') === false) {
								$script = str_replace('</', '<\/', $old_script);
								$script = str_replace('<\/script>', '</script>', $script);
								$content = str_replace($old_script, $script, $content);
							}
						}


						$dom = new DOMDocument();

						libxml_use_internal_errors(true);
						$dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
						libxml_clear_errors();

						$deregister_scripts = [];
						$deregister_styles = [];

						//Check SplitText
						if (!$this->find_element([
							'data-split-text' => 'true'
						], $dom)) {
							$deregister_scripts[] = 'splittext';
						}

						//Check Gsap Custom Easy
						if (!$this->find_element([
							'data-liquid-animatedframes' => 'true'
						], $dom)) {
							$deregister_scripts[] = 'gsap-custom-ease';
						}

						//Check ThreeJS
						if (!$this->find_element([
							'data-webglhover' => 'true',
							'data-lqd-fake3d' => 'true'
						], $dom)) {
							$deregister_scripts[] = 'threejs';
						}

						//Check Fresco
						if (!$this->find_element([
							'class' => ['fresco']
						], $dom)) {
							$deregister_styles[] = 'fresco';
							$deregister_scripts[] = 'jquery-fresco';
						}

						//Check FontAwesome
						if (!$this->find_element([
							'class' => ['fa', 'fab', 'fas', 'far']
						], $dom)) {
							$deregister_styles[] = 'font-awesome';
						}

						//Check Gsap
						if (!$this->find_element([
							'data-liquid-animatedframes' => 'true',
							'data-animate-onscroll' => 'true',
							'data-asym-slider' => 'true',
							'data-liquid-bg' => 'true',
							'data-enable-counter' => 'true',
							'data-custom-animations' => 'true',
							'data-lqd-cc' => 'true',
							'data-lqd-dist-gal' => 'true',
							'data-dynamic-shape' => 'true',
							'data-lqd-fullproj' => 'true',
							'data-hover3d' => 'true',
							'data-spread-incircle' => 'true',
							'data-lqd-img-trail' => 'true',
							'data-parallax' => 'true',
							'data-progressbar' => 'true',
							'data-reveal' => 'true',
							'data-lqd-scroll-indicator' => 'true',
							'data-shrink-borders' => 'true',
							'data-slideelement-onhover' => 'true',
							'data-slideshow-bg' => 'true',
							'data-sticky-footer' => 'true',
							'data-text-rotator' => 'true',
							'data-webglhover' => 'true',
							'data-pin' => 'true',
							'data-lqd-slideshow' => 'true',
							'class' => [
								'lqd-preloader-wrap',
								'lqd-carousel-stack',
								'carousel-vertical-3d',
								'lqd-sticky-stack',
								'lqd-dist-gal',
							]
						], $dom)) {
							$deregister_scripts[] = 'gsap';
						}

						//Check Scroll Trigger
						if (!$this->find_element([
							'data-animate-onscroll' => 'true',
							'data-parallax' => 'true',
							'data-pin' => 'true',
							'data-lqd-scroll-indicator' => 'true',
							'data-shrink-borders' => 'true',
							'data-liquid-bg' => 'true',
							'data-sticky-footer' => 'true',
							'class' => ['lqd-sticky-stack']
						], $dom)) {
							$deregister_scripts[] = 'scrollTrigger';
						}

						//Check Bootstrap
						if (!$this->find_element([
							'data-ld-toggle' => 'true',
							'class' => ['module-lqd-fullproj-scrn', 'accordion', 'lqd-tabs']
						], $dom)) {
							$deregister_scripts[] = 'bootstrap';
						}

						//Check Flickity
						if (!$this->find_element([
							'data-lqd-flickity' => '',
							'class' => ['carousel-falcate']
						], $dom)) {
							$deregister_scripts[] = 'flickity';
						}

						//Check Flickity Fade
						if (!$this->find_element([
							'class' => ['lqd-carousel-fade']
						], $dom)) {
							$deregister_scripts[] = 'flickity-fade';
						}

						//Check Isotope
						if (!$this->find_element([
							'data-liquid-masonry' => 'true'
						], $dom)) {
							$deregister_scripts[] = 'isotope';
							$deregister_scripts[] = 'packery-mode';
						}

						//Check jQuery UI
						if (!$this->find_element([
							'class' => [
								'date-picker',
								'wpcf7-form-control',
								'spinner',
								'widget_price_filter',
								'orderby',
								'liquid-wc-product-search',
								'lqd-domain-search',
								'lqd-filter-dropdown',
								'widget_archive',
								'widget_categories',
								'widget_text',
							]
						], $dom)) {
							$deregister_styles[] = 'jquery-ui';
							$deregister_scripts[] = 'jquery-ui';
						}

						//Check jQuery UI Touch
						if (!$this->find_element([
							'class' => [
								'widget_price_filter'
							]
						], $dom)) {
							$deregister_scripts[] = 'jquery-ui-touch';
						}

						//Check Contact Form 7
						if (!$this->find_element([
							'class' => ['wpcf7-form']
						], $dom)) {
							$deregister_styles[] = 'contact-form-7';
							$deregister_scripts[] = 'contact-form-7';
						}

						//Check Lity
						if (!$this->find_element([
							'data-lqd-lity' => ''
						], $dom)) {
							$deregister_scripts[] = 'lity';
						}

						//Check Circle Progress
						if (!$this->find_element([
							'class' => ['ld-prgbr-circle-container']
						], $dom)) {
							$deregister_scripts[] = 'circle-progress';
						}

						//Check imagesLoaded
						if (!$this->find_element([
							'data-ajaxify' => 'true',
							'data-asym-slider' => 'true',
							'data-lqd-flickity' => 'true',
							'data-lqd-img-trail' => 'true',
							'data-inview' => 'true',
							'data-liquid-masonry' => 'true',
							'data-responsive-bg' => 'true',
							'data-reveal' => 'true',
							'data-row-bg' => '',
							'data-slideelement-onhover' => 'true',
							'data-slideshow-bg' => 'true',
							'data-sticky-footer' => 'true',
							'data-webglhover' => 'true',
							'data-localscroll' => 'true',
							'class' => ['carousel-falcate', 'lqd-mobile-sec-nav']
						], $dom)) {
							$deregister_scripts[] = 'imagesloaded';
						}

						//Check Particles
						if (!$this->find_element([
							'data-particles' => 'true'
						], $dom)) {
							$deregister_scripts[] = 'jquery-particles';
						}

						//Check js_composer_front
						if (!$this->find_element([
							'data-vc-full-width' => 'true',
							'class' => [
								'wpb_flexslider',
								'wpb_pinterest',
								'vc_progress_bar',
								'wpb_tabs',
								'wpb_tour',
								'wpb_accordion',
								'wpb_grid',
								'wpb_carousel',
								'wpb_gallery_slides',
								'vc_pie_chart',
								'vc_round-chart',
								'vc_line-chart',
								'vc_masonry_media_grid',
								'vc_masonry_grid',
							]
						], $dom)) {
							$deregister_scripts[] = 'wpb_composer_front_js';
						}

						//Check mediaelements
						if (!$this->find_element([
							'data-video-bg' => '',
							'class' => [
								'wp-audio-shortcode',
								'wp-video-shortcode'
							]
						], $dom)) {
							$deregister_scripts[] = 'mediaelement-core';
							$deregister_scripts[] = 'mediaelement-migrate';
							$deregister_scripts[] = 'wp-mediaelement';
						}

						//Check Schedule Table
						if (!$this->find_element([
							'data-liquid-schedule-table' => 'true'
						], $dom)) {
							$deregister_styles[] = 'le-schedule-table';
							$deregister_scripts[] = 'le-table-js';
						}

						//Check Tinycolor
						if (!$this->find_element([
							'data-liquid-bg' => 'true',
							'data-liquid-stack' => 'true',
							'class' => ['megamenu', 'main-header-dynamiccolors']
						], $dom)) {
							$deregister_scripts[] = 'jquery-tinycolor';
						}

						//Check Vivus
						if (!$this->find_element([
							'data-animated-svg' => 'true'
						], $dom)) {
							$deregister_scripts[] = 'jquery-vivus';
						}

						//Check Google Maps
						if (!$this->find_element([
							'data-plugin-map' => 'true'
						], $dom)) {
							$deregister_scripts[] = 'google-maps-api';
						}

						//Check YTPlayer
						if (!$this->find_element([
							'data-video-bg' => 'true'
						], $dom)) {
							$deregister_styles[] = 'jquery-ytplayer';
							$deregister_scripts[] = 'jquery-ytplayer';
						}

						//Check liquid-essentials
						if (!$this->find_element([
							'class' => ['lqd-icn-ess', 'lqd-lp-read-more']
						], $dom)) {
							$deregister_styles[] = 'liquid-icons';
						}

						$this->deregister_scripts($deregister_scripts, $dom);
						$this->deregister_styles($deregister_styles, $dom);

						$dom->removeChild($dom->doctype);

						$content = $dom->saveHTML();

						if (isset($_GET['debug']) && $_GET['debug'] === '1') {
							$content = '<pre>Scripts: ' . json_encode($deregister_scripts) . '</pre><br><pre>Styles: ' . json_encode($deregister_styles) . '</pre>' . $content;
						}

						$content = str_replace('<html>', '', $content);
						$content = str_replace('<head>', '', $content);
						$content = str_replace('</head>', '', $content);
						$content = str_replace('</body>', '', $content);
						$content = str_replace('</html>', '', $content);

						return $content;
					}

					/**
					 * Search HTML Element by attribute
					 *
					 * @method find_element
					 *
					 * @param array $attributes
					 * @param DOMDocument $dom
					 *
					 * @return bool
					 */
					private
					function find_element(array $attributes, DOMDocument $dom)
					{

						$finder = new DomXPath($dom);
						$query = [];

						foreach ($attributes as $attribute => $value) {
							if ($attribute === 'class') {
								foreach ($value as $class) {
									$query[] = "//*[contains(@class, '$class')]";
								}
							} else {
								$query[] = $value ? "//*[contains(@{$attribute}, '{$value}')]" : "//*[@{$attribute}]";
							}
						}

						$elements = $finder->query(implode(' | ', $query));

						if ($elements && $elements->length) {
							return true;
						}

						return false;
					}

					/**
					 * @method get_script_src_by_handle
					 *
					 * @param $handle
					 *
					 * @return bool
					 */
					private
					function get_script_src_by_handle($handle)
					{
						global $wp_scripts;
						if (isset($wp_scripts->registered[$handle])) {
							return $wp_scripts->registered[$handle]->src;
						}

						return false;
					}

					/**
					 * @method get_style_src_by_handle
					 *
					 * @param $handle
					 *
					 * @return bool
					 */
					private
					function get_style_src_by_handle($handle)
					{
						global $wp_styles;
						if (isset($wp_styles->registered[$handle])) {
							return $wp_styles->registered[$handle]->src;
						}

						return false;
					}

					/**
					 * Deregister Scripts
					 *
					 * @method deregister_styles
					 *
					 * @param array $handles_to_remove
					 * @param DOMDocument $dom
					 */
					private
					function deregister_styles(array $handles_to_remove, DOMDocument $dom)
					{

						$finder = new DomXPath($dom);
						$query = [];

						foreach ($handles_to_remove as $handle) {
							if ($src = $this->get_style_src_by_handle($handle)) {
								$query[] = "//link[contains(@href, '$src')]";
							}
						}

						$elements = $finder->query(implode(' | ', $query));

						if ($elements && $elements->length) {
							foreach ($elements as $element) {
								$element->parentNode->removeChild($element);
							}
						}
					}

					/**
					 * Deregister Scripts
					 *
					 * @method deregister_scripts
					 *
					 * @param array $handles_to_remove
					 * @param DOMDocument $dom
					 */
					private
					function deregister_scripts(array $handles_to_remove, DOMDocument $dom)
					{

						$finder = new DomXPath($dom);
						$query = [];

						foreach ($handles_to_remove as $handle) {
							if ($src = $this->get_script_src_by_handle($handle)) {
								$query[] = "//script[contains(@src, '$src')]";
							}
						}

						$elements = $finder->query(implode(' | ', $query));

						if ($elements && $elements->length) {
							foreach ($elements as $element) {
								$element->parentNode->removeChild($element);
							}
						}
					}
				}

				new Liquid_Optimization();

			endif;
