array(), 'scripts' => array(), ); if ( null !== $set ) { $expected = $set; } return $expected; } /** * Records every queued OpenStation handle as expected to print. * * A handle is ours when its registered `src` sits under * `OPENSTATION_URL`. Third-party chromeless overrides (enqueued on * `openstation_chromeless_styles`) deliberately don't match — a * plugin that wants its own handles guarded adds them via the * `openstation_guarded_styles` / `openstation_guarded_scripts` * filters instead. */ function openstation_asset_guard_snapshot() { $store = openstation_asset_guard_store(); $pools = array( 'styles' => wp_styles(), 'scripts' => wp_scripts(), ); foreach ( $pools as $type => $dependencies ) { foreach ( $dependencies->queue as $handle ) { if ( in_array( $handle, $store[ $type ], true ) ) { continue; } if ( ! isset( $dependencies->registered[ $handle ] ) ) { continue; } $src = $dependencies->registered[ $handle ]->src; if ( is_string( $src ) && 0 === strpos( $src, OPENSTATION_URL ) ) { $store[ $type ][] = $handle; } } } openstation_asset_guard_store( $store ); } add_action( 'admin_enqueue_scripts', 'openstation_asset_guard_snapshot', 11 ); add_action( 'admin_enqueue_scripts', 'openstation_asset_guard_snapshot', PHP_INT_MAX ); /** * Collects `$handle` (dependencies first) into `$missing` unless it * is already queued to print, already printed, or unregistered. * * @param WP_Dependencies $dependencies The styles or scripts registry. * @param string $handle Handle to collect. * @param string[] $to_do Handles already queued to print. * @param string[] $missing Collected handles, in print order. Passed by reference. */ function openstation_asset_guard_collect( $dependencies, $handle, $to_do, &$missing ) { if ( in_array( $handle, $to_do, true ) || in_array( $handle, $missing, true ) || in_array( $handle, $dependencies->done, true ) || ! isset( $dependencies->registered[ $handle ] ) ) { return; } foreach ( $dependencies->registered[ $handle ]->deps as $dep ) { openstation_asset_guard_collect( $dependencies, $dep, $to_do, $missing ); } $missing[] = $handle; } /** * Appends any expected-but-missing handles to a to-print list. * * @param WP_Dependencies $dependencies The styles or scripts registry. * @param string[] $to_do Handles about to be printed. * @param string[] $handles Handles that must be among them. * @return string[] The to-print list with missing handles appended. */ function openstation_asset_guard_merge( $dependencies, $to_do, $handles ) { $missing = array(); foreach ( $handles as $handle ) { if ( is_string( $handle ) && '' !== $handle ) { openstation_asset_guard_collect( $dependencies, $handle, $to_do, $missing ); } } if ( empty( $missing ) ) { return $to_do; } return array_merge( $to_do, $missing ); } /** * Re-asserts snapshotted OpenStation styles into the to-print list. * * Runs inside `WP_Styles::all_deps()`, after any force-dequeue has * already happened — the last word before output. * * @param string[] $to_do Style handles about to be printed. * @return string[] */ function openstation_asset_guard_print_styles( $to_do ) { $store = openstation_asset_guard_store(); /** * Filters the style handles the asset guard re-asserts at print * time. * * Defaults to every style this plugin enqueued for the current * page. A plugin whose chromeless overrides are stripped by an * asset-cleanup plugin can append its own handles here. * * @param string[] $handles Style handles expected to print. */ $handles = apply_filters( 'openstation_guarded_styles', $store['styles'] ); if ( empty( $handles ) || ! is_array( $handles ) ) { return $to_do; } return openstation_asset_guard_merge( wp_styles(), $to_do, $handles ); } add_filter( 'print_styles_array', 'openstation_asset_guard_print_styles' ); /** * Re-asserts snapshotted OpenStation scripts into the to-print list. * * Only acts during the admin footer pass: every OpenStation bundle * is registered `in_footer`, and handles appended during the head * pass would print there without their group bookkeeping. Re-added * handles are stamped into the footer group so * `WP_Scripts::do_item()` finds the entry it expects. * * @param string[] $to_do Script handles about to be printed. * @return string[] */ function openstation_asset_guard_print_scripts( $to_do ) { if ( ! doing_action( 'admin_print_footer_scripts' ) ) { return $to_do; } $store = openstation_asset_guard_store(); /** * Filters the script handles the asset guard re-asserts at print * time. * * Defaults to every script this plugin enqueued for the current * page. A plugin whose iframe-side scripts are stripped by an * asset-cleanup plugin can append its own handles here. * * @param string[] $handles Script handles expected to print. */ $handles = apply_filters( 'openstation_guarded_scripts', $store['scripts'] ); if ( empty( $handles ) || ! is_array( $handles ) ) { return $to_do; } $scripts = wp_scripts(); $merged = openstation_asset_guard_merge( $scripts, $to_do, $handles ); foreach ( array_diff( $merged, $to_do ) as $handle ) { $scripts->groups[ $handle ] = 1; } return $merged; } add_filter( 'print_scripts_array', 'openstation_asset_guard_print_scripts' );