| @@ -551,9 +551,18 @@ | ||
| 551 | 551 | // /status block so the dashboard callout renders on first paint |
| 552 | 552 | // without waiting for a status re-fetch. |
| 553 | 553 | 'mobile_separate' => array( |
| 554 | 554 | 'enabled' => (bool) ( $opts['cache_enabled'] ? ( Settings_Manager::get( 'cache' )['mobile_separate'] ?? false ) : false ), |
| 555 | - 'blocking' => $rewrite_capable && 'mobile_separate' === Cache::static_rewrite_block_reason(), | |
| 555 | + // Gated to servers that HAVE a static fast path — on IIS or | |
| 556 | + // an undetected server block_reason still falls through to | |
| 557 | + // mobile_separate, and reporting that as "blocking" would | |
| 558 | + // nag about a rewrite that does not exist there (#108). | |
| 559 | + // LiteSpeed joined the capable set with the Static Fast | |
| 560 | + // Path opt-in (#509); its own refusal (litespeed_dropin) | |
| 561 | + // outranks mobile_separate, so this stays false there | |
| 562 | + // until the opt-in is on. | |
| 563 | + 'blocking' => ( $rewrite_capable || Server::LITESPEED === $server_type ) | |
| 564 | + && 'mobile_separate' === Cache::static_rewrite_block_reason(), | |
| 556 | 565 | 'needs_review' => Cache::mobile_separate_needs_review(), |
| 557 | 566 | ), |
| 558 | 567 | // One consolidated nginx server-block snippet aggregating |
| 559 | 568 | // every enabled module's directives (Cache static-rewrite, |
| @@ -560,8 +569,14 @@ | ||
| 560 | 569 | // BrowserCache headers, GZIP, …). Null on non-nginx hosts |
| 561 | 570 | // or when no module contributes directives. Replaces the |
| 562 | 571 | // per-module "paste this snippet" notices. |
| 563 | 572 | 'nginx_server_block' => Cache::full_nginx_server_block(), |
| 573 | + // Mirrors the /status block so the enable-time disclosure is | |
| 574 | + // correct on FIRST PAINT. Without it the top-bar switch can be | |
| 575 | + // clicked before a status fetch lands, and the one moment the | |
| 576 | + // warning exists for — a leftover drop-in about to be | |
| 577 | + // replaced — is exactly when it would be missing. | |
| 578 | + 'dropin' => Page_Cache_Detector::dropin_disclosure(), | |
| 564 | 579 | ), |
| 565 | 580 | // Registered Modules (Free + Pro). The React app discovers them |
| 566 | 581 | // here and renders one sidebar item + one panel per module that |
| 567 | 582 | // declares a settings schema. Hidden modules are filtered. |
| @@ -657,8 +672,15 @@ | ||
| 657 | 672 | // Public view: real values except secret fields, which are masked. |
| 658 | 673 | // The dashboard bundle localizes this into page HTML, so a raw |
| 659 | 674 | // credential here would be readable from view-source. (#115) |
| 660 | 675 | 'settings' => $settings, |
| 676 | + // Where each value actually came from: a wp-config.php constant, | |
| 677 | + // the option row, or the schema default. The panel renders a | |
| 678 | + // constant-sourced field read-only and names the constant, so it | |
| 679 | + // can never present an editable box over a value the site is not | |
| 680 | + // using. Every module gets this, not just the ones that declare | |
| 681 | + // constants today. (#398) | |
| 682 | + 'setting_origins' => Settings_Manager::origins( $slug ), | |
| 661 | 683 | 'schema' => $schema, |
| 662 | 684 | 'notices' => $module->ui_notices(), |
| 663 | 685 | 'custom_panel' => $meta['custom_panel'] ?? null, |
| 664 | 686 | ); |