PluginProbe
Autoptimize / 3.1.7
Autoptimize v3.1.7
2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 All 107 releases
autoptimize / classes / critcss-inc / admin_settings_rules.js.php

admin_settings_rules.js.php in Autoptimize 3.1.7, at classes/critcss-inc/admin_settings_rules.js.php

452 lines 18.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Outputs JS code for the rules panel.
4 */
5
6 if ( $ao_ccss_debug ) {
7 echo "console.log('[WARN] Autoptimize CriticalCSS is in debug mode!');\n";
8 echo "console.log('[WARN] Avoid using debug mode on production/live environments unless for ad-hoc troubleshooting purposes and make sure to disable it after!');\n";
9 }
10 ?>
11
12 var rulesOriginEl = document.getElementById("critCssOrigin");
13 var deferInlineEl = document.getElementById("autoptimize_css_defer_inline");
14 var additionalEl = document.getElementById("autoptimize_ccss_additional");
15 if (rulesOriginEl)
16 rulesOriginEl.style.display = 'none';
17 if (deferInlineEl)
18 deferInlineEl.style.display = 'none';
19 if (additionalEl)
20 additionalEl.style.display = 'none';
21
22 if (rulesOriginEl) {
23 jQuery(document).ready(function() {
24 critCssArray=JSON.parse(document.getElementById("critCssOrigin").value);
25 <?php
26 if ( $ao_ccss_debug ) {
27 echo "console.log('Rules Object:', critCssArray);\n";
28 }
29 ?>
30 drawTable(critCssArray);
31 jQuery("#addCritCssButton").click(function(){addEditRow();});
32 jQuery("#editDefaultButton").click(function(){editDefaultCritCss();});
33 jQuery("#editAdditionalButton").click(function(){editAdditionalCritCss();});
34 jQuery("#removeAllRules").click(function(){removeAllRules();});
35 });
36 }
37
38 function drawTable(critCssArray) {
39 jQuery("#rules-list").empty();
40 rnotice = 0;
41 jQuery.each(critCssArray,function(k,v) {
42 if (k=="paths") {
43 kstring="<?php _e( 'Path Based Rules', 'autoptimize' ); ?>";
44 } else {
45 kstring="<?php _e( 'Conditional Tags, Custom Post Types and Page Templates Rules', 'autoptimize' ); ?>";
46 }
47 if (!(jQuery.isEmptyObject(v))) {
48 jQuery("#rules-list").append("<tr><td colspan='5'><h4>" + kstring + "</h4></td></tr>");
49 jQuery("#rules-list").append("<tr class='header "+k+"Rule'><th><?php _e( 'Type', 'autoptimize' ); ?></th><th><?php _e( 'Target', 'autoptimize' ); ?></th><th><?php _e( 'Critical CSS File', 'autoptimize' ); ?></th><th colspan='2'><?php _e( 'Actions', 'autoptimize' ); ?></th></tr>");
50 }
51 nodeNumber=0;
52 jQuery.each(v,function(i,nv){
53 nodeNumber++;
54 nodeId=k + "_" + nodeNumber;
55 hash=nv.hash;
56 file=nv.file;
57 filest=nv.file;
58 auto_style = '';
59 <?php
60 $criticalcss = new autoptimizeCriticalCSSBase();
61 if ( $criticalcss->is_api_active() ) {
62 echo 'api_active = 1;' . "\n";
63 } else {
64 echo 'api_active = 0;' . "\n";
65 }
66 ?>
67 if (file == 0) {
68 file='<?php _e( 'To be fetched from criticalcss.com in the next queue run...', 'autoptimize' ); ?>';
69 }
70 if (nv.hash === 0 && filest != 0) {
71 type='<?php _e( 'MANUAL', 'autoptimize' ); ?>';
72 typeClass = 'manual';
73 } else {
74 type='<?php _e( 'AUTO', 'autoptimize' ); ?>';
75 typeClass = 'auto';
76 if ( api_active != 1 ) {
77 auto_style = ' style="opacity:.5;" '
78 }
79 }
80 if (file && typeof file == 'string') {
81 rmark_find=file.split('_');
82 if (rmark_find[2] || rmark_find[2] == 'R.css') {
83 rnotice = rnotice + 1;
84 }
85 }
86 if ( k == "paths" ) {
87 <?php
88 if ( apply_filters( 'autoptimize_filter_ccss_paths_clickable', true ) ) {
89 ?>
90 target = '<a href="<?php echo AUTOPTIMIZE_WP_SITE_URL; ?>' + i + '" target="_blank">' + i + '</a>';
91 <?php
92 } else {
93 ?>
94 target = i;
95 <?php
96 }
97 ?>
98 } else {
99 target = i.replace(/(woo_|template_|custom_post_|edd_|bp_|bbp_)/,'');
100 }
101
102 jQuery("#rules-list").append("<tr " + auto_style + "class='rule "+k+"Rule'><td class='type'><span class='badge " + typeClass + "'>" + type + "</span></td><td class='target'>" + target + "</td><td class='file'>" + file + "</td><td class='btn edit'><span class=\"button-secondary\" id=\"" + nodeId + "_edit\"><?php _e( 'Edit', 'autoptimize' ); ?></span></td><td class='btn delete'><span class=\"button-secondary\" id=\"" + nodeId + "_remove\"><?php _e( 'Remove', 'autoptimize' ); ?></span></td></tr>");
103 if ( typeClass == 'manual' || api_active == 1 ) {
104 jQuery("#" + nodeId + "_edit").click(function(){addEditRow(this.id);});
105 }
106 jQuery("#" + nodeId + "_remove").click(function(){confirmRemove(this.id);});
107 })
108 });
109 if ( rnotice && rnotice != 0 ) {
110 // R rules were found, show a notice!
111 // and add some JS magic to ensure the notice works as a notice, but is shown inline
112 // in the rules panel instead of in the notice area where it would be too prominent.
113 <?php
114 $_ao_ccss_review_notice_id = 'autoptimize-ccss-review-rules-notice-30';
115 // Translators: before the 1st word a number + a space will be displayed, as in e.g. "2 of above rules".
116 $_ao_ccss_review_notice_copy = __( 'of the above rules got flagged by criticalcss.com as possibly needing review. This is often due to font-related issues which can be safely ignored, but in case of doubt do a visual test or check for Cumulative Layout Shift issues in e.g. Pagespeed Insights.', 'autoptimize' );
117 if ( PAnD::is_admin_notice_active( $_ao_ccss_review_notice_id ) ) {
118 ?>
119 jQuery("#rules-notices").append( "&nbsp;<div class='rnotice notice notice-info is-dismissible hidden' data-dismissible='<?php echo $_ao_ccss_review_notice_id; ?>'><p>" + rnotice + " <?php echo $_ao_ccss_review_notice_copy; ?>" + "</p></div>");
120 jQuery( document ).ready(function() {
121 jQuery("div.rnotice").detach().appendTo('#rules-notices');
122 jQuery("div.rnotice").show();
123 });
124 <?php
125 } else if ( $ao_ccss_debug ) {
126 ?>
127 console.log( "Autoptimize: " + rnotice + " <?php echo $_ao_ccss_review_notice_copy; ?>" );
128 <?php
129 }
130 ?>
131 }
132 }
133
134 function confirmRemove(idToRemove) {
135 jQuery( "#confirm-rm" ).dialog({
136 resizable: false,
137 height:235,
138 modal: true,
139 buttons: {
140 "<?php _e( 'Delete', 'autoptimize' ); ?>": function() {
141 removeRow(idToRemove);
142 updateAfterChange();
143 jQuery( this ).dialog( "close" );
144 },
145 "<?php _e( 'Cancel', 'autoptimize' ); ?>": function() {
146 jQuery( this ).dialog( "close" );
147 }
148 }
149 });
150 }
151
152 function removeAllRules() {
153 jQuery( "#confirm-rm-all" ).dialog({
154 resizable: false,
155 height:235,
156 modal: true,
157 buttons: {
158 "<?php _e( 'Delete All', 'autoptimize' ); ?>": function() {
159 critCssArray={'paths':[],'types':[]};
160 drawTable(critCssArray);
161 updateAfterChange();
162 removeAllCcssFilesOnServer();
163 jQuery( this ).dialog( "close" );
164 },
165 "<?php _e( 'Cancel', 'autoptimize' ); ?>": function() {
166 jQuery( this ).dialog( "close" );
167 }
168 }
169 });
170 }
171
172 function removeRow(idToRemove) {
173 splits=idToRemove.split(/_/);
174 crit_type=splits[0];
175 crit_item=splits[1];
176 crit_key=Object.keys(critCssArray[crit_type])[crit_item-1];
177 crit_file=critCssArray[crit_type][crit_key].file;
178 delete critCssArray[crit_type][crit_key];
179
180 var data = {
181 'action': 'rm_critcss',
182 'critcss_rm_nonce': '<?php echo wp_create_nonce( 'rm_critcss_nonce' ); ?>',
183 'cachebustingtimestamp': new Date().getTime(),
184 'critcssfile': crit_file
185 };
186
187 jQuery.ajaxSetup({
188 async: false
189 });
190
191 jQuery.post(ajaxurl, data, function(response) {
192 response_array=JSON.parse(response);
193 if (response_array["code"]!=200) {
194 // not displaying notice, as the end result is OK; the file isn't there
195 // displayNotice(response_array["string"]);
196 }
197 });
198 }
199
200 function removeAllCcssFilesOnServer() {
201 var data = {
202 'action': 'rm_critcss_all',
203 'critcss_rm_all_nonce': '<?php echo wp_create_nonce( 'rm_critcss_all_nonce' ); ?>',
204 'cachebustingtimestamp': new Date().getTime()
205 };
206
207 jQuery.ajaxSetup({
208 async: false
209 });
210
211 jQuery.post(ajaxurl, data, function(response) {
212 response_array=JSON.parse(response);
213 if (response_array["code"]!=200) {
214 // not displaying notice, as the end result is OK; the file isn't there
215 // displayNotice(response_array["string"]);
216 }
217 });
218 }
219
220 function addEditRow(idToEdit) {
221 resetForm();
222 if (idToEdit) {
223 dialogTitle="<?php _e( 'Edit Critical CSS Rule', 'autoptimize' ); ?>";
224
225 splits=idToEdit.split(/_/);
226 crit_type=splits[0];
227 crit_item=splits[1];
228 crit_key=Object.keys(critCssArray[crit_type])[crit_item-1];
229 crit_file=critCssArray[crit_type][crit_key].file;
230
231 jQuery("#critcss_addedit_id").val(idToEdit);
232 jQuery("#critcss_addedit_type").val(crit_type);
233 jQuery("#critcss_addedit_file").val(crit_file);
234 jQuery("#critcss_addedit_css").attr("placeholder", "<?php _e( 'Loading critical CSS...', 'autoptimize' ); ?>");
235 jQuery("#critcss_addedit_type").attr("disabled",true);
236
237 if (crit_type==="paths") {
238 jQuery("#critcss_addedit_path").val(crit_key);
239 jQuery("#critcss_addedit_path_wrapper").show();
240 jQuery("#critcss_addedit_pagetype_wrapper").hide();
241 } else {
242 jQuery("#critcss_addedit_pagetype").val(crit_key);
243 jQuery("#critcss_addedit_pagetype_wrapper").show();
244 jQuery("#critcss_addedit_path_wrapper").hide();
245 }
246
247 var data = {
248 'action': 'fetch_critcss',
249 'critcss_fetch_nonce': '<?php echo wp_create_nonce( 'fetch_critcss_nonce' ); ?>',
250 'cachebustingtimestamp': new Date().getTime(),
251 'critcssfile': crit_file
252 };
253
254 jQuery.post(ajaxurl, data, function(response) {
255 response_array=JSON.parse(response);
256 if (response_array["code"]==200) {
257 jQuery("#critcss_addedit_css").val(response_array["string"]);
258 } else {
259 jQuery("#critcss_addedit_css").attr("placeholder", "").focus();
260 }
261 });
262 } else {
263 dialogTitle="<?php _e( 'Add Critical CSS Rule', 'autotimize' ); ?>";
264
265 // default: paths, hide content type field
266 jQuery("#critcss_addedit_type").val("paths");
267 jQuery("#critcss_addedit_pagetype_wrapper").hide();
268
269 // event handler on type to switch display
270 jQuery("#critcss_addedit_type").on('change', function (e) {
271 if(this.value==="types") {
272 jQuery("#critcss_addedit_pagetype_wrapper").show();
273 jQuery("#critcss_addedit_path_wrapper").hide();
274 jQuery("#critcss_addedit_css").attr("placeholder", "<?php _e( 'For type based rules, paste your specific and minified critical CSS here and hit submit to save. If you want to create a rule to exclude from critical CSS injection, enter \"none\".', 'autoptimize' ); ?>");
275 } else {
276 jQuery("#critcss_addedit_path_wrapper").show();
277 jQuery("#critcss_addedit_pagetype_wrapper").hide();
278 jQuery("#critcss_addedit_css").attr("placeholder", "<?php _e( 'For path based rules, paste your specific and minified critical CSS here or leave this empty to fetch it from criticalcss.com and hit submit to save. If you want to create a rule to exclude from critical CSS injection, enter \"none\"', 'autoptimize' ); ?>");
279 }
280 });
281 }
282
283 jQuery("#addEditCritCss").dialog({
284 autoOpen: true,
285 height: 500,
286 width: 700,
287 title: dialogTitle,
288 modal: true,
289 buttons: {
290 "<?php _e( 'Submit', 'autoptimize' ); ?>": function() {
291 rpath = jQuery("#critcss_addedit_path").val();
292 rtype = jQuery("#critcss_addedit_pagetype option:selected").val();
293 rccss = jQuery("#critcss_addedit_css").val();
294 <?php if ( $ao_ccss_debug ) { ?>
295 console.log('rpath: ' + rpath, 'rtype: ' + rtype, 'rccss: ' + rccss);
296 <?php } ?>
297 if (rpath === '' && rtype === '') {
298 alert('<?php _e( "Rule validation error:\\n\\nBased on your rule type, you should set a path or conditional tag.", 'autoptimize' ); ?>');
299 } else if (rtype !== '' && rccss == '') {
300 alert('<?php _e( "Rule validation error:\\n\\nType based rules requires a minified critical CSS.", 'autoptimize' ); ?>');
301 } else if (rpath !== rpath.replace(/("|\'|<|>|\[|\]|{|}|\|)/,'')) {
302 alert('<?php _e( "Path validation error:\\n\\nThe path contains characters that are not permitted, remove or encode the unsafe characters.", 'autoptimize' ); ?>');
303 } else {
304 saveEditCritCss();
305 jQuery(this).dialog('close');
306 }
307 },
308 "<?php _e( 'Cancel', 'autoptimize' ); ?>": function() {
309 resetForm();
310 jQuery(this).dialog("close");
311 }
312 }
313 });
314 }
315
316 function editDefaultCritCss(){
317 document.getElementById("dummyDefault").value=document.getElementById("autoptimize_css_defer_inline").value;
318 jQuery("#default_critcss_wrapper").dialog({
319 autoOpen: true,
320 height: 505,
321 width: 700,
322 title: "<?php _e( 'Default Critical CSS', 'autoptimize' ); ?>",
323 modal: true,
324 buttons: {
325 "<?php _e( 'Submit', 'autoptimize' ); ?>": function() {
326 document.getElementById("autoptimize_css_defer_inline").value=document.getElementById("dummyDefault").value;
327 jQuery("#unSavedWarning").show();
328 jQuery("#default_critcss_wrapper").dialog( "close" );
329 },
330 "<?php _e( 'Cancel', 'autoptimize' ); ?>": function() {
331 jQuery("#default_critcss_wrapper").dialog( "close" );
332 }
333 }
334 });
335 }
336
337 function editAdditionalCritCss(){
338 document.getElementById("dummyAdditional").value=document.getElementById("autoptimize_ccss_additional").value;
339 jQuery("#additional_critcss_wrapper").dialog({
340 autoOpen: true,
341 height: 505,
342 width: 700,
343 title: "<?php _e( 'Additional Critical CSS', 'autoptimize' ); ?>",
344 modal: true,
345 buttons: {
346 "<?php _e( 'Submit', 'autoptimize' ); ?>": function() {
347 document.getElementById("autoptimize_ccss_additional").value=document.getElementById("dummyAdditional").value;
348 jQuery("#unSavedWarning").show();
349 jQuery("#additional_critcss_wrapper").dialog( "close" );
350 },
351 "<?php _e( 'Cancel', 'autoptimize' ); ?>": function() {
352 jQuery("#additional_critcss_wrapper").dialog( "close" );
353 }
354 }
355 });
356 }
357
358 function saveEditCritCss(){
359 critcssfile=jQuery("#critcss_addedit_file").val();
360 critcsscontents=jQuery("#critcss_addedit_css").val();
361 critcsstype=jQuery("#critcss_addedit_type").val();
362 critcssid=jQuery("#critcss_addedit_id").val();
363
364 if (critcssid) {
365 // this was an "edit" action, so remove original
366 // will also remove the file, but that will get rewritten anyway
367 removeRow(critcssid);
368 }
369 if (critcsstype==="types") {
370 critcsstarget=jQuery("#critcss_addedit_pagetype").val();
371 } else {
372 critcsstarget=jQuery("#critcss_addedit_path").val();
373 }
374
375 if (!critcssfile && !critcsscontents) {
376 critcssfile=0;
377 } else if (!critcssfile && critcsscontents) {
378 critcssfile="ccss_" + md5(critcsscontents+critcsstarget) + ".css";
379 }
380
381 // Compose the rule object
382 critCssArray[critcsstype][critcsstarget]={};
383 critCssArray[critcsstype][critcsstarget].hash=0;
384 critCssArray[critcsstype][critcsstarget].file=critcssfile;
385
386 <?php
387 if ( $ao_ccss_debug ) {
388 echo "console.log('[RULE PROPERTIES] Type:', critcsstype, ', Target:', critcsstarget, ', Hash:', 0, ', File:', critcssfile);";
389 }
390 ?>
391
392 updateAfterChange();
393
394 var data = {
395 'action': 'save_critcss',
396 'critcss_save_nonce': '<?php echo wp_create_nonce( 'save_critcss_nonce' ); ?>',
397 'critcssfile': critcssfile,
398 'critcsscontents': critcsscontents
399 };
400
401 jQuery.post(ajaxurl, data, function(response) {
402 response_array=JSON.parse(response);
403 if (response_array["code"]!=200) {
404 displayNotice(response_array["string"]);
405 }
406 });
407 }
408
409 function updateAfterChange() {
410 document.getElementById("critCssOrigin").value=JSON.stringify(critCssArray);
411 drawTable(critCssArray);
412
413 <?php
414 // autosave rules is on by default, but can be disabled with a filter.
415 if ( apply_filters( 'autoptimize_filter_ccss_settings_rules_autosave', true ) ) {
416 ?>
417 var data = {
418 'action': 'ao_ccss_saverules',
419 'ao_ccss_saverules_nonce': '<?php echo wp_create_nonce( 'ao_ccss_saverules_nonce' ); ?>',
420 'critcssrules': document.getElementById("critCssOrigin").value
421 };
422
423 jQuery.post(ajaxurl, data, function(response) {
424 response_array=JSON.parse(response);
425 if (response_array["code"]!=200) {
426 displayNotice(response_array["msg"]);
427 jQuery("#unSavedWarning").show();
428 }
429 });
430 <?php } else { ?>
431 jQuery("#unSavedWarning").show();
432 <?php } ?>
433
434 document.getElementById('ao_title_and_button').scrollIntoView();
435 }
436
437 function displayNotice(textIn, level = 'error') {
438 jQuery('<div class="notice notice-' + level + ' notice is-dismissible"><p>'+textIn+'</p></div>').insertBefore("#unSavedWarning");
439 document.getElementById('ao_title_and_button').scrollIntoView();
440 }
441
442 function resetForm() {
443 jQuery("#critcss_addedit_css").attr("placeholder", "<?php _e( 'For path based rules, paste your specific and minified critical CSS. If you want to create a rule to exclude from critical CSS injection, enter \"none\"', 'autoptimize' ); ?>");
444 jQuery("#critcss_addedit_type").attr("disabled",false);
445 jQuery("#critcss_addedit_path_wrapper").show();
446 jQuery("#critcss_addedit_id").val("");
447 jQuery("#critcss_addedit_path").val("");
448 jQuery("#critcss_addedit_file").val("");
449 jQuery("#critcss_addedit_pagetype").val("");
450 jQuery("#critcss_addedit_css").val("");
451 }
452