| @@ -38,8 +38,36 @@ | ||
| 38 | 38 | |
| 39 | 39 | <div class="dashboard-card"> |
| 40 | 40 | <?php $this->render_compatibility_sections(); ?> |
| 41 | 41 | </div> |
| 42 | + | |
| 43 | + <?php | |
| 44 | + # Plugin-compatibility toggles. Registered under the | |
| 45 | + # <page_slug>_compatibility settings page only while the relevant | |
| 46 | + # plugin is active, so the card self-hides when neither plugin is | |
| 47 | + # present. Saves through options.php with a hidden active_tab so | |
| 48 | + # the General-tab sanitizer blocks stay inert. | |
| 49 | + $has_compat_fields = defined('WP_ROCKET_VERSION') | |
| 50 | + || class_exists('WP_Rocket') | |
| 51 | + || class_exists('SiteGround_Optimizer\Parser\Parser') | |
| 52 | + || defined('SiteGround_Optimizer\VERSION') | |
| 53 | + || class_exists('bookingpress_spam_protection'); | |
| 54 | + if ($has_compat_fields) : | |
| 55 | + settings_errors(); | |
| 56 | + ?> | |
| 57 | + <div class="dashboard-card" style="margin-top: 20px;"> | |
| 58 | + <h2 style="margin: 0 0 4px 0;">Plugin Compatibility Settings</h2> | |
| 59 | + <p style="color: var(--dashboard-text-secondary); margin: 0 0 20px 0;">Control how <?php echo esc_html(Metasync::get_effective_plugin_name()); ?> interacts with detected plugins. Each setting appears only while its plugin is active.</p> | |
| 60 | + <form method="post" action="options.php"> | |
| 61 | + <input type="hidden" name="active_tab" value="compatibility" /> | |
| 62 | + <?php | |
| 63 | + settings_fields(Metasync_Admin::option_group); | |
| 64 | + do_settings_sections(Metasync_Admin::$page_slug . '_compatibility'); | |
| 65 | + submit_button(); | |
| 66 | + ?> | |
| 67 | + </form> | |
| 68 | + </div> | |
| 69 | + <?php endif; ?> | |
| 42 | 70 | |
| 43 | 71 | <!-- Section: Host Blocking Test --> |
| 44 | 72 | <div id="ms-comp-host-test" class="dashboard-card" style="margin-top: 20px;"> |
| 45 | 73 | <details open> |
| @@ -134,9 +162,9 @@ | ||
| 134 | 162 | $.ajax({ |
| 135 | 163 | url: ajaxUrl, |
| 136 | 164 | type: 'POST', |
| 137 | 165 | dataType: 'json', |
| 138 | - data: { action: action, nonce: '<?php echo wp_create_nonce("metasync_nonce"); ?>' }, | |
| 166 | + data: { action: action, nonce: '<?php echo esc_attr(wp_create_nonce("metasync_nonce")); ?>' }, | |
| 139 | 167 | timeout: 35000, |
| 140 | 168 | success: function(response, textStatus, xhr) { |
| 141 | 169 | try { |
| 142 | 170 | if (response && response.success && response.data) { |
| @@ -507,8 +535,10 @@ | ||
| 507 | 535 | color: #646970 !important; |
| 508 | 536 | opacity: 0.7; |
| 509 | 537 | } |
| 510 | 538 | |
| 539 | + /* Equal width so badges of different lengths (Exact, Contains, | |
| 540 | + etc.) render at the same size for a visually balanced column. */ | |
| 511 | 541 | .otto-pattern-type-badge { |
| 512 | 542 | display: inline-block; |
| 513 | 543 | padding: 3px 8px; |
| 514 | 544 | border-radius: 3px; |
| @@ -515,8 +545,11 @@ | ||
| 515 | 545 | font-size: 11px; |
| 516 | 546 | font-weight: 600; |
| 517 | 547 | text-transform: uppercase; |
| 518 | 548 | letter-spacing: 0.5px; |
| 549 | + min-width: 90px; | |
| 550 | + text-align: center; | |
| 551 | + box-sizing: border-box; | |
| 519 | 552 | } |
| 520 | 553 | |
| 521 | 554 | /* Badge text is 11px uppercase, i.e. normal-size text: the darker |
| 522 | 555 | foreground steps keep every pair at or above the 4.5:1 AA bar |
| @@ -616,11 +649,15 @@ | ||
| 616 | 649 | border: 1px solid #dcdcde; |
| 617 | 650 | } |
| 618 | 651 | |
| 619 | 652 | #otto-excluded-urls-table-container .otto-delete-url, |
| 620 | - #otto-excluded-urls-table-container .otto-recheck-url { | |
| 653 | + #otto-excluded-urls-table-container .otto-recheck-url, | |
| 654 | + #otto-excluded-urls-table-container .otto-recheck-disabled { | |
| 621 | 655 | padding: 4px 10px; |
| 622 | 656 | font-size: 12px; |
| 657 | + box-sizing: border-box; | |
| 658 | + height: 26px; | |
| 659 | + line-height: 1; | |
| 623 | 660 | } |
| 624 | 661 | |
| 625 | 662 | #otto-excluded-urls-table-container .otto-delete-url { |
| 626 | 663 | background: #dc3545 !important; |