PluginProbe
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress / 4.1.2
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress v4.1.2
4.1.2 4.1.1 4.1.0 4.0.1 4.0.0 3.3.1 3.3.0 trunk 1.0.0 2.0.0 2.1.0 3.0.0 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8
← All changes | admin/templates/page-settings.php +978 -173 3.0.04.1.2 View file →
@@ -1,216 +1,1021 @@
1 1 <?php
2 +if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3 +
2 4 /**
3 5 * The admin settings of the plugin.
4 6 * @since 1.0.0
5 7 */
6 8 ?>
7 -<h1><?php _e( "QuickWebp Settings", QUICKWEBP_TEXT_DOMAIN ); ?></h1>
9 +<div class="quickwebp-settings-v2" data-current-profile="<?php echo esc_attr( $profile_label ); ?>">
8 10
9 -<form action="" method="post">
11 + <header class="quickwebp-hero">
12 + <h1><?php esc_html_e( 'QuickWebP Settings', 'quickwebp' ); ?></h1>
13 + <p><?php esc_html_e( 'Configure your image workflow with coherent presets, guarded options, and an optimized media delivery strategy.', 'quickwebp' ); ?></p>
14 + </header>
10 15
11 - <table class="form-table">
16 + <form action="" method="post" class="quickwebp-settings-form">
17 + <div class="quickwebp-layout">
18 + <main class="quickwebp-main">
19 + <?php if ( $show_onboarding ) : ?>
20 + <section class="quickwebp-card" id="quickwebp-onboarding">
21 + <div class="quickwebp-card-head">
22 + <h2><?php esc_html_e( 'Quick setup assistant', 'quickwebp' ); ?></h2>
23 + <p><?php esc_html_e( 'Start from a recommended profile and refine only what you need.', 'quickwebp' ); ?></p>
24 + </div>
25 + <div class="quickwebp-card-body">
26 + <div class="quickwebp-onboarding-grid">
27 + <button type="button" class="quickwebp-onboarding-option quickwebp-onboarding-apply" data-profile="new-site">
28 + <strong><?php esc_html_e( 'New site with few media', 'quickwebp' ); ?></strong>
29 + <span><?php esc_html_e( 'Replace originals on upload for the simplest and fastest workflow.', 'quickwebp' ); ?></span>
30 + </button>
31 + <button type="button" class="quickwebp-onboarding-option quickwebp-onboarding-apply" data-profile="existing-site">
32 + <strong><?php esc_html_e( 'Existing site with many media', 'quickwebp' ); ?></strong>
33 + <span><?php esc_html_e( 'Keep originals, enable rewrite delivery, and run bulk optimization.', 'quickwebp' ); ?></span>
34 + </button>
35 + </div>
36 + <p class="quickwebp-onboarding-feedback" aria-live="polite"></p>
37 + </div>
38 + </section>
39 + <?php endif; ?>
12 40
13 - <?php $this->render_component( array(
14 - 'type' => 'toggle',
15 - 'name' => 'quickwebp_settings_conversion',
16 - 'label' => __( "Enable/disable image conversion to WEBP format", QUICKWEBP_TEXT_DOMAIN ),
17 - 'default' => quickwebp_settings_default('quickwebp_settings_conversion'),
18 - 'classes' => 'toggle-with-children',
19 - )); ?>
41 + <section class="quickwebp-card" id="quickwebp-conversion">
42 + <div class="quickwebp-card-head">
43 + <h2><?php esc_html_e( 'Conversion and Delivery', 'quickwebp' ); ?></h2>
44 + <p><?php esc_html_e( 'Define how images are converted, preserved, and delivered on frontend pages.', 'quickwebp' ); ?></p>
45 + </div>
46 + <div class="quickwebp-card-body">
47 + <table class="form-table">
48 +
49 + <?php $this->render_component( array(
50 + 'type' => 'button-group',
51 + 'name' => 'quickwebp_settings_conversion',
52 + 'label' => __( 'Image Format Optimization', 'quickwebp' ),
53 + 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion' ),
54 + 'options' => array(
55 + array(
56 + 'label' => __( 'Off', 'quickwebp' ),
57 + 'color' => '#000000',
58 + 'desc' => __( '0% saved', 'quickwebp' ),
59 + 'value' => '0',
60 + 'classes' => 'toggle-with-children',
61 + ),
62 + array(
63 + 'label' => __( 'WebP', 'quickwebp' ),
64 + 'color' => '#316BFF',
65 + 'desc' => __( '≈ −30% on average across a site', 'quickwebp' ),
66 + 'value' => '1',
67 + 'classes' => 'toggle-with-children',
68 + ),
69 + array(
70 + 'label' => __( 'AVIF', 'quickwebp' ),
71 + 'color' => '#16A34A',
72 + 'desc' => __( '≈ −50% on average across a site', 'quickwebp' ),
73 + 'value' => '2',
74 + 'classes' => 'toggle-with-children',
75 + 'parent_classes' => 'quickwebp__pro-popup-open',
76 + 'disabled' => ! $license_valid || ! $php_version_valid,
77 + 'taglines' => array(
78 + array(
79 + 'label' => 'Pro',
80 + 'value' => 'pro',
81 + 'show' => ! $license_valid,
82 + ),
83 + array(
84 + 'label' => 'Requires PHP 8.1+',
85 + 'value' => 'pro',
86 + 'show' => ! $php_version_valid,
87 + ),
88 + array(
89 + 'label' => __( 'Recommended', 'quickwebp' ),
90 + 'value' => 'recommended',
91 + 'show' => true,
92 + ),
93 + ),
94 + )
95 + )
96 + ) ); ?>
20 97
21 - <tbody class="form-table children">
98 + <tbody class="form-table children">
22 99
23 - <?php $this->render_component( array(
24 - 'type' => 'range-slider',
25 - 'min' => 0,
26 - 'max' => 100,
27 - 'step' => 1,
28 - 'unit' => '%',
29 - 'name' => 'quickwebp_settings_conversion_quality',
30 - 'label' => __( 'Quality', QUICKWEBP_TEXT_DOMAIN ),
31 - 'default' => quickwebp_settings_default('quickwebp_settings_conversion_quality')
32 - )); ?>
100 + <?php $this->render_component( array(
101 + 'type' => 'button-group',
102 + 'name' => 'quickwebp_settings_conversion_quality',
103 + 'label' => __( 'Image Quality', 'quickwebp' ),
104 + 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion_quality' ),
105 + 'options' => array(
106 + array(
107 + 'label' => __( 'Low', 'quickwebp' ),
108 + 'value' => 'low',
109 + 'color' => '#E74C3C',
110 + 'desc' => __( 'Smallest size', 'quickwebp' ),
111 + ),
112 + array(
113 + 'label' => __( 'Medium', 'quickwebp' ),
114 + 'value' => 'medium',
115 + 'color' => '#E67E22',
116 + 'desc' => __( 'Good balance', 'quickwebp' ),
117 + ),
118 + array(
119 + 'label' => __( 'High', 'quickwebp' ),
120 + 'value' => 'high',
121 + 'color' => '#16A34A',
122 + 'desc' => __( 'High quality & good size', 'quickwebp' ),
123 + 'taglines' => array(
124 + array(
125 + 'label' => __( 'Recommended', 'quickwebp' ),
126 + 'value' => 'recommended',
127 + 'show' => true,
128 + ),
129 + ),
130 + ),
131 + array(
132 + 'label' => __( 'Extra High', 'quickwebp' ),
133 + 'value' => 'extra_high',
134 + 'color' => '#2563EB',
135 + 'desc' => __( 'Maximum quality', 'quickwebp' ),
136 + ),
137 + )
138 + ) ); ?>
33 139
34 - <?php $this->render_component( array(
35 - 'type' => 'range-slider',
36 - 'min' => 0,
37 - 'max' => 100,
38 - 'step' => 1,
39 - 'unit' => '%',
40 - 'name' => 'quickwebp_settings_conversion_sharpen',
41 - 'label' => __( 'Sharpen', QUICKWEBP_TEXT_DOMAIN ),
42 - 'default' => quickwebp_settings_default('quickwebp_settings_conversion_sharpen')
43 - )); ?>
140 + <tr>
141 + <th><label><?php esc_html_e( 'Preview', 'quickwebp' ); ?></label></th>
142 + <td>
143 + <?php include QUICKWEBP_PLUGIN_PATH . 'admin/templates/popup-settings-preview.php'; ?>
144 + </td>
145 + </tr>
44 146
45 - <?php $this->render_component( array(
46 - 'type' => 'checkbox',
47 - 'name' => 'quickwebp_settings_conversion_ignore_webp',
48 - 'label' => __( "Do not compress images already in WebP", QUICKWEBP_TEXT_DOMAIN ),
49 - 'default' => quickwebp_settings_default('quickwebp_settings_conversion_ignore_webp'),
50 - 'options' => array(
51 - array(
52 - 'label' => '',
53 - 'value' => 'checked'
54 - )
55 - )
56 - )); ?>
147 + <?php $this->render_component( array(
148 + 'type' => 'checkbox',
149 + 'name' => 'quickwebp_settings_conversion_ignore_webp',
150 + 'label' => __( 'Do not compress images already in same format', 'quickwebp' ),
151 + 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion_ignore_webp' ),
152 + 'options' => array(
153 + array(
154 + 'label' => '',
155 + 'value' => 'checked'
156 + )
157 + )
158 + ) ); ?>
57 159
58 - <tr>
59 - <th>
60 - <label><?php _e( 'Before saving, test your configuration with preview mode.', QUICKWEBP_TEXT_DOMAIN ); ?></label>
61 - </th>
62 - <td>
63 - <?php include QUICKWEBP_PLUGIN_PATH . 'admin/templates/popup-settings-preview.php'; ?>
64 - </td>
65 - </tr>
160 + <?php $this->render_component( array(
161 + 'type' => 'checkbox',
162 + 'name' => 'quickwebp_settings_conversion_save_original',
163 + 'label' => __( 'Save original images', 'quickwebp' ),
164 + 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion_save_original' ),
165 + 'options' => array(
166 + array(
167 + 'label' => '',
168 + 'value' => 'checked'
169 + )
170 + )
171 + ) ); ?>
66 172
67 - <?php $this->render_component( array(
68 - 'type' => 'checkbox',
69 - 'name' => 'quickwebp_settings_conversion_display_webp',
70 - 'label' => __( "Display images in WebP format on the site", QUICKWEBP_TEXT_DOMAIN ),
71 - 'description' => __( "If activated, this option allows to deliver optimized images in bulk via QuickWebP in WebP format (useless for images converted to import)", QUICKWEBP_TEXT_DOMAIN ),
72 - 'default' => quickwebp_settings_default('quickwebp_settings_conversion_display_webp'),
73 - 'options' => array(
74 - array(
75 - 'label' => '',
76 - 'value' => 'checked'
77 - )
78 - )
79 - )); ?>
173 + <tr class="quickwebp-guidance-row">
174 + <th>
175 + <label><?php esc_html_e( 'Consistency guidance', 'quickwebp' ); ?></label>
176 + </th>
177 + <td>
178 + <div class="quickwebp-guidance-box">
179 + <p class="quickwebp-guidance-message" aria-live="polite"></p>
180 + </div>
181 + </td>
182 + </tr>
80 183
81 - <tr>
82 - <th>
83 - <label><?php _e( 'Bulk optimization', QUICKWEBP_TEXT_DOMAIN ); ?></label>
84 - </th>
85 - <td>
86 - <?php include QUICKWEBP_PLUGIN_PATH . 'admin/templates/bulk-optimization.php'; ?>
87 - </td>
88 - </tr>
184 + <?php
185 + $quickwebp_description_for_nginx = $is_nginx ? __( "If you choose to use rewrite rules, the file conf/quickwebp.conf will be created and must be included into the server's configuration file (then restart the server).", 'quickwebp' ) : '';
89 186
90 - </tbody>
187 + $this->render_component( array(
188 + 'type' => 'radio',
189 + 'name' => 'quickwebp_settings_conversion_display_webp_mode',
190 + 'label' => __( 'Display images in WebP format on the site', 'quickwebp' ),
191 + 'description' => sprintf(
192 + // translators: %s is a placeholder for the description for nginx.
193 + __( 'If activated, this option allows to deliver optimized images in bulk via QuickWebP in WebP format (useless for images converted to import). %s', 'quickwebp' ),
194 + $quickwebp_description_for_nginx
195 + ),
196 + 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion_display_webp_mode' ),
197 + 'options' => array(
198 + array(
199 + 'label' => __( 'Deactivate', 'quickwebp' ),
200 + 'value' => 'disabled'
201 + ),
202 + array(
203 + 'label' => __( 'Use <picture> tags', 'quickwebp' ),
204 + 'value' => 'picture'
205 + ),
206 + array(
207 + 'label' => sprintf(
208 + // translators: %s is a placeholder for the text "(beta)" if the server is Nginx.
209 + __( 'Use rewrite rules %s', 'quickwebp' ),
210 + $is_nginx ? '(beta)' : ''
211 + ),
212 + 'value' => 'rewrite'
213 + )
214 + )
215 + ) );
216 + ?>
91 217
92 - </table>
218 + <tr class="quickwebp-display-warning-row" style="display:none;">
219 + <th>
220 + <label><?php esc_html_e( 'Why this is locked', 'quickwebp' ); ?></label>
221 + </th>
222 + <td>
223 + <p class="quickwebp-display-warning"></p>
224 + </td>
225 + </tr>
93 226
94 - <hr>
95 -
96 - <table class="form-table">
227 + <tr class="quickwebp-row-bulk-optimization">
228 + <th>
229 + <label><?php esc_html_e( 'Bulk optimization', 'quickwebp' ); ?></label>
230 + </th>
231 + <td>
232 + <?php include QUICKWEBP_PLUGIN_PATH . 'admin/templates/bulk-optimization.php'; ?>
233 + </td>
234 + </tr>
97 235
98 - <?php $this->render_component( array(
99 - 'type' => 'toggle',
100 - 'name' => 'quickwebp_settings_resize',
101 - 'label' => __( "Enable/disable image resizing", QUICKWEBP_TEXT_DOMAIN ),
102 - 'default' => quickwebp_settings_default('quickwebp_settings_resize'),
103 - 'classes' => 'toggle-with-children',
104 - 'description' => __( "By default, WordPress limits the maximum width of uploaded images to 2560 pixels.", QUICKWEBP_TEXT_DOMAIN ),
105 - )); ?>
236 + </tbody>
106 237
107 - <tbody class="form-table children">
238 + </table>
239 + </div>
240 + </section>
108 241
109 - <?php $this->render_component( array(
110 - 'type' => 'number',
111 - 'name' => 'quickwebp_settings_resize_value',
112 - 'label' => __( 'Max size', QUICKWEBP_TEXT_DOMAIN ),
113 - 'default' => quickwebp_settings_default('quickwebp_settings_resize_value')
114 - )); ?>
242 + <section class="quickwebp-card" id="quickwebp-resize">
243 + <div class="quickwebp-card-head">
244 + <h2><?php esc_html_e( 'Resize', 'quickwebp' ); ?></h2>
245 + <p><?php esc_html_e( 'Keep your uploads under control to reduce bandwidth and processing costs.', 'quickwebp' ); ?></p>
246 + </div>
247 + <div class="quickwebp-card-body">
248 + <table class="form-table">
249 + <?php $this->render_component( array(
250 + 'type' => 'toggle',
251 + 'name' => 'quickwebp_settings_resize',
252 + 'label' => __( 'Enable/disable image resizing', 'quickwebp' ),
253 + 'default' => quickwebp_settings_default( 'quickwebp_settings_resize' ),
254 + 'classes' => 'toggle-with-children',
255 + 'description' => __( 'By default, WordPress limits the maximum width of uploaded images to 2560 pixels.', 'quickwebp' ),
256 + ) ); ?>
115 257
116 - </tbody>
258 + <tbody class="form-table children">
259 + <?php $this->render_component( array(
260 + 'type' => 'number',
261 + 'name' => 'quickwebp_settings_resize_value',
262 + 'label' => __( 'Max size', 'quickwebp' ),
263 + 'default' => quickwebp_settings_default( 'quickwebp_settings_resize_value' )
264 + ) ); ?>
265 + </tbody>
266 + </table>
267 + </div>
268 + </section>
117 269
118 - </table>
270 + <section class="quickwebp-card" id="quickwebp-seo">
271 + <div class="quickwebp-card-head">
272 + <h2><?php esc_html_e( 'SEO metadata automation', 'quickwebp' ); ?></h2>
273 + <p><?php esc_html_e( 'Auto-fill media fields from image names for a faster editorial workflow.', 'quickwebp' ); ?></p>
274 + </div>
275 + <div class="quickwebp-card-body">
276 + <table class="form-table">
277 + <?php $this->render_component( array(
278 + 'type' => 'toggle',
279 + 'name' => 'quickwebp_settings_completion',
280 + 'label' => __( 'Enable/disable smart media completion for SEO', 'quickwebp' ),
281 + 'default' => quickwebp_settings_default( 'quickwebp_settings_completion' ),
282 + 'classes' => 'toggle-with-children',
283 + 'description' => __( 'This feature will automatically complete the media information (title, caption, alt text, description) from the image name.', 'quickwebp' ),
284 + ) ); ?>
119 285
120 - <hr>
286 + <tbody class="form-table children">
287 + <?php $this->render_component( array(
288 + 'type' => 'checkbox',
289 + 'name' => 'quickwebp_settings_completion_options',
290 + 'default' => quickwebp_settings_default( 'quickwebp_settings_completion_options' ),
291 + 'options' => array(
292 + array(
293 + 'label' => __( 'Title completion from image name', 'quickwebp' ),
294 + 'value' => 'title',
295 + ),
296 + array(
297 + 'label' => __( 'Caption completion from image name.', 'quickwebp' ),
298 + 'value' => 'caption',
299 + ),
300 + array(
301 + 'label' => __( 'Alt text completion from image name.', 'quickwebp' ),
302 + 'value' => 'alt',
303 + ),
304 + array(
305 + 'label' => __( 'Description completion from image name.', 'quickwebp' ),
306 + 'value' => 'description',
307 + )
308 + )
309 + ) ); ?>
310 + </tbody>
311 + </table>
121 312
122 - <table class="form-table">
313 + <div class="quickwebp-seo-example">
314 + <h3><?php esc_html_e( 'Live example', 'quickwebp' ); ?></h3>
315 + <p><?php esc_html_e( 'Use a descriptive filename once (including spaces or apostrophes), and metadata is auto-filled from that original filename without the extension.', 'quickwebp' ); ?></p>
316 + <input
317 + type="text"
318 + class="quickwebp-seo-example-input"
319 + value="Men's Summer Shoes - Limited Edition 2026.jpg"
320 + aria-label="<?php echo esc_attr__( 'SEO metadata example filename', 'quickwebp' ); ?>"
321 + >
123 322
124 - <?php $this->render_component( array(
125 - 'type' => 'toggle',
126 - 'name' => 'quickwebp_settings_completion',
127 - 'label' => __( "Enable/disable smart media completion for SEO", QUICKWEBP_TEXT_DOMAIN ),
128 - 'default' => quickwebp_settings_default('quickwebp_settings_completion'),
129 - 'classes' => 'toggle-with-children',
130 - 'description' => __( "This feature will automatically complete the media information (title, caption, alt text, description) from the image name.", QUICKWEBP_TEXT_DOMAIN ),
131 - )); ?>
323 + <div class="quickwebp-seo-example-grid">
324 + <div class="quickwebp-seo-example-item">
325 + <strong><?php esc_html_e( 'Title', 'quickwebp' ); ?></strong>
326 + <span class="quickwebp-seo-preview-title"></span>
327 + </div>
328 + <div class="quickwebp-seo-example-item">
329 + <strong><?php esc_html_e( 'Caption', 'quickwebp' ); ?></strong>
330 + <span class="quickwebp-seo-preview-caption"></span>
331 + </div>
332 + <div class="quickwebp-seo-example-item">
333 + <strong><?php esc_html_e( 'Alt text', 'quickwebp' ); ?></strong>
334 + <span class="quickwebp-seo-preview-alt"></span>
335 + </div>
336 + <div class="quickwebp-seo-example-item">
337 + <strong><?php esc_html_e( 'Description', 'quickwebp' ); ?></strong>
338 + <span class="quickwebp-seo-preview-description"></span>
339 + </div>
340 + </div>
341 + </div>
342 + </div>
343 + </section>
132 344
133 - <tbody class="form-table children">
345 + <section class="quickwebp-card" id="quickwebp-tools">
346 + <div class="quickwebp-card-head">
347 + <h2><?php esc_html_e( 'Other tools', 'quickwebp' ); ?></h2>
348 + <p><?php esc_html_e( 'Fine tune file naming, paste behavior, and local image processing.', 'quickwebp' ); ?></p>
349 + </div>
350 + <div class="quickwebp-card-body">
351 + <table class="form-table">
352 + <?php $this->render_component( array(
353 + 'type' => 'toggle',
354 + 'name' => 'quickwebp_settings_cleanup',
355 + 'label' => __( 'Enable/disable file name cleanup', 'quickwebp' ),
356 + 'default' => quickwebp_settings_default( 'quickwebp_settings_cleanup' ),
357 + // 'description' => __( 'Remove special characters from file names.', 'quickwebp' ),
358 + ) ); ?>
134 359
135 - <?php $this->render_component( array(
136 - 'type' => 'checkbox',
137 - 'name' => 'quickwebp_settings_completion_options',
138 - 'default' => quickwebp_settings_default('quickwebp_settings_completion_options'),
139 - 'options' => array(
140 - array(
141 - 'label' => __( 'Title completion from image name', QUICKWEBP_TEXT_DOMAIN ),
142 - 'value' => 'title',
143 - ),
144 - array(
145 - 'label' => __( 'Caption completion from image name.', QUICKWEBP_TEXT_DOMAIN ),
146 - 'value' => 'caption',
147 - ),
148 - array(
149 - 'label' => __( 'Alt text completion from image name.', QUICKWEBP_TEXT_DOMAIN ),
150 - 'value' => 'alt',
151 - ),
152 - array(
153 - 'label' => __( 'Description completion from image name.', QUICKWEBP_TEXT_DOMAIN ),
154 - 'value' => 'description',
155 - )
156 - )
157 - )); ?>
360 + <tr class="quickwebp-cleanup-example-row">
361 + <th>
362 +
363 + </th>
364 + <td>
365 + <div class="quickwebp-cleanup-example">
366 + <p><?php esc_html_e( 'Use a filename with spaces, apostrophes, or accents to preview the cleaned filename.', 'quickwebp' ); ?></p>
367 + <input
368 + type="text"
369 + class="quickwebp-cleanup-example-input"
370 + value="Men's Summer Shoes - Limited Edition 2026.jpg"
371 + aria-label="<?php echo esc_attr__( 'Cleanup filename example input', 'quickwebp' ); ?>"
372 + >
373 + <div class="quickwebp-cleanup-example-grid">
374 + <div class="quickwebp-cleanup-example-item">
375 + <strong><?php esc_html_e( 'Original filename', 'quickwebp' ); ?></strong>
376 + <span class="quickwebp-cleanup-preview-original"></span>
377 + </div>
378 + <div class="quickwebp-cleanup-example-item">
379 + <strong><?php esc_html_e( 'Cleaned filename', 'quickwebp' ); ?></strong>
380 + <span class="quickwebp-cleanup-preview-cleaned"></span>
381 + </div>
382 + </div>
383 + </div>
384 + </td>
385 + </tr>
158 386
159 - </tbody>
387 + <?php $this->render_component( array(
388 + 'type' => 'toggle',
389 + 'name' => 'quickwebp_settings_paste_image',
390 + 'label' => __( 'Enable/disable paste picture directly (beta)', 'quickwebp' ),
391 + 'default' => quickwebp_settings_default( 'quickwebp_settings_paste_image' ),
392 + 'description' => __( 'With this feature you can paste directly your picture in WordPress media.', 'quickwebp' ),
393 + ) ); ?>
160 394
161 - </table>
395 + <?php $this->render_component( array(
396 + 'type' => 'toggle',
397 + 'name' => 'quickwebp_settings_debug_mode',
398 + 'label' => __( 'Enable/disable debug mode', 'quickwebp' ),
399 + 'default' => quickwebp_settings_default( 'quickwebp_settings_debug_mode' ),
400 + 'description' => sprintf(
401 + /* translators: %s: debug log path. */
402 + __( 'Write detailed optimization logs to %s.', 'quickwebp' ),
403 + quickwebp_get_debug_log_path()
404 + ),
405 + ) ); ?>
406 + </table>
407 + </div>
408 + </section>
162 409
163 - <hr>
410 + <section class="quickwebp-card" id="quickwebp-migration">
411 + <div class="quickwebp-card-head">
412 + <h2><?php esc_html_e( 'Migration notice', 'quickwebp' ); ?></h2>
413 + <p><?php esc_html_e( 'QuickWebP is now available inside WPMasterToolKit.', 'quickwebp' ); ?></p>
414 + </div>
415 + <div class="quickwebp-card-body">
416 + <p><?php esc_html_e( 'QuickWebP is now part of the WPMasterToolKit plugin. You can download it for free on the WordPress repository.', 'quickwebp' ); ?></p>
417 + <video autoplay loop muted controls class="quickwebp-migration-video">
418 + <source src="<?php echo esc_url( QUICKWEBP_PLUGIN_URL . 'public/assets/video/wpmastertoolkit.mp4' ); ?>" type="video/mp4">
419 + <?php esc_html_e( 'Your browser does not support the video tag.', 'quickwebp' ); ?>
420 + </video>
421 + <?php if ( $wpmtk_is_active ) : ?>
422 + <p><strong><?php esc_html_e( 'You can now deactivate QuickWebP and finish the migration.', 'quickwebp' ); ?></strong></p>
423 + <?php else : ?>
424 + <p>
425 + <a href="<?php echo esc_url( admin_url( 'plugin-install.php?s=wpmastertoolkit&tab=search&type=term' ) ); ?>" class="button button-primary" target="_blank"><?php esc_html_e( 'Download WPMasterToolKit', 'quickwebp' ); ?></a>
426 + <a href="https://wordpress.org/plugins/wpmastertoolkit/" class="button button-secondary" target="_blank"><?php esc_html_e( 'Download WPMasterToolKit from wordpress.org', 'quickwebp' ); ?></a>
427 + </p>
428 + <?php endif; ?>
429 + </div>
430 + </section>
164 431
165 - <table class="form-table">
432 + <div class="quickwebp-submit-wrap">
433 + <?php submit_button( __( 'Save settings', 'quickwebp' ), 'primary', 'submit', false ); ?>
434 + <p class="quickwebp-submit-note"><?php esc_html_e( 'Your consistency rules are enforced automatically when saving.', 'quickwebp' ); ?></p>
435 + </div>
166 436
167 - <?php $this->render_component( array(
168 - 'type' => 'toggle',
169 - 'name' => 'quickwebp_settings_cleanup',
170 - 'label' => __( "Enable/disable file name cleanup", QUICKWEBP_TEXT_DOMAIN ),
171 - 'default' => quickwebp_settings_default('quickwebp_settings_cleanup'),
172 - 'description' => __( "Remove special characters from file names.", QUICKWEBP_TEXT_DOMAIN ),
173 - )); ?>
437 + <div class="quickwebp-credits">
438 + <p>
439 + <?php esc_html_e( 'This plugin is developed by', 'quickwebp' ); ?>
440 + <a href="https://webdeclic.com/" target="_blank">Webdeclic</a>.
441 + <?php esc_html_e( 'You can support this project here:', 'quickwebp' ); ?>
442 + <a href="https://www.buymeacoffee.com/ludwig" target="_blank"><?php esc_html_e( 'Buy me a coffee', 'quickwebp' ); ?></a>.
443 + </p>
444 + <p>
445 + <?php esc_html_e( 'You can show all Webdeclic plugins on', 'quickwebp' ); ?>
446 + <a href="https://wordpress.org/plugins/search/webdeclic/" target="_blank">wordpress.org</a>.
447 + </p>
448 + </div>
449 + </main>
174 450
175 - </table>
176 -
177 - <hr>
451 + <aside class="quickwebp-aside">
452 + <div class="quickwebp-aside-inner">
453 + <section class="quickwebp-card">
454 + <div class="quickwebp-card-head">
455 + <h2><?php esc_html_e( 'Live configuration summary', 'quickwebp' ); ?></h2>
456 + <p><?php esc_html_e( 'This panel updates instantly while you edit your settings.', 'quickwebp' ); ?></p>
457 + </div>
458 + <div class="quickwebp-card-body">
459 + <ul class="quickwebp-summary-list">
460 + <li>
461 + <span class="quickwebp-summary-label"><?php esc_html_e( 'Conversion', 'quickwebp' ); ?></span>
462 + <span class="quickwebp-summary-value quickwebp-summary-conversion-side"><?php echo esc_html( $conversion_enabled ? __( 'Enabled', 'quickwebp' ) : __( 'Disabled', 'quickwebp' ) ); ?></span>
463 + </li>
464 + <li>
465 + <span class="quickwebp-summary-label"><?php esc_html_e( 'Original images', 'quickwebp' ); ?></span>
466 + <span class="quickwebp-summary-value quickwebp-summary-originals-side"><?php echo esc_html( $save_original_enabled ? __( 'Preserved', 'quickwebp' ) : __( 'Replaced', 'quickwebp' ) ); ?></span>
467 + </li>
468 + <li>
469 + <span class="quickwebp-summary-label"><?php esc_html_e( 'Frontend display', 'quickwebp' ); ?></span>
470 + <span class="quickwebp-summary-value quickwebp-summary-display-side"><?php echo esc_html( $display_mode ); ?></span>
471 + </li>
472 + <li>
473 + <span class="quickwebp-summary-label"><?php esc_html_e( 'Bulk optimization', 'quickwebp' ); ?></span>
474 + <span class="quickwebp-summary-value quickwebp-summary-bulk-side"><?php echo esc_html( $save_original_enabled ? __( 'Available', 'quickwebp' ) : __( 'Unavailable', 'quickwebp' ) ); ?></span>
475 + </li>
476 + </ul>
477 + </div>
478 + </section>
178 479
179 - <table class="form-table">
480 + <section class="quickwebp-card">
481 + <div class="quickwebp-card-head">
482 + <h2><?php esc_html_e( 'Quick navigation', 'quickwebp' ); ?></h2>
483 + </div>
484 + <div class="quickwebp-card-body quickwebp-quick-links">
485 + <?php if ( $show_onboarding ) : ?>
486 + <a href="#quickwebp-onboarding"><?php esc_html_e( 'Quick setup assistant', 'quickwebp' ); ?></a>
487 + <?php endif; ?>
488 + <a href="#quickwebp-conversion"><?php esc_html_e( 'Conversion and delivery', 'quickwebp' ); ?></a>
489 + <a href="#quickwebp-resize"><?php esc_html_e( 'Resize', 'quickwebp' ); ?></a>
490 + <a href="#quickwebp-seo"><?php esc_html_e( 'SEO metadata automation', 'quickwebp' ); ?></a>
491 + <a href="#quickwebp-tools"><?php esc_html_e( 'Other tools', 'quickwebp' ); ?></a>
492 + <a href="#quickwebp-migration"><?php esc_html_e( 'Migration notice', 'quickwebp' ); ?></a>
493 + </div>
494 + </section>
180 495
181 - <?php $this->render_component( array(
182 - 'type' => 'toggle',
183 - 'name' => 'quickwebp_settings_paste_image',
184 - 'label' => __( "Enable/disable paste picture directly (beta)", QUICKWEBP_TEXT_DOMAIN ),
185 - 'default' => quickwebp_settings_default('quickwebp_settings_paste_image'),
186 - 'description' => __( "With this feature you can paste directly your picture in WordPress media.", QUICKWEBP_TEXT_DOMAIN ),
187 - )); ?>
496 + <section class="quickwebp-card">
497 + <div class="quickwebp-card-head">
498 + <h2><?php esc_html_e( 'License', 'quickwebp' ); ?></h2>
499 + </div>
500 + <div class="quickwebp-card-body quickwebp-license">
501 + <div class="quickwebp-license__status">
502 + <div class="quickwebp-license__status__text"><?php esc_html_e( 'State', 'quickwebp' ); ?>:</div>
503 + <div class="quickwebp-license__status__icon <?php echo $license_valid ? 'valid' : 'invalid'; ?>"></div>
504 + </div>
188 505
189 - </table>
506 + <div class="quickwebp-license__link">
507 + <a href="<?php echo esc_url( admin_url( 'admin.php?page=quickwebp-manage-license' ) ); ?>" class="<?php echo $license_valid ? 'valid' : 'invalid'; ?>">
508 + <?php if ( $license_valid ) : ?>
509 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/key-disable.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
510 + <?php esc_html_e( 'Deactivate the license', 'quickwebp' ); ?>
511 + <?php else : ?>
512 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/key.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
513 + <?php esc_html_e( 'Activate the license', 'quickwebp' ); ?>
514 + <?php endif; ?>
515 + </a>
516 + </div>
517 + </div>
518 + </section>
519 + </div>
520 + </aside>
521 + </div>
522 + </form>
190 523
191 - <hr>
524 + <?php if ( ! $license_valid ): ?>
525 + <div class="quickwebp__pro-popup">
526 + <div class="quickwebp__pro-popup__overlay"></div>
527 + <div class="quickwebp__pro-popup__content">
528 + <div class="quickwebp__pro-popup__content__header">
529 + <div class="quickwebp__pro-popup__content__header__text">
530 + <div class="quickwebp__pro-popup__content__header__text__subtitle">
531 + <div class="quickwebp__pro-popup__content__header__text__subtitle__tag"><?php esc_html_e( 'Pro', 'quickwebp' ); ?></div>
532 + <div class="quickwebp__pro-popup__content__header__text__subtitle__text"><?php esc_html_e( 'AVIF Format', 'quickwebp' ); ?></div>
533 + </div>
534 + <div class="quickwebp__pro-popup__content__header__text__title">
535 + <?php esc_html_e( 'Go further with', 'quickwebp' ); ?>
536 + <span class="highlight"> AVIF</span>
537 + </div>
538 + <div class="quickwebp__pro-popup__content__header__text__desc">
539 + <?php esc_html_e( 'The next-generation image format, available with', 'quickwebp' ); ?>
540 + <span class="highlight">QuickWebP Pro.</span>
541 + </div>
542 + </div>
192 543
193 - <table class="form-table">
544 + <div class="quickwebp__pro-popup__content__header__close">
545 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/close.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
546 + </div>
547 + </div>
548 + <div class="quickwebp__pro-popup__content__body">
549 + <div class="quickwebp__pro-popup__content__body__top">
550 + <div class="quickwebp__pro-popup__content__body__top__item">
551 + <div class="quickwebp__pro-popup__content__body__top__item__icon">
552 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/gauge.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
553 + </div>
554 + <div class="quickwebp__pro-popup__content__body__top__item__text">
555 + <div class="quickwebp__pro-popup__content__body__top__item__text__title">-50%</div>
556 + <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'Vs jpeg/png on average', 'quickwebp' ); ?></div>
557 + </div>
558 + </div>
194 559
195 - <?php $this->render_component( array(
196 - 'type' => 'select',
197 - 'options' => array(
198 - array(
199 - 'value' => 'gd',
200 - 'label' => 'GD'
201 - ),
202 - array(
203 - 'value' => 'imagick',
204 - 'label' => 'Imagick'
205 - )
206 - ),
207 - 'name' => 'quickwebp_settings_library',
208 - 'label' => __( "Library to use", QUICKWEBP_TEXT_DOMAIN ),
209 - 'default' => quickwebp_settings_default('quickwebp_settings_library'),
210 - 'description' => __( "We use the GD library as the default option. However, if the GD library is not available, we will use Imagick instead.", QUICKWEBP_TEXT_DOMAIN )
211 - )); ?>
560 + <div class="quickwebp__pro-popup__content__body__top__item second">
561 + <div class="quickwebp__pro-popup__content__body__top__item__icon">
562 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/chart-line.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
563 + </div>
564 + <div class="quickwebp__pro-popup__content__body__top__item__text">
565 + <div class="quickwebp__pro-popup__content__body__top__item__text__title">-30%</div>
566 + <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'Vs webp on average', 'quickwebp' ); ?></div>
567 + </div>
568 + </div>
212 569
213 - </table>
570 + <div class="quickwebp__pro-popup__content__body__top__item third">
571 + <div class="quickwebp__pro-popup__content__body__top__item__icon">
572 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/global.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
573 + </div>
574 + <div class="quickwebp__pro-popup__content__body__top__item__text">
575 + <div class="quickwebp__pro-popup__content__body__top__item__text__title">100%</div>
576 + <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'of modern browsers supported', 'quickwebp' ); ?></div>
577 + </div>
578 + </div>
579 + </div>
214 580
215 - <?php submit_button(); ?>
216 -</form>
581 + <div class="quickwebp__pro-popup__content__body__middle">
582 + <div class="quickwebp__pro-popup__content__body__middle__item">
583 + <div class="quickwebp__pro-popup__content__body__middle__item__icon">
584 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/check-mark.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
585 + </div>
586 + <div class="quickwebp__pro-popup__content__body__middle__item__text">
587 + <strong><?php echo wp_kses_post(
588 + // translators: %s is a placeholder for the text "</strong>".
589 + sprintf( __( 'The best compression available %s images typically half the size of your originals.', 'quickwebp' ), '</strong>' )
590 + ); ?>
591 + </div>
592 + </div>
593 +
594 + <div class="quickwebp__pro-popup__content__body__middle__item">
595 + <div class="quickwebp__pro-popup__content__body__middle__item__icon">
596 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/check-mark.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
597 + </div>
598 + <div class="quickwebp__pro-popup__content__body__middle__item__text">
599 + <strong><?php echo wp_kses_post(
600 + // translators: %s is a placeholder for the text "</strong>".
601 + sprintf( __( 'Sharper images at lower weight %s for faster pages and better Core Web Vitals.', 'quickwebp' ), '</strong>' )
602 + ); ?>
603 + </div>
604 + </div>
605 +
606 + <div class="quickwebp__pro-popup__content__body__middle__item">
607 + <div class="quickwebp__pro-popup__content__body__middle__item__icon">
608 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/check-mark.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
609 + </div>
610 + <div class="quickwebp__pro-popup__content__body__middle__item__text">
611 + <strong><?php echo wp_kses_post(
612 + // translators: %s is a placeholder for the text "</strong>".
613 + sprintf( __( 'Automatic fallback %s so older browsers keep receiving a compatible format.', 'quickwebp' ), '</strong>' )
614 + ); ?>
615 + </div>
616 + </div>
617 +
618 + </div>
619 +
620 + <div class="quickwebp__pro-popup__content__body__bottom">
621 + <div class="quickwebp__pro-popup__content__body__bottom__upgrade">
622 + <a href="<?php echo esc_url( quickwebp_get_pro_url( 'settings-upgrade-popup' ) ); ?>" class="quickwebp__pro-popup__content__body__bottom__upgrade__link" target="_blank">
623 + <span class="quickwebp__pro-popup__content__body__bottom__upgrade__link__icon">
624 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/crown.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
625 + </span>
626 + <?php esc_html_e( 'Upgrade to QuickWebP Pro', 'quickwebp' ); ?>
627 + </a>
628 + </div>
629 +
630 + <div class="quickwebp__pro-popup__content__body__bottom__license">
631 + <a href="<?php echo esc_url( admin_url( 'admin.php?page=quickwebp-manage-license' ) ); ?>" class="quickwebp__pro-popup__content__body__bottom__license__link">
632 + <span class="quickwebp__pro-popup__content__body__bottom__license__link__icon">
633 + <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/shield-check.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
634 + </span>
635 + <?php esc_html_e( 'I already have a license', 'quickwebp' ); ?>
636 + </a>
637 + </div>
638 + </div>
639 + </div>
640 + </div>
641 + </div>
642 + <?php endif; ?>
643 +
644 + <script>
645 + document.addEventListener('DOMContentLoaded', function () {
646 + const conversionToggles = document.querySelectorAll('input[type="radio"][name="quickwebp_settings_conversion"]');
647 + const saveOriginalCheckbox = document.querySelector('input[type="checkbox"][name="quickwebp_settings_conversion_save_original[]"]');
648 + const displayModeInputs = document.querySelectorAll('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"]');
649 + const disabledDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="disabled"]');
650 + const pictureDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="picture"]');
651 + const rewriteDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="rewrite"]');
652 + const bulkRow = document.querySelector('.quickwebp-row-bulk-optimization');
653 + const guidanceMessage = document.querySelector('.quickwebp-guidance-message');
654 + const displayWarningRow = document.querySelector('.quickwebp-display-warning-row');
655 + const displayWarningText = document.querySelector('.quickwebp-display-warning');
656 + const onboardingButtons = document.querySelectorAll('.quickwebp-onboarding-apply');
657 + const onboardingFeedback = document.querySelector('.quickwebp-onboarding-feedback');
658 + const seoExampleInput = document.querySelector('.quickwebp-seo-example-input');
659 + const seoPreviewTitle = document.querySelector('.quickwebp-seo-preview-title');
660 + const seoPreviewCaption = document.querySelector('.quickwebp-seo-preview-caption');
661 + const seoPreviewAlt = document.querySelector('.quickwebp-seo-preview-alt');
662 + const seoPreviewDescription = document.querySelector('.quickwebp-seo-preview-description');
663 + const completionToggle = document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion"]');
664 + const completionOptionInputs = document.querySelectorAll('input[type="checkbox"][name="quickwebp_settings_completion_options[]"]');
665 + const cleanupToggle = document.querySelector('input[type="checkbox"][name="quickwebp_settings_cleanup"]');
666 + const cleanupExampleInput = document.querySelector('.quickwebp-cleanup-example-input');
667 + const cleanupPreviewOriginal = document.querySelector('.quickwebp-cleanup-preview-original');
668 + const cleanupPreviewCleaned = document.querySelector('.quickwebp-cleanup-preview-cleaned');
669 +
670 + const displayModeRow = displayModeInputs.length ? displayModeInputs[0].closest('tr') : null;
671 + const disabledDisplayModeLabel = disabledDisplayModeInput ? disabledDisplayModeInput.closest('label') : null;
672 + const conversionCard = document.querySelector('#quickwebp-conversion');
673 +
674 + const summary = {
675 + sideConversion: document.querySelector('.quickwebp-summary-conversion-side'),
676 + sideOriginals: document.querySelector('.quickwebp-summary-originals-side'),
677 + sideDisplay: document.querySelector('.quickwebp-summary-display-side'),
678 + sideBulk: document.querySelector('.quickwebp-summary-bulk-side')
679 + };
680 +
681 + const strings = {
682 + noOriginals: <?php echo wp_json_encode( __( 'Current mode: originals are replaced on upload. Frontend display mode and bulk optimization are hidden because they are designed for preserved originals.', 'quickwebp' ) ); ?>,
683 + withOriginals: <?php echo wp_json_encode( __( 'Current mode: originals are preserved. Choose a frontend display strategy and run bulk optimization for existing media.', 'quickwebp' ) ); ?>,
684 + conversionOff: <?php echo wp_json_encode( __( 'Conversion is disabled. Frontend display mode is forced to Deactivate.', 'quickwebp' ) ); ?>,
685 + warningNoOriginals: <?php echo wp_json_encode( __( 'Display mode is locked to Deactivate because original images are not preserved.', 'quickwebp' ) ); ?>,
686 + warningConversionOff: <?php echo wp_json_encode( __( 'Display mode is locked to Deactivate because image conversion is disabled.', 'quickwebp' ) ); ?>,
687 + appliedNewSite: <?php echo wp_json_encode( __( 'Preset applied: New site profile. Originals are replaced and display mode is set to Deactivate.', 'quickwebp' ) ); ?>,
688 + appliedExistingSite: <?php echo wp_json_encode( __( 'Preset applied: Existing site profile. Originals are preserved and rewrite mode is selected.', 'quickwebp' ) ); ?>,
689 + profileNew: <?php echo wp_json_encode( __( 'New site profile', 'quickwebp' ) ); ?>,
690 + profileExisting: <?php echo wp_json_encode( __( 'Existing site profile', 'quickwebp' ) ); ?>,
691 + profileCustom: <?php echo wp_json_encode( __( 'Custom profile', 'quickwebp' ) ); ?>,
692 + enabled: <?php echo wp_json_encode( __( 'Enabled', 'quickwebp' ) ); ?>,
693 + disabled: <?php echo wp_json_encode( __( 'Disabled', 'quickwebp' ) ); ?>,
694 + preserved: <?php echo wp_json_encode( __( 'Preserved', 'quickwebp' ) ); ?>,
695 + replaced: <?php echo wp_json_encode( __( 'Replaced', 'quickwebp' ) ); ?>,
696 + available: <?php echo wp_json_encode( __( 'Available', 'quickwebp' ) ); ?>,
697 + unavailable: <?php echo wp_json_encode( __( 'Unavailable', 'quickwebp' ) ); ?>,
698 + disabledPreview: <?php echo wp_json_encode( __( 'Disabled in current settings', 'quickwebp' ) ); ?>,
699 + cleanupDisabledPreview: <?php echo wp_json_encode( __( 'Cleanup disabled in current settings', 'quickwebp' ) ); ?>,
700 + };
701 +
702 + function setDisplayMode(value) {
703 + displayModeInputs.forEach((input) => {
704 + input.checked = input.value === value;
705 + });
706 + }
707 +
708 + function getSelectedDisplayMode() {
709 + const selected = Array.from(displayModeInputs).find((input) => input.checked);
710 + return selected ? selected.value : 'disabled';
711 + }
712 +
713 + function isSaveOriginalEnabled() {
714 + return !!saveOriginalCheckbox && saveOriginalCheckbox.checked;
715 + }
716 +
717 + function isConversionEnabled() {
718 + let conversionToggle = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion"]:checked');
719 +
720 + return !!conversionToggle && conversionToggle.value !== '0';
721 + }
722 +
723 + function getProfile(hasOriginals, conversionEnabled) {
724 + if (!conversionEnabled) {
725 + return strings.profileCustom;
726 + }
727 +
728 + return hasOriginals ? strings.profileExisting : strings.profileNew;
729 + }
730 +
731 + function updateSummary() {
732 + const hasOriginals = isSaveOriginalEnabled();
733 + const conversionEnabled = isConversionEnabled();
734 + const displayMode = getSelectedDisplayMode();
735 + const profile = getProfile(hasOriginals, conversionEnabled);
736 +
737 + if (summary.sideConversion) {
738 + summary.sideConversion.textContent = conversionEnabled ? strings.enabled : strings.disabled;
739 + }
740 +
741 + if (summary.sideOriginals) {
742 + summary.sideOriginals.textContent = hasOriginals ? strings.preserved : strings.replaced;
743 + }
744 +
745 + if (summary.sideDisplay) {
746 + summary.sideDisplay.textContent = displayMode;
747 + }
748 +
749 + if (summary.sideBulk) {
750 + summary.sideBulk.textContent = hasOriginals && conversionEnabled ? strings.available : strings.unavailable;
751 + }
752 + }
753 +
754 + function updateUiConsistency() {
755 + const hasOriginals = isSaveOriginalEnabled();
756 + const conversionEnabled = isConversionEnabled();
757 + const forceDisabled = !hasOriginals || !conversionEnabled;
758 +
759 + if (displayModeRow) {
760 + displayModeRow.style.display = hasOriginals && conversionEnabled ? '' : 'none';
761 + }
762 +
763 + if (bulkRow) {
764 + bulkRow.style.display = hasOriginals && conversionEnabled ? '' : 'none';
765 + }
766 +
767 + if (guidanceMessage) {
768 + if (!conversionEnabled) {
769 + guidanceMessage.textContent = strings.conversionOff;
770 + } else {
771 + guidanceMessage.textContent = hasOriginals ? strings.withOriginals : strings.noOriginals;
772 + }
773 + }
774 +
775 + if (displayWarningRow && displayWarningText) {
776 + displayWarningRow.style.display = forceDisabled ? '' : 'none';
777 +
778 + if (!conversionEnabled) {
779 + displayWarningText.textContent = strings.warningConversionOff;
780 + } else {
781 + displayWarningText.textContent = strings.warningNoOriginals;
782 + }
783 + }
784 +
785 + if (disabledDisplayModeLabel) {
786 + disabledDisplayModeLabel.style.display = hasOriginals && conversionEnabled ? 'none' : '';
787 + }
788 +
789 + if (disabledDisplayModeInput) {
790 + disabledDisplayModeInput.disabled = hasOriginals && conversionEnabled;
791 + }
792 +
793 + if (forceDisabled) {
794 + setDisplayMode('disabled');
795 + updateSummary();
796 + return;
797 + }
798 +
799 + if (disabledDisplayModeInput && disabledDisplayModeInput.checked) {
800 + if (pictureDisplayModeInput) {
801 + pictureDisplayModeInput.checked = true;
802 + } else if (rewriteDisplayModeInput) {
803 + rewriteDisplayModeInput.checked = true;
804 + }
805 + }
806 +
807 + updateSummary();
808 + }
809 +
810 + function extractBaseFilename(value) {
811 + if (!value) {
812 + return 'example image';
813 + }
814 +
815 + const base = value.replace(/\.[^/.]+$/, '');
816 + const normalized = base
817 + .replace(/\s+/g, ' ')
818 + .trim();
819 +
820 + return normalized || 'example image';
821 + }
822 +
823 + function updateSeoLiveExample() {
824 + if (!seoExampleInput || !seoPreviewTitle || !seoPreviewCaption || !seoPreviewAlt || !seoPreviewDescription) {
825 + return;
826 + }
827 +
828 + const optionsMap = {
829 + title: {
830 + checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="title"]:checked'),
831 + preview: seoPreviewTitle
832 + },
833 + caption: {
834 + checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="caption"]:checked'),
835 + preview: seoPreviewCaption
836 + },
837 + alt: {
838 + checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="alt"]:checked'),
839 + preview: seoPreviewAlt
840 + },
841 + description: {
842 + checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="description"]:checked'),
843 + preview: seoPreviewDescription
844 + }
845 + };
846 +
847 + const completionEnabled = !!completionToggle && completionToggle.checked;
848 + const baseFilename = extractBaseFilename(seoExampleInput.value);
849 +
850 + optionsMap.title.preview.textContent = baseFilename;
851 + optionsMap.caption.preview.textContent = baseFilename;
852 + optionsMap.alt.preview.textContent = baseFilename;
853 + optionsMap.description.preview.textContent = baseFilename;
854 +
855 + Object.keys(optionsMap).forEach((key) => {
856 + const item = optionsMap[key];
857 + const container = item.preview.closest('.quickwebp-seo-example-item');
858 + const isEnabled = completionEnabled && item.checked;
859 +
860 + if (!isEnabled) {
861 + item.preview.textContent = strings.disabledPreview;
862 + }
863 +
864 + if (container) {
865 + container.classList.toggle('is-disabled', !isEnabled);
866 + }
867 + });
868 + }
869 +
870 + function sanitizeFilenamePreview(value) {
871 + const inputValue = (value || '').trim();
872 + if (!inputValue) {
873 + return 'example-image.jpg';
874 + }
875 +
876 + const lastDot = inputValue.lastIndexOf('.');
877 + const hasExtension = lastDot > 0 && lastDot < inputValue.length - 1;
878 + const extension = hasExtension ? inputValue.slice(lastDot + 1).toLowerCase() : '';
879 + const basename = hasExtension ? inputValue.slice(0, lastDot) : inputValue;
880 +
881 + let normalized = basename;
882 + if (normalized.normalize) {
883 + normalized = normalized.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
884 + }
885 +
886 + normalized = normalized
887 + .replace(/[’']/g, '-')
888 + .replace(/[^A-Za-z0-9\s-]/g, '')
889 + .toLowerCase()
890 + .trim()
891 + .replace(/\s+/g, '-')
892 + .replace(/-+/g, '-')
893 + .replace(/^-+|-+$/g, '');
894 +
895 + if (!normalized) {
896 + normalized = 'image';
897 + }
898 +
899 + return extension ? normalized + '.' + extension : normalized;
900 + }
901 +
902 + function updateCleanupLiveExample() {
903 + if (!cleanupExampleInput || !cleanupPreviewOriginal || !cleanupPreviewCleaned) {
904 + return;
905 + }
906 +
907 + const original = cleanupExampleInput.value || '';
908 + const cleaned = sanitizeFilenamePreview(original);
909 + const isCleanupEnabled = !!cleanupToggle && cleanupToggle.checked;
910 +
911 + cleanupPreviewOriginal.textContent = original || 'example image.jpg';
912 +
913 + const cleanedContainer = cleanupPreviewCleaned.closest('.quickwebp-cleanup-example-item');
914 + if (!isCleanupEnabled) {
915 + cleanupPreviewCleaned.textContent = strings.cleanupDisabledPreview;
916 + if (cleanedContainer) {
917 + cleanedContainer.classList.add('is-disabled');
918 + }
919 + return;
920 + }
921 +
922 + cleanupPreviewCleaned.textContent = cleaned;
923 + if (cleanedContainer) {
924 + cleanedContainer.classList.remove('is-disabled');
925 + }
926 + }
927 +
928 + onboardingButtons.forEach((button) => {
929 + button.addEventListener('click', function () {
930 + const profile = this.getAttribute('data-profile');
931 +
932 + let conversionToggle = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion"][value="1"]');
933 + if (conversionToggle) {
934 + conversionToggle.checked = true;
935 + conversionToggle.dispatchEvent(new Event('change', { bubbles: true }));
936 + }
937 +
938 + if (!saveOriginalCheckbox) {
939 + return;
940 + }
941 +
942 + if (profile === 'new-site') {
943 + saveOriginalCheckbox.checked = false;
944 + setDisplayMode('disabled');
945 +
946 + if (onboardingFeedback) {
947 + onboardingFeedback.textContent = strings.appliedNewSite;
948 + }
949 + }
950 +
951 + if (profile === 'existing-site') {
952 + saveOriginalCheckbox.checked = true;
953 + if (rewriteDisplayModeInput) {
954 + rewriteDisplayModeInput.checked = true;
955 + } else {
956 + setDisplayMode('picture');
957 + }
958 +
959 + if (onboardingFeedback) {
960 + onboardingFeedback.textContent = strings.appliedExistingSite;
961 + }
962 + }
963 +
964 + updateUiConsistency();
965 +
966 + if (conversionCard) {
967 + conversionCard.scrollIntoView({ behavior: 'smooth', block: 'start' });
968 + }
969 + });
970 + });
971 +
972 + if (saveOriginalCheckbox) {
973 + saveOriginalCheckbox.addEventListener('change', updateUiConsistency);
974 + }
975 +
976 + conversionToggles.forEach((toggle) => {
977 + toggle.addEventListener('change', updateUiConsistency);
978 + });
979 +
980 + displayModeInputs.forEach((input) => {
981 + input.addEventListener('change', updateSummary);
982 + });
983 +
984 + if (seoExampleInput) {
985 + seoExampleInput.addEventListener('input', updateSeoLiveExample);
986 + updateSeoLiveExample();
987 + }
988 +
989 + if (cleanupExampleInput) {
990 + cleanupExampleInput.addEventListener('input', updateCleanupLiveExample);
991 + updateCleanupLiveExample();
992 + }
993 +
994 + if (completionToggle) {
995 + completionToggle.addEventListener('change', updateSeoLiveExample);
996 + }
997 +
998 + if (cleanupToggle) {
999 + cleanupToggle.addEventListener('change', updateCleanupLiveExample);
1000 + }
1001 +
1002 + completionOptionInputs.forEach((input) => {
1003 + input.addEventListener('change', updateSeoLiveExample);
1004 + });
1005 +
1006 + document.querySelectorAll('.quickwebp-quick-links a[href^="#"]').forEach((anchor) => {
1007 + anchor.addEventListener('click', function (event) {
1008 + const target = document.querySelector(this.getAttribute('href'));
1009 + if (!target) {
1010 + return;
1011 + }
1012 +
1013 + event.preventDefault();
1014 + target.scrollIntoView({ behavior: 'smooth', block: 'start' });
1015 + });
1016 + });
1017 +
1018 + updateUiConsistency();
1019 + });
1020 + </script>
1021 +</div>