<?php
/**
 * Genesis Framework.
 *
 * WARNING: This file is part of the core Genesis Framework. DO NOT edit this file under any circumstances.
 * Please do all modifications in the form of a child theme.
 *
 * @package Genesis\Assets
 * @author  StudioPress
 * @license GPL-2.0-or-later
 * @link    https://my.studiopress.com/themes/genesis/
 */

/**
 * Script loader class.
 *
 * @since 2.5.0
 *
 * @package Genesis\Assets
 */
class Genesis_Script_Loader {

	/**
	 * Holds script file name suffix.
	 *
	 * @since 2.5.0
	 *
	 * @var string suffix
	 */
	private $suffix = '.min';

	/**
	 * Hook into WordPress.
	 *
	 * @since 2.5.0
	 */
	public function add_hooks() {

		// Register scripts early to allow replacement by plugin/child theme.
		add_action( 'wp_enqueue_scripts', [ $this, 'register_front_scripts' ], 0 );
		add_action( 'admin_enqueue_scripts', [ $this, 'register_admin_scripts' ], 0 );

		// Enqueue the scripts.
		add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_front_scripts' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'maybe_enqueue_admin_scripts' ] );
		add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_block_editor_scripts' ] );

		// Enable extra attributes for enqueued wp_enqueue_scripts.
		add_filter( 'script_loader_tag', [ $this, 'maybe_enable_attrs' ], 10, 3 );

	}

	/**
	 * Register front end scripts used by Genesis.
	 *
	 * @since 2.5.0
	 */
	public function register_front_scripts() {

		if ( genesis_is_in_dev_mode() ) {
			$this->suffix = '';
		}

		wp_register_script( 'superfish', GENESIS_JS_URL . "/menu/superfish{$this->suffix}.js", [ 'jquery', 'hoverIntent' ], '1.7.10', true );
		wp_register_script( 'superfish-args', apply_filters( 'genesis_superfish_args_url', GENESIS_JS_URL . "/menu/superfish.args{$this->suffix}.js" ), [ 'superfish' ], PARENT_THEME_VERSION, true );
		wp_register_script( 'skip-links', GENESIS_JS_URL . "/skip-links{$this->suffix}.js", [], PARENT_THEME_VERSION, true );
		wp_register_script( 'drop-down-menu', GENESIS_JS_URL . "/drop-down-menu{$this->suffix}.js", [ 'jquery' ], PARENT_THEME_VERSION, true );

	}

	/**
	 * Register admin scripts used by Genesis.
	 *
	 * @since 2.5.0
	 */
	public function register_admin_scripts() {

		if ( genesis_is_in_dev_mode() ) {
			$this->suffix = '';
		}

		wp_register_script( 'genesis_admin_js', GENESIS_JS_URL . "/admin{$this->suffix}.js", [ 'jquery', 'wp-a11y' ], PARENT_THEME_VERSION, true );
		wp_register_script( 'van11y-accessible-modal-window-aria', GENESIS_JS_URL . '/vendor/modal/van11y-accessible-modal-window-aria.min.js', '', PARENT_THEME_VERSION, true );

	}

	/**
	 * Enqueue scripts specific to the Block Editor.
	 *
	 * @since 3.1.0
	 */
	public function enqueue_block_editor_scripts() {

		$visible_panels = $this->visible_genesis_sidebar_panels();

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

		wp_enqueue_script(
			'genesis-sidebar',
			GENESIS_JS_URL . '/build/genesis-sidebar.js',
			[ 'wp-components', 'wp-edit-post', 'wp-element', 'wp-plugins', 'wp-polyfill' ],
			PARENT_THEME_VERSION,
			true
		);

		// Breadcrumbs panel.
		if ( isset( $visible_panels['breadcrumbs'] ) ) {
			wp_enqueue_script(
				'genesis-breadcrumbs-toggle',
				GENESIS_JS_URL . '/build/breadcrumbs-toggle.js',
				[ 'lodash', 'wp-a11y', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-polyfill' ],
				PARENT_THEME_VERSION,
				true
			);
		}

		// Title panel.
		if ( isset( $visible_panels['title'] ) ) {
			wp_enqueue_script(
				'genesis-title-toggle',
				GENESIS_JS_URL . '/build/title-toggle.js',
				[ 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-polyfill' ],
				PARENT_THEME_VERSION,
				true
			);
		}

		// Images panel.
		if ( isset( $visible_panels['images'] ) ) {
			wp_enqueue_script(
				'genesis-image-toggle',
				GENESIS_JS_URL . '/build/image-toggle.js',
				[ 'lodash', 'wp-a11y', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-polyfill' ],
				PARENT_THEME_VERSION,
				true
			);
		}

		// Layout panel.
		if ( isset( $visible_panels['layout'] ) ) {
			wp_enqueue_script(
				'genesis-layout-toggle',
				GENESIS_JS_URL . '/build/layout-toggle.js',
				[ 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-polyfill' ],
				PARENT_THEME_VERSION,
				true
			);
		}

		// Footer Widgets panel.
		if ( isset( $visible_panels['footer-widgets'] ) ) {
			wp_enqueue_script(
				'genesis-footer-widgets-toggle',
				GENESIS_JS_URL . '/build/footer-widgets-toggle.js',
				[ 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-polyfill' ],
				PARENT_THEME_VERSION,
				true
			);
		}

		// Custom Classes panel.
		if ( isset( $visible_panels['custom-classes'] ) ) {
			wp_enqueue_script(
				'genesis-custom-classes',
				GENESIS_JS_URL . '/build/custom-classes.js',
				[ 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-polyfill' ],
				PARENT_THEME_VERSION,
				true
			);
		}

		// Set up translations for all scripts with the wp-i18n dependency.
		wp_set_script_translations( 'genesis-breadcrumbs-toggle', 'genesis', GENESIS_LANGUAGES_DIR );
		wp_set_script_translations( 'genesis-title-toggle', 'genesis', GENESIS_LANGUAGES_DIR );
		wp_set_script_translations( 'genesis-image-toggle', 'genesis', GENESIS_LANGUAGES_DIR );
		wp_set_script_translations( 'genesis-layout-toggle', 'genesis', GENESIS_LANGUAGES_DIR );
		wp_set_script_translations( 'genesis-footer-widgets-toggle', 'genesis', GENESIS_LANGUAGES_DIR );
		wp_set_script_translations( 'genesis-custom-classes', 'genesis', GENESIS_LANGUAGES_DIR );

	}

	/**
	 * Enqueue the scripts used on the front-end of the site.
	 *
	 * Includes comment-reply, superfish and the superfish arguments.
	 *
	 * Applies the `genesis_superfish_enabled`, and `genesis_superfish_args_uri`. filter.
	 *
	 * @since 2.5.0
	 */
	public function enqueue_front_scripts() {

		// Scripts not allowed in AMP.
		if ( genesis_is_amp() ) {
			return false;
		}

		// If a single post or page, threaded comments are enabled, and comments are open.
		if ( is_singular() && get_option( 'thread_comments' ) && comments_open() ) {
			wp_enqueue_script( 'comment-reply' );
		}

		// If superfish is enabled.
		if ( genesis_superfish_enabled() ) {

			wp_enqueue_script( 'superfish' );
			wp_enqueue_script( 'superfish-args' );

		}

		// If accessibility support enabled.
		if ( genesis_a11y( 'skip-links' ) ) {
			wp_enqueue_script( 'skip-links' );
		}

	}

	/**
	 * Conditionally enqueue the scripts used in the admin.
	 *
	 * Includes Thickbox, theme preview and a Genesis script (actually enqueued in genesis_load_admin_js()).
	 *
	 * @since 2.5.0
	 *
	 * @param string $hook_suffix Admin page identifier.
	 */
	public function maybe_enqueue_admin_scripts( $hook_suffix ) {

		if ( genesis_is_menu_page( 'genesis-getting-started' ) ) {
			wp_enqueue_script( 'van11y-accessible-modal-window-aria' );
		}

		// Only add thickbox/preview if there is an update to Genesis available.
		if ( genesis_update_check() ) {

			add_thickbox();
			wp_enqueue_script( 'theme-preview' );
			$this->enqueue_and_localize_admin_scripts();
			return;

		}

		// If we're on a Genesis admin screen.
		if ( genesis_is_menu_page( 'genesis' ) || genesis_is_menu_page( 'seo-settings' ) || genesis_is_menu_page( 'design-settings' ) || genesis_is_menu_page( 'genesis-getting-started' ) ) {

			$this->enqueue_and_localize_admin_scripts();
			return;

		}

		// If we're viewing an edit post page, make sure we need Genesis SEO JS.
		if (
			in_array( $hook_suffix, [ 'post-new.php', 'post.php' ], true )
			&& ! genesis_seo_disabled()
			&& post_type_supports( get_post_type(), 'genesis-seo' )
		) {
				$this->enqueue_and_localize_admin_scripts();
		}

	}

	/**
	 * Enqueues the custom script used in the admin, and localizes several strings or values used in the scripts.
	 *
	 * Applies the `genesis_toggles` filter to toggleable admin settings, so plugin developers can add their own without
	 * having to recreate the whole setup.
	 *
	 * @since 2.5.0
	 */
	public function enqueue_and_localize_admin_scripts() {

		wp_enqueue_script( 'genesis_admin_js' );

		$strings = [
			'categoryChecklistToggle' => __( 'Select / Deselect All', 'genesis' ),
			'saveAlert'               => __( 'The changes you made will be lost if you navigate away from this page.', 'genesis' ),
			'confirmUpgrade'          => __( 'Updating Genesis will overwrite the current installed version of Genesis. Are you sure you want to update?. "Cancel" to stop, "OK" to update.', 'genesis' ),
			'confirmReset'            => __( 'Are you sure you want to reset?', 'genesis' ),
		];

		wp_localize_script( 'genesis_admin_js', 'genesisL10n', $strings );

		$toggles = [
			// Checkboxes - when checked, show extra settings.
			'update'                    => [ '#genesis-settings\\[update\\]', '#genesis_update_notification_setting', '_checked' ],
			'content_archive_thumbnail' => [ '#genesis-settings\\[content_archive_thumbnail\\]', '#genesis_image_extras', '_checked' ],
			// Checkboxes - when unchecked, show extra settings.
			'semantic_headings'         => [ '#genesis-seo-settings\\[semantic_headings\\]', '#genesis_seo_h1_wrap', '_unchecked' ],
			// Select toggles.
			'nav_extras'                => [ '#genesis-settings\\[nav_extras\\]', '#genesis_nav_extras_twitter', 'twitter' ],
			'content_archive'           => [ '#genesis-settings\\[content_archive\\]', '#genesis_content_limit_setting', 'full' ],
		];

		wp_localize_script( 'genesis_admin_js', 'genesis_toggles', apply_filters( 'genesis_toggles', $toggles ) );

		$onboarding = [
			'nonce' => wp_create_nonce( 'genesis-onboarding' ),
			'l10n'  => [
				'a11y' => [
					'onboarding_started'  => esc_html__( 'The website setup process has started.', 'genesis' ),
					'onboarding_complete' => esc_html__( 'The website setup process has completed.', 'genesis' ),
					'step_started'        => esc_html__( 'A setup step has started.', 'genesis' ),
					'step_completed'      => esc_html__( 'A setup step has completed.', 'genesis' ),
				],
			],
		];

		if ( genesis_is_menu_page( 'genesis-getting-started' ) ) {
			$onboarding['tasks'] = genesis_onboarding_tasks();
		}

		wp_localize_script( 'genesis_admin_js', 'genesis_onboarding', $onboarding );
	}

	/**
	 * Enable whitelisted attributes on registered scripts by adding `...=true` to the script URL.
	 *
	 * @since 2.6.0
	 *
	 * @param string $tag    The script tag, generated by WordPress.
	 * @param string $handle The handle for the registered script.
	 * @param string $src    The source URL for the script.
	 * @return string $tag The (maybe) reformatted script tag.
	 */
	public function maybe_enable_attrs( $tag, $handle, $src ) {

		$supported_attributes = [
			'async',
			'defer',
		];

		$decoded_src = wp_specialchars_decode( $src );

		$query = wp_parse_url( $decoded_src, PHP_URL_QUERY );

		if ( ! $query ) {
			return $tag;
		}

		wp_parse_str( $query, $query_args );

		foreach ( $supported_attributes as $attr ) {

			if ( isset( $query_args[ $attr ] ) && 'true' === $query_args[ $attr ] ) {

				$new_src = esc_url( remove_query_arg( $attr, $decoded_src ) );

				$tag = genesis_strip_attr( $tag, 'script', $attr );
				$tag = str_replace( ' src=', ' ' . esc_attr( $attr ) . ' src=', $tag );
				$tag = str_replace( esc_html( $src ), $new_src, $tag );
			}
		}

		return $tag;

	}

	/**
	 * Determines which Genesis sidebar panels should be visible for the current post type.
	 *
	 * Intended for use on WordPress admin pages only.
	 *
	 * @since 3.1.1
	 *
	 * @param string $post_type Defaults to current post type if not passed.
	 * @return array Genesis editor sidebar panels that should be displayed for the given post type, with key as panel name.
	 */
	public function visible_genesis_sidebar_panels( $post_type = '' ) {

		$visible_panels = [];

		if ( ! $post_type ) {
			$current_screen = get_current_screen();
			$post_type      = $current_screen->post_type ?: '';
		}

		if ( ! post_type_supports( $post_type, 'custom-fields' ) ) {
			return [];
		}

		$post_type_is_public = false;
		$post_type_info      = get_post_type_object( $post_type );

		if ( ! is_null( $post_type_info ) && $post_type_info->public ) {
			$post_type_is_public = true;
		}

		// Breadcrumbs panel.
		$breadcrumbs_toggle_enabled  = apply_filters( 'genesis_breadcrumbs_toggle_enabled', true );
		$supports_breadcrumbs_toggle = post_type_supports( $post_type, 'genesis-breadcrumbs-toggle' );

		if (
			current_theme_supports( 'genesis-breadcrumbs' )
			&& $breadcrumbs_toggle_enabled
			&& $supports_breadcrumbs_toggle
		) {
			$visible_panels['breadcrumbs'] = 1;
		}

		// Title panel.
		$title_toggle_enabled  = apply_filters( 'genesis_title_toggle_enabled', true );
		$supports_title_toggle = post_type_supports( $post_type, 'genesis-title-toggle' );

		if ( $title_toggle_enabled && $supports_title_toggle ) {
			$visible_panels['title'] = 1;
		}

		// Image panel.
		$editing_blog_page    = 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_for_posts' ) === get_the_ID();
		$image_toggle_enabled = apply_filters( 'genesis_singular_image_toggle_enabled', true );

		if (
			$image_toggle_enabled
			&& post_type_supports( $post_type, 'genesis-singular-images' )
			&& ! $editing_blog_page
		) {
			$visible_panels['images'] = 1;
		}

		// Layout panel.
		$inpost_layouts_supported = current_theme_supports( 'genesis-inpost-layouts' );
		$supports_genesis_layouts = post_type_supports( $post_type, 'genesis-layouts' );

		if ( $inpost_layouts_supported && $supports_genesis_layouts ) {
			$visible_panels['layout'] = 1;
		}

		// Footer Widgets panel.
		$footer_widgets_toggle_enabled  = apply_filters( 'genesis_footer_widgets_toggle_enabled', true );
		$supports_footer_widgets_toggle = post_type_supports( $post_type, 'genesis-footer-widgets-toggle' );

		if (
			current_theme_supports( 'genesis-footer-widgets' )
			&& $footer_widgets_toggle_enabled
			&& $supports_footer_widgets_toggle
		) {
			$visible_panels['footer-widgets'] = 1;
		}

		// Custom classes panel.
		if ( $post_type_is_public ) {
			$visible_panels['custom-classes'] = 1;
		}

		return $visible_panels;

	}

}
