refactor(color): unify color sanitizing and picking behind shared components

- Add AKSRT\Core\Color::sanitize($value, $allow_alpha) as the single PHP
  color sanitizer; replace sanitize_hex_color calls and per-class regexes
  (FloatButtons, FieldSchema, ThemeSearch, icon cards, TicketStatusService)
- SchemaProvider / ControllerBase sanitize `color` fields as colors;
  alpha kept only when the schema sets showAlpha
- Split SchemaProvider OAuth validation and option matching into sibling
  traits to stay under the 1000-line limit
- Add AksColorPicker.vue + utils/color.js mirroring the PHP rules; AksField,
  FloatBtnCommonFields and TicketStatusPanel use it
- Widget background color input now uses wpColorPicker
- Remove dead AksCompositeField dimensions/spacing/background branches and
  the unused Gutenberg ColorPicker var
- Add color-unification contract test; update harness requires and tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-28 20:47:41 +08:00
1 parent 74021d26bb
commit 57ff405691
32 files changed
+522 -456

No files matched your search

+4 -7
View File
@@ -167,11 +167,8 @@ if (!function_exists('aksrt_icon_card')) :
}
$style = '';
$custom_color = sanitize_hex_color((string) $args['icon_custom_color']);
if (!$custom_color && preg_match('/^rgba?\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}(?:\s*,\s*(?:0|1|0?\.\d+))?\s*\)$/', (string) $args['icon_custom_color'])) {
$custom_color = (string) $args['icon_custom_color'];
}
if (!$radius && $custom_color) {
$custom_color = \AKSRT\Core\Color::sanitize($args['icon_custom_color'], true);
if (!$radius && $custom_color !== '') {
$style = ' style="color:' . esc_attr($custom_color) . ';"';
}
@@ -327,8 +324,8 @@ if (!function_exists('aksrt_icon_cover_card')) :
$icon_size = max(14, min(64, (int) $args['icon_size']));
// legacy always sets font-size on the icon badge.
$style = 'font-size: ' . $icon_size . 'px;';
$custom_color = sanitize_hex_color((string) $args['icon_custom_color']);
if ($custom_color) {
$custom_color = \AKSRT\Core\Color::sanitize($args['icon_custom_color'], true);
if ($custom_color !== '') {
$style .= 'color:' . $custom_color . ';';
}
+1 -1
View File
@@ -132,7 +132,7 @@ function aksrt_render_slider(array $args = []): string {
$title = sanitize_text_field($slide['title'] ?? '');
$desc = sanitize_text_field($slide['desc'] ?? '');
$alt = sanitize_text_field($slide['alt'] ?? $title);
$bg_color = sanitize_hex_color($slide['bg_color'] ?? '');
$bg_color = \AKSRT\Core\Color::sanitize($slide['bg_color'] ?? '');
$target = ($slide['target'] ?? '') === '_blank' ? '_blank' : '_self';
$slide_style = $bg_color ? 'background-color:' . esc_attr($bg_color) . ';' : '';
+1 -1
View File
@@ -443,7 +443,7 @@ if (!function_exists('aksrt_header_slide')) {
}
}
$nav_color = sanitize_hex_color((string) ($args['header_slider_nav_color'] ?? ''));
$nav_color = \AKSRT\Core\Color::sanitize((string) ($args['header_slider_nav_color'] ?? ''));
if ($nav_color && $nav_color !== '#ffffff') {
echo '<style>body.nav-fixed:not(.body-scroll):not(.mobile-navbar-show) .header.show-slide{--header-color:' . esc_html($nav_color) . ';}</style>';
}