PluginProbe
Autoptimize / trunk
Autoptimize vtrunk
3.1.16 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 All 108 releases
autoptimize / classes / critcss-inc / admin_settings_rules.js.php

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

456 lines 19.0 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 esc_html_e( 'Path Based Rules', 'autoptimize' ); ?>";
44 } else {
45 kstring="<?php esc_html_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 esc_html_e( 'Type', 'autoptimize' ); ?></th><th><?php esc_html_e( 'Target', 'autoptimize' ); ?></th><th><?php esc_html_e( 'Critical CSS File', 'autoptimize' ); ?></th><th colspan='2'><?php esc_html_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 esc_html_e( 'To be fetched from criticalcss.com in the next queue run...', 'autoptimize' ); ?>';
69 }
70 if (nv.hash === 0 && filest != 0) {
71 type='<?php esc_html_e( 'MANUAL', 'autoptimize' ); ?>';
72 typeClass = 'manual';
73 } else {
74 type='<?php esc_html_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 esc_html_e( 'Edit', 'autoptimize' ); ?></span></td><td class='btn delete'><span class=\"button-secondary\" id=\"" + nodeId + "_remove\"><?php esc_html_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 = esc_html__( '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 esc_html_e( 'Delete', 'autoptimize' ); ?>": function() {
141 removeRow(idToRemove);
142 updateAfterChange();
143 jQuery( this ).dialog( "close" );
144 },
145 "<?php esc_html_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 esc_html_e( 'Delete All', 'autoptimize' ); ?>": function() {
159 critCssArray={'paths':[],'types':[]};
160 drawTable(critCssArray);
161 updateAfterChange();
162 removeAllCcssFilesOnServer();
163 jQuery( this ).dialog( "close" );
164 },
165 "<?php esc_html_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 esc_html_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 esc_html_e( 'Loading critical CSS...', 'autoptimize' ); ?>");
235 jQuery("#critcss_addedit_css").attr("spellcheck",false);
236 jQuery("#critcss_addedit_type").attr("disabled",true);
237
238 if (crit_type==="paths") {
239 jQuery("#critcss_addedit_path").val(crit_key);
240 jQuery("#critcss_addedit_path_wrapper").show();
241 jQuery("#critcss_addedit_pagetype_wrapper").hide();
242 } else {
243 jQuery("#critcss_addedit_pagetype").val(crit_key);
244 jQuery("#critcss_addedit_pagetype_wrapper").show();
245 jQuery("#critcss_addedit_path_wrapper").hide();
246 }
247
248 var data = {
249 'action': 'fetch_critcss',
250 'critcss_fetch_nonce': '<?php echo wp_create_nonce( 'fetch_critcss_nonce' ); ?>',
251 'cachebustingtimestamp': new Date().getTime(),
252 'critcssfile': crit_file
253 };
254
255 jQuery.post(ajaxurl, data, function(response) {
256 response_array=JSON.parse(response);
257 if (response_array["code"]==200) {
258 jQuery("#critcss_addedit_css").val(response_array["string"]);
259 } else {
260 jQuery("#critcss_addedit_css").attr("placeholder", "").focus();
261 }
262 });
263 } else {
264 dialogTitle="<?php esc_html_e( 'Add Critical CSS Rule', 'autoptimize' ); ?>";
265
266 // default: paths, hide content type field
267 jQuery("#critcss_addedit_type").val("paths");
268 jQuery("#critcss_addedit_css").attr("spellcheck",false);
269 jQuery("#critcss_addedit_pagetype_wrapper").hide();
270
271 // event handler on type to switch display
272 jQuery("#critcss_addedit_type").on('change', function (e) {
273 if(this.value==="types") {
274 jQuery("#critcss_addedit_pagetype_wrapper").show();
275 jQuery("#critcss_addedit_path_wrapper").hide();
276 jQuery("#critcss_addedit_css").attr("placeholder", "<?php esc_html_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' ); ?>");
277 } else {
278 jQuery("#critcss_addedit_path_wrapper").show();
279 jQuery("#critcss_addedit_pagetype_wrapper").hide();
280 jQuery("#critcss_addedit_css").attr("placeholder", "<?php esc_html_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' ); ?>");
281 }
282 });
283 }
284
285 jQuery("#addEditCritCss").dialog({
286 autoOpen: true,
287 height: 500,
288 width: 700,
289 title: dialogTitle,
290 modal: true,
291 buttons: {
292 "<?php esc_html_e( 'Submit', 'autoptimize' ); ?>": function() {
293 rpath = jQuery("#critcss_addedit_path").val();
294 rtype = jQuery("#critcss_addedit_pagetype option:selected").val();
295 rccss = jQuery("#critcss_addedit_css").val();
296 <?php if ( $ao_ccss_debug ) { ?>
297 console.log('rpath: ' + rpath, 'rtype: ' + rtype, 'rccss: ' + rccss);
298 <?php } ?>
299 if (rpath === '' && rtype === '') {
300 alert('<?php esc_html_e( "Rule validation error:\\n\\nBased on your rule type, you should set a path or conditional tag.", 'autoptimize' ); ?>');
301 } else if (rtype !== '' && rccss == '') {
302 alert('<?php esc_html_e( "Rule validation error:\\n\\nType based rules requires a minified critical CSS.", 'autoptimize' ); ?>');
303 } else if (rpath !== rpath.replace(/("|\'|<|>|\[|\]|{|}|\|)/,'')) {
304 alert('<?php esc_html_e( "Path validation error:\\n\\nThe path contains characters that are not permitted, remove or encode the unsafe characters.", 'autoptimize' ); ?>');
305 } else {
306 saveEditCritCss();
307 jQuery(this).dialog('close');
308 }
309 },
310 "<?php esc_html_e( 'Cancel', 'autoptimize' ); ?>": function() {
311 resetForm();
312 jQuery(this).dialog("close");
313 }
314 }
315 });
316 }
317
318 function editDefaultCritCss(){
319 document.getElementById("dummyDefault").value=document.getElementById("autoptimize_css_defer_inline").value;
320 jQuery("#dummyDefault").attr("spellcheck",false);
321 jQuery("#default_critcss_wrapper").dialog({
322 autoOpen: true,
323 height: 505,
324 width: 700,
325 title: "<?php esc_html_e( 'Default Critical CSS', 'autoptimize' ); ?>",
326 modal: true,
327 buttons: {
328 "<?php esc_html_e( 'Submit', 'autoptimize' ); ?>": function() {
329 document.getElementById("autoptimize_css_defer_inline").value=document.getElementById("dummyDefault").value;
330 jQuery("#unSavedWarning").show();
331 jQuery("#default_critcss_wrapper").dialog( "close" );
332 },
333 "<?php esc_html_e( 'Cancel', 'autoptimize' ); ?>": function() {
334 jQuery("#default_critcss_wrapper").dialog( "close" );
335 }
336 }
337 });
338 }
339
340 function editAdditionalCritCss(){
341 document.getElementById("dummyAdditional").value=document.getElementById("autoptimize_ccss_additional").value;
342 jQuery("#dummyAdditional").attr("spellcheck",false);
343 jQuery("#additional_critcss_wrapper").dialog({
344 autoOpen: true,
345 height: 505,
346 width: 700,
347 title: "<?php esc_html_e( 'Additional Critical CSS', 'autoptimize' ); ?>",
348 modal: true,
349 buttons: {
350 "<?php esc_html_e( 'Submit', 'autoptimize' ); ?>": function() {
351 document.getElementById("autoptimize_ccss_additional").value=document.getElementById("dummyAdditional").value;
352 jQuery("#unSavedWarning").show();
353 jQuery("#additional_critcss_wrapper").dialog( "close" );
354 },
355 "<?php esc_html_e( 'Cancel', 'autoptimize' ); ?>": function() {
356 jQuery("#additional_critcss_wrapper").dialog( "close" );
357 }
358 }
359 });
360 }
361
362 function saveEditCritCss(){
363 critcssfile=jQuery("#critcss_addedit_file").val();
364 critcsscontents=jQuery("#critcss_addedit_css").val();
365 critcsstype=jQuery("#critcss_addedit_type").val();
366 critcssid=jQuery("#critcss_addedit_id").val();
367
368 if (critcssid) {
369 // this was an "edit" action, so remove original
370 // will also remove the file, but that will get rewritten anyway
371 removeRow(critcssid);
372 }
373 if (critcsstype==="types") {
374 critcsstarget=jQuery("#critcss_addedit_pagetype").val();
375 } else {
376 critcsstarget=jQuery("#critcss_addedit_path").val();
377 }
378
379 if (!critcssfile && !critcsscontents) {
380 critcssfile=0;
381 } else if (!critcssfile && critcsscontents) {
382 critcssfile="ccss_" + md5(critcsscontents+critcsstarget) + ".css";
383 }
384
385 // Compose the rule object
386 critCssArray[critcsstype][critcsstarget]={};
387 critCssArray[critcsstype][critcsstarget].hash=0;
388 critCssArray[critcsstype][critcsstarget].file=critcssfile;
389
390 <?php
391 if ( $ao_ccss_debug ) {
392 echo "console.log('[RULE PROPERTIES] Type:', critcsstype, ', Target:', critcsstarget, ', Hash:', 0, ', File:', critcssfile);";
393 }
394 ?>
395
396 updateAfterChange();
397
398 var data = {
399 'action': 'save_critcss',
400 'critcss_save_nonce': '<?php echo wp_create_nonce( 'save_critcss_nonce' ); ?>',
401 'critcssfile': critcssfile,
402 'critcsscontents': critcsscontents
403 };
404
405 jQuery.post(ajaxurl, data, function(response) {
406 response_array=JSON.parse(response);
407 if (response_array["code"]!=200) {
408 displayNotice(response_array["string"]);
409 }
410 });
411 }
412
413 function updateAfterChange() {
414 document.getElementById("critCssOrigin").value=JSON.stringify(critCssArray);
415 drawTable(critCssArray);
416
417 <?php
418 // autosave rules is on by default, but can be disabled with a filter.
419 if ( apply_filters( 'autoptimize_filter_ccss_settings_rules_autosave', true ) ) {
420 ?>
421 var data = {
422 'action': 'ao_ccss_saverules',
423 'ao_ccss_saverules_nonce': '<?php echo wp_create_nonce( 'ao_ccss_saverules_nonce' ); ?>',
424 'critcssrules': document.getElementById("critCssOrigin").value
425 };
426
427 jQuery.post(ajaxurl, data, function(response) {
428 response_array=JSON.parse(response);
429 if (response_array["code"]!=200) {
430 displayNotice(response_array["msg"]);
431 jQuery("#unSavedWarning").show();
432 }
433 });
434 <?php } else { ?>
435 jQuery("#unSavedWarning").show();
436 <?php } ?>
437
438 document.getElementById('ao_title_and_button').scrollIntoView();
439 }
440
441 function displayNotice(textIn, level = 'error') {
442 jQuery('<div class="notice notice-' + level + ' notice is-dismissible"><p>'+textIn+'</p></div>').insertBefore("#unSavedWarning");
443 document.getElementById('ao_title_and_button').scrollIntoView();
444 }
445
446 function resetForm() {
447 jQuery("#critcss_addedit_css").attr("placeholder", "<?php esc_html_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' ); ?>");
448 jQuery("#critcss_addedit_type").attr("disabled",false);
449 jQuery("#critcss_addedit_path_wrapper").show();
450 jQuery("#critcss_addedit_id").val("");
451 jQuery("#critcss_addedit_path").val("");
452 jQuery("#critcss_addedit_file").val("");
453 jQuery("#critcss_addedit_pagetype").val("");
454 jQuery("#critcss_addedit_css").val("");
455 }
456