'vc-backend-min-js', 'frontend' => 'vc-frontend-editor-min-js', ); /** * Registers the hooks WPBakery fires while rendering its editors. */ public static function register(): void { add_action( 'vc_backend_editor_enqueue_js_css', array( self::class, 'enqueue_backend' ) ); add_action( 'vc_frontend_editor_enqueue_js_css', array( self::class, 'enqueue_frontend' ) ); add_action( 'vc_load_iframe_jscss', array( self::class, 'enqueue_iframe' ) ); add_filter( 'vc_nav_controls', array( self::class, 'add_nav_control' ) ); add_filter( 'vc_nav_front_controls', array( self::class, 'add_nav_control' ) ); } /** * Backend editor: buttons and navbar menu in the same document. */ public static function enqueue_backend(): void { self::enqueue_entry( 'backend', self::VC_HANDLES['backend'] ); } /** * Frontend editor: script and navbar menu in the editor page. */ public static function enqueue_frontend(): void { self::enqueue_entry( 'frontend', self::VC_HANDLES['frontend'] ); } /** * Frontend editor: button styles inside the page preview iframe. */ public static function enqueue_iframe(): void { if ( ! current_user_can( 'edit_posts' ) ) { return; } $asset = self::asset( 'iframe' ); if ( null === $asset ) { return; } wp_enqueue_style( self::HANDLE_PREFIX . 'iframe', SHIFTSNAP_URL . 'build/iframe.css', array(), $asset['version'] ); } /** * Adds an empty navbar item that the script fills with the clipboard menu. * * @param mixed $controls List of [ slug, html ] pairs. * @return mixed */ public static function add_nav_control( $controls ) { if ( ! is_array( $controls ) || ! current_user_can( 'edit_posts' ) ) { return $controls; } $controls[] = array( 'shiftsnap', self::nav_markup() ); return $controls; } /** * Navbar item markup. */ public static function nav_markup(): string { return ''; } /** * Enqueues a built script and its style. * * @param string $entry Entry name in `build/`. * @param string $vc_handle WPBakery script that must load first. */ private static function enqueue_entry( string $entry, string $vc_handle ): void { if ( ! current_user_can( 'edit_posts' ) ) { return; } $asset = self::asset( $entry ); if ( null === $asset ) { return; } $handle = self::HANDLE_PREFIX . $entry; $dependencies = $asset['dependencies']; if ( wp_script_is( $vc_handle, 'registered' ) ) { $dependencies[] = $vc_handle; } wp_enqueue_script( $handle, SHIFTSNAP_URL . "build/{$entry}.js", $dependencies, $asset['version'], true ); wp_set_script_translations( $handle, 'shift-snapcopy' ); wp_add_inline_script( $handle, 'window.shiftsnapConfig = ' . wp_json_encode( self::config() ) . ';', 'before' ); wp_enqueue_style( $handle, SHIFTSNAP_URL . "build/{$entry}.css", array(), $asset['version'] ); } /** * Settings the editor script needs: the user's preferences and where to change them. * * @return array */ public static function config(): array { return array( 'prefs' => Preferences::get( get_current_user_id() ), 'hasPrefs' => Preferences::exists( get_current_user_id() ), 'settingsUrl' => SettingsPage::url(), ); } /** * Reads the dependencies and version webpack wrote for an entry. * * @param string $entry Entry name in `build/`. * @return array{dependencies: string[], version: string}|null Null when the plugin is not built. */ private static function asset( string $entry ): ?array { $file = SHIFTSNAP_DIR . "build/{$entry}.asset.php"; if ( ! is_readable( $file ) ) { return null; } $asset = require $file; return is_array( $asset ) ? $asset : null; } }