Asset CleanUp: Page Speed Booster - Version 1.3.6.2

Version Description

  • Once a page is updated, the plugin preloads that page for both the admin and the guest visitor, making sure any new changes would take effect, saving the admin's time and making sure any first visitor coming to that page will access it faster (not having to wait for the caching to re-built)
  • If the attribute "data-wpacu-skip" is applied to any CSS/JS, then no alteration (e.g. no minify and no addition to any combine list) will be applied to that file (apart from the actual unload or attributes such as async/defer)
  • 'Remove All "generator" meta tags?' improvement: Higher accuracy in stripping META tag generators if the option is enabled in case some of their attributes have no quotes around them (rare cases)
  • If 'Remove "REST API" link tag?' is enabled, the /wp-json/ reference is also removed from the "Response headers" when accessing the page via remove_action()
  • Compatibility with extra page builders: "X" & "PRO" themes (Theme.co), "WP Page Builder" & "Page Builder: Live Composer" plugins: whenever their editor is ON, no unloads or any other changes to the HTML source (including minification) are performed to make sure the editor is loading its files and works smoothly
  • Compatibility with "Redis Object Cache" plugin: The global variable $wp_object_cache from the WordPress core is no longer used and it's replaced with a custom solution
  • Compatibility with "404page your smart custom 404 error page" plugin and similar plugins that are making pages as 404 customizable ones
  • For debugging purposes, the admin can use /?wpacu_no_cache to view how the website would load without the CSS/JS cache applied (the files will still be referenced from the caching directory but they will be dynamically generated instead)
  • Sometimes, large inline STYLE/SCRIPT tags' content has to be minified; if it's between 40KB and 500 KB it will be cached; any tags' content over 500KB will not be minified as it would use too many resources; it's advisable to put very large tag content into a .js external file as it would affect the TTFB (time to the first byte) when the page is loaded
  • Any inline CSS/JS associated with a handle (generated via wp_add_inline_style() and wp_add_inline_script() respectively) are automatically added to the combined file
  • Combined CSS/JS files are all stored in /wp-content/cache/asset-cleanup/("css" or "js")/ to avoid duplicated files that used to be stored in "logged-in" directory which is no longer created; This reduces the total disk space especially when the same CSS/JS is created (sometimes these files are quite large) for both guests & logged-in users
  • If "Combine loaded CSS (Stylesheets) into fewer files" is enabled, the LINK tags that are preloaded (at least two of them) will also be combined, thus reducing the number of HTTP requests
  • The method loadHTML() from DOMDocument is processing tags faster as the initial HTML source passed to it as a parameter goes through several filters, making it much smaller which makes a different in page speed when it comes to large HTML sources
  • Prevent certain DOMDocument calls (which can be slow on large HTML documents) when they are not necessary (e.g. when preloading CSS stylesheets and the RegEx which is faster can do the same task with the same accuracy)
  • Strip LINK tags that are pointing to empty content (including any inline code associated with the enqueued style added via wp_add_inline_style() function) if "CSS Files Minification" is enabled, making sure any empty tags are also stripped when "Inline CSS Files" is enabled, this saving HTTP requests and having less DOM elements
  • In some cases, the PHP function strtr() has proven to be faster than str_replace() to make replacements, thus it has been applied to some methods that are dealing with the alteration of the HTML source
  • Notify the admin that unloading 'jquery-migrate' won't unload it's "child" as well, 'jquery' (as it's a special case)
  • Fix: In rare cases, URLs to the assets are starting with ../ (it's not the best practice as this would only work depending on the page's URL structure); Make sure the file's size is calculated correctly and the right URL for the file is checked in the background to determine if it returns a 200 OK response or not
  • Fix: Store the assets info (which are shown only within the Dashboard for reference purposes) with the relative location (UR) to the asset, in case the data is later imported from a Staging to Live environment, it won't show any Staging URLs on the Live website on pages such as "Overview", thus avoiding any confusion the admin might have
  • Fix: Make sure the time dequeueing CSS/JS is calculated correctly
  • Fix: If "Asynchronous via Web Font Loader (webfont.js)" was chosen for "Combine Multiple Requests Into Fewer Ones", the font weights weren't added to the final generated SCRIPT tag
  • Fix: Make sure when the handle information is saved, there are no PHP notice errors if the 'src' index is missing as some handles do not have an "src"
Download this release

Release Info

Developer gabelivan
Plugin Icon 128x128 Asset CleanUp: Page Speed Booster
Version 1.3.6.2
Comparing to
See all releases

Code changes from version 1.3.6.1 to 1.3.6.2

assets/script.min.js CHANGED
@@ -1 +1 @@
1
- function wpacuTabOpenSettingsArea(a,b){a.preventDefault();var c,d,e;for(d=document.getElementsByClassName("wpacu-settings-tab-content"),c=0;c<d.length;c++)d[c].style.display="none";for(e=document.getElementsByClassName("wpacu-settings-tab-link"),c=0;c<e.length;c++)e[c].className=e[c].className.replace(" active","");document.getElementById(b).style.display="table-cell",jQuery('a[href="#'+b+'"]').addClass("active"),jQuery("#wpacu-selected-tab-area").val(b)}function wpacuBytesToSize(a){return 0===a?"N/A":(a/1024).toFixed(4)+" KB"}function wpacuAjaxClearCache(){jQuery.post(wpacu_object.ajax_url+"?wpacu_clear_cache",{action:wpacu_object.plugin_id+"_clear_cache",time_r:(new Date).getTime()},function(a){setTimeout(function(){wpacuClearAutoptimizeCache()},150)})}function wpacuClearAutoptimizeCache(){jQuery("#wp-admin-bar-autoptimize-default li").length>0&&void 0!==autoptimize_ajax_object.ajaxurl&&void 0!==autoptimize_ajax_object.nonce&&jQuery.ajax({type:"GET",url:autoptimize_ajax_object.ajaxurl,data:{action:"autoptimize_delete_cache",nonce:autoptimize_ajax_object.nonce},dataType:"json",cache:!1,timeout:9e3,success:function(a){},error:function(a,b){}})}jQuery(document).ready(function(a){function b(){if(!a("#wpacu_ajax_fetch_assets_list_dashboard_view").length)return!1;var b,c,d,f,g,h={};"direct"===wpacu_object.dom_get_type?(h[wpacu_object.plugin_name+"_load"]=1,h[wpacu_object.plugin_name+"_time_r"]=(new Date).getTime(),a.ajax({method:"GET",url:wpacu_object.page_url,data:h,cache:!1,complete:function(b,c){if("error"===b.statusText){f=b.responseText.replace(/(<([^>]+)>)/gi,"");try{f=String(f).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}catch(a){console.log(a)}g=wpacu_object.ajax_direct_fetch_error,g=g.replace(/{wpacu_output}/,f),g=g.replace(/{wpacu_status_code_error}/,b.status),a("#wpacu_meta_box_content").html(g)}}}).done(function(f){if(f.lastIndexOf(wpacu_object.start_del_e)<0||f.lastIndexOf(wpacu_object.end_del_e)<0||f.lastIndexOf(wpacu_object.start_del_h)<0||f.lastIndexOf(wpacu_object.end_del_h)<0){g=wpacu_object.ajax_direct_fetch_error_with_success_response,g=g.replace(/{wpacu_output}/,xhr.responseText.replace(/(<([^>]+)>)/gi,""));try{g=String(g).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}catch(a){console.log(a)}return void a("#wpacu_meta_box_content").html(g)}c=f.substring(f.lastIndexOf(wpacu_object.start_del_e)+wpacu_object.start_del_e.length,f.lastIndexOf(wpacu_object.end_del_e)),d=f.substring(f.lastIndexOf(wpacu_object.start_del_h)+wpacu_object.start_del_h.length,f.lastIndexOf(wpacu_object.end_del_h)),b={action:wpacu_object.plugin_name+"_get_loaded_assets",wpacu_list_e:c,wpacu_list_h:d,post_id:wpacu_object.post_id,page_url:wpacu_object.page_url,tag_id:wpacu_object.tag_id,wpacu_taxonomy:wpacu_object.wpacu_taxonomy,time_r:(new Date).getTime()},a.post(wpacu_object.ajax_url,b,function(b){b&&(a("#wpacu_meta_box_content").html(b),a("#wpacu_home_page_form").length>0&&a("#submit").show(),setTimeout(function(){e.load(),a(".wpacu_asset_row").removeClass("wpacu-loading"),a("#wpacu-assets-reloading").remove(),e.checkSourcesFor404Errors()},200))})})):"wp_remote_post"===wpacu_object.dom_get_type&&(b={action:wpacu_object.plugin_name+"_get_loaded_assets",post_id:wpacu_object.post_id,page_url:wpacu_object.page_url,tag_id:wpacu_object.tag_id,wpacu_taxonomy:wpacu_object.wpacu_taxonomy,time_r:(new Date).getTime()},a.post(wpacu_object.ajax_url,b,function(b){if(!b)return!1;a("#wpacu_meta_box_content").html(b),a("#wpacu_home_page_form").length>0&&a("#submit").show(),setTimeout(function(){e.load(),setTimeout(function(){e.checkSourcesFor404Errors()},100)},200)}))}a('input[name="wpacu_sub_tab_area"]').click(function(){a(this).prop("checked")&&a("#wpacu-selected-sub-tab-area").val(a(this).val())}),a("#wpacu_minify_css_enable, #wpacu_combine_loaded_css_enable, #wpacu_minify_js_enable, #wpacu_combine_loaded_js_enable, #wpacu_cdn_rewrite_enable, #wpacu_enable_test_mode").click(function(){a(this).prop("checked")?a('[data-linked-to="'+a(this).attr("id")+'"]').find(".wpacu-circle-status").addClass("wpacu-on").removeClass("wpacu-off"):a('[data-linked-to="'+a(this).attr("id")+'"]').find(".wpacu-circle-status").addClass("wpacu-off").removeClass("wpacu-on")}),a(document).on("click","#wpacu_inline_css_files_below_size_checkbox",function(){a(this).is(":checked")?a("#wpacu_inline_css_files_enable").prop("checked",!0).trigger("tick"):""===a("#wpacu_inline_css_files_list").val()&&a("#wpacu_inline_css_files_enable").prop("checked",!1).trigger("tick")}),a(document).on("click","#wpacu_inline_js_files_below_size_checkbox",function(){if(a(this).is(":checked")){if(!confirm(wpacu_object.inline_auto_js_files_confirm_msg))return!1;a("#wpacu_inline_js_files_enable").prop("checked",!0).trigger("tick")}else""===a("#wpacu_inline_js_files_list").val()&&a("#wpacu_inline_js_files_enable").prop("checked",!1).trigger("tick")}),a("#wpacu-mark-license-valid-button").click(function(){return confirm(wpacu_object.mark_license_valid_confirm)}),a("#wpacu-license-form").submit(function(){a("#edd_license_activate_btn").attr("disabled","disabled"),a("#edd_license_deactivate_btn").attr("disabled","disabled"),a(".wpacu-license-spinner").show()});var c,d;a("#wpacu-reset-drop-down").on("change keyup keydown mouseup mousedown click",function(){""===a(this).val()?(a("#wpacu-warning-read").removeClass("wpacu-visible"),a("#wpacu-reset-submit-btn").attr("disabled","disabled").removeClass("button-primary").addClass("button-secondary")):("reset_everything"===a(this).val()?a("#wpacu-license-data-remove-area, #wpacu-cache-assets-remove-area").addClass("wpacu-visible"):a("#wpacu-license-data-remove-area, #wpacu-cache-assets-remove-area").removeClass("wpacu-visible"),a("#wpacu-warning-read").addClass("wpacu-visible"),a("#wpacu-reset-submit-btn").removeAttr("disabled").removeClass("button-secondary").addClass("button-primary")),a(".wpacu-tools-area .wpacu-warning").hide(),c=a(this).find("option:selected"),a("#"+c.attr("data-id")).show()}),a("#wpacu-reset-submit-btn").on("click",function(){if("reset_settings"===a("#wpacu-reset-drop-down").val()?d=wpacu_object.reset_settings_confirm_msg:"reset_everything_except_settings"===a("#wpacu-reset-drop-down").val()?d=wpacu_object.reset_everything_except_settings_confirm_msg:"reset_everything"===a("#wpacu-reset-drop-down").val()&&(d=wpacu_object.reset_everything_confirm_msg),!confirm(d))return!1;a("#wpacu-action-confirmed").val("yes"),setTimeout(function(){"yes"===a("#wpacu-action-confirmed").val()&&a("#wpacu-tools-form").submit()},1e3)}),a("#wpacu-import-form").submit(function(){if(!confirm(wpacu_object.import_confirm_msg))return!1;a(this).find("button").addClass("wpacu-importing").prop("disabled",!0)});var e={load:function(){var b,c,d,f=".input-unload-on-this-page.wpacu-not-locked";a(".input-unload-on-this-page").on("click change",function(f){if(b=a(this).attr("data-handle"),c=a(this).hasClass("wpacu_unload_rule_for_style")?"style":"script",a(this).prop("checked")){if("click"===f.type&&!e.triggerAlertWhenAnyUnloadRuleIsChosen(b,c))return!1;e.uncheckAllOtherBulkUnloadRules(a(this),!1),e.showHandleLoadExceptionArea(c,b),a(this).closest("tr").addClass("wpacu_not_load")}else a(this).closest("tr").removeClass("wpacu_not_load"),d=a(this).parents(".wpacu_asset_row"),e.hideHandleLoadExceptionArea(d,b,c)}),a(".wpacu-plugin-check-all").on("click",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-plugin");a('table.wpacu_list_by_location[data-wpacu-plugin="'+c+'"]').find(f).prop("checked",!0).closest("tr").addClass("wpacu_not_load")}),a(".wpacu-plugin-uncheck-all").on("click",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-plugin");a('table.wpacu_list_by_location[data-wpacu-plugin="'+c+'"]').find(f).prop("checked",!1).closest("tr").removeClass("wpacu_not_load")}),a(".wpacu-plugin-check-load-all").on("click change",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-plugin"),d=a('table.wpacu_list_by_location[data-wpacu-plugin="'+c+'"]');d.find(".wpacu_load_it_option_one.wpacu_load_exception").prop("checked",!0).closest("tr.wpacu_is_bulk_unloaded").removeClass("wpacu_not_load"),d.find(f).prop("checked",!1).trigger("change")}),a(".wpacu-plugin-uncheck-load-all").on("click change",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-plugin"),d=a('table.wpacu_list_by_location[data-wpacu-plugin="'+c+'"]');d.find(".wpacu_load_it_option_one.wpacu_load_exception").prop("checked",!1).closest("tr.wpacu_is_bulk_unloaded").addClass("wpacu_not_load"),d.find(f).prop("checked",!1).trigger("change")}),a(".wpacu_keep_bulk_rule").click(function(){a(this).prop("checked")&&a(this).parents("li").next().removeClass("remove_rule")}),a(".wpacu_remove_bulk_rule").click(function(){a(this).prop("checked")&&a(this).parents("li").addClass("remove_rule")}),a(".wpacu_bulk_unload").on("click change",function(f){b=a(this).attr("data-handle"),c=a(this).attr("data-handle-for"),d=a("[data-"+c+'-handle-row="'+b+'"]');var g=a(this).parents("li");if(a(this).prop("checked")){if("click"===f.type&&!e.triggerAlertWhenAnyUnloadRuleIsChosen(b,c))return!1;a(this).hasClass("wpacu_unload_it_regex_checkbox")?(g.find("label").addClass("wpacu_unload_checked"),g.find("textarea").prop("disabled",!1).focus().removeClass("wpacu_disabled"),g.find(".wpacu_handle_unload_regex_input_wrap").removeClass("wpacu_hide")):(a(this).parent("label").addClass("wpacu_input_load_checked"),a(this).closest("tr").addClass("wpacu_not_load")),e.showHandleLoadExceptionArea(c,b),a(this).hasClass("wpacu_global_unload")?(e.uncheckAllOtherBulkUnloadRules(a(this),!0),a('.input-unload-on-this-page[data-handle-for="'+c+'"][data-handle="'+b+'"]').prop("checked",!1)):a(this).hasClass("wpacu_post_type_unload")&&(e.uncheckAllOtherBulkUnloadRules(a(this),!1),a('.input-unload-on-this-page[data-handle-for="'+c+'"][data-handle="'+b+'"]').prop("checked",!1))}else a(this).hasClass("wpacu_unload_it_regex_checkbox")?(g.find("label").removeClass("wpacu_unload_checked"),g.find("textarea").blur().addClass("wpacu_disabled"),""===g.find("textarea").val().trim()&&(g.find("textarea").prop("disabled",!0).val(""),g.find(".wpacu_handle_unload_regex_input_wrap").addClass("wpacu_hide"))):(a(this).parent("label").removeClass("wpacu_input_load_checked"),a(this).closest("tr").removeClass("wpacu_not_load")),e.hideHandleLoadExceptionArea(d,b,c);d.hasClass("wpacu_is_bulk_unloaded")||a(".wpacu_bulk_unload:not(.wpacu_unload_it_regex_checkbox)").is(":checked")||a(this).closest("tr").removeClass("wpacu_not_load")}),a(".wpacu_load_it_option_one.wpacu_load_exception").on("click change",function(){var b=a(this).attr("data-handle");if(a(this).prop("checked")){a(this).parent("label").addClass("wpacu_global_unload_exception");var c="";a(this).hasClass("wpacu_style")?c="style":a(this).hasClass("wpacu_script")&&(c="script"),a("#"+c+"_"+b).prop("checked",!1).trigger("change")}else a(this).parent("label").removeClass("wpacu_global_unload_exception")}),a(".wpacu_load_it_option_two").on("click change",function(){var b=a(this).parents("li");a(this).prop("checked")?(b.find("label").addClass("wpacu_bold"),b.find("textarea").prop("disabled",!1).focus().removeClass("wpacu_disabled"),b.find(".wpacu_load_regex_input_wrap").removeClass("wpacu_hide")):(b.find("label").removeClass("wpacu_bold"),b.find("textarea").blur().addClass("wpacu_disabled"),""===b.find("textarea").val().trim()&&(b.find("textarea").prop("disabled",!0).val(""),b.find(".wpacu_load_regex_input_wrap").addClass("wpacu_hide")))}),a(".wpacu_script_attr_rule_input").on("click change",function(){a(this).is(":checked")&&(a(this).parents("ul").find(".wpacu_script_attr_rule_input").not(a(this)).prop("checked",!1),a(this).hasClass("wpacu_script_attr_rule_global")&&a(this).parents("ul").find(".wpacu-script-attr-make-exception").removeClass("wpacu_hide")),a(this).parents("ul").find(".wpacu_script_attr_rule_global").is(":checked")||a(this).parents("ul").find(".wpacu-script-attr-make-exception").addClass("wpacu_hide")}),a(".wpacu-add-handle-note").on("click",function(b){b.preventDefault();var c,d,e=a(this).attr("data-handle");a(this).hasClass("wpacu-for-script")?c=a('.wpacu-handle-notes-field[data-script-handle="'+e+'"]'):a(this).hasClass("wpacu-for-style")&&(c=a('.wpacu-handle-notes-field[data-style-handle="'+e+'"]')),c.length<1||(d=c.find(":input"),c.is(":hidden")?(c.show(),d.prop("disabled",!1)):(c.hide(),""===d.val().trim()&&"true"===d.attr("data-wpacu-is-empty-on-page-load")&&d.prop("disabled",!0).val("")))}),a(".wpacu-external-file-size").on("click",function(b){b.preventDefault();var c,d=a(this),e=d.attr("data-src");d.hide(),c=d.next(),c.show(),e.includes("/?")?a.get(e,{},function(a,b,d){if("success"!==b)return"N/A";c.html(wpacuBytesToSize(a.length))}):a.post(wpacu_object.ajax_url,{action:wpacu_object.plugin_id+"_get_external_file_size",wpacu_remote_file:e},function(a){c.html(a)})}),a(".wpacu_handle_row_expand_contract").on("click",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-handle"),d=a(this).attr("data-wpacu-handle-for");a(this).find("span").hasClass("dashicons-minus")?(a(this).parents("td").attr("data-wpacu-row-status","contracted").find(".wpacu_handle_row_expanded_area").addClass("wpacu_hide"),a(this).find("span").removeClass("dashicons-minus").addClass("dashicons-plus"),a("#wpacu_"+d+"_"+c+"_row_contracted_area").val("1")):a(this).find("span").hasClass("dashicons-plus")&&(a(this).parents("td").attr("data-wpacu-row-status","expanded").find(".wpacu_handle_row_expanded_area").removeClass("wpacu_hide"),a(this).find("span").removeClass("dashicons-plus").addClass("dashicons-minus"),a("#wpacu_"+d+"_"+c+"_row_contracted_area").val(""))});a('[data-is-hardcoded-asset="true"]').length>0&&(a.each(a('[data-is-hardcoded-asset="true"]'),function(b,c){e.updateHardcodedDataHiddenFieldStatus(a(this))}),a('[data-is-hardcoded-asset="true"]').on("click",".wpacu_unload_rule_input",function(){e.updateHardcodedDataHiddenFieldStatus(a(this).parents("[data-is-hardcoded-asset]"))}))},updateHardcodedDataHiddenFieldStatus:function(b){var c=!1;b.is("[data-style-handle-row]")?c=b.attr("data-style-handle-row"):b.is("[data-script-handle-row]")&&(c=b.attr("data-script-handle-row")),c&&(b.find(".wpacu_unload_rule_input:checked").length>0||b.hasClass("wpacu_not_load")?a("#"+c+"_hardcoded_data").prop("disabled",!1):a("#"+c+"_hardcoded_data").prop("disabled",!0))},triggerAlertWhenAnyUnloadRuleIsChosen:function(b,c){if("dashicons"===b&&"style"===c&&a('input[name="wpacu_ignore_child[styles][nf-display]').length>0&&!confirm(wpacu_object.dashicons_unload_alert_ninja_forms))return!1;if("script"===c){if(("jquery"===b||"jquery-core"===b)&&a("#script_jquery_ignore_children").length>0&&!confirm(wpacu_object.jquery_unload_alert))return!1;if(("backbone"===b||"underscore"===b)&&!confirm(wpacu_object.sensitive_library_unload_alert))return!1}return!0},pluginLoadManager:function(){a(".wpacu_plugin_load_it").on("click",function(){var b=a(this).attr("data-wpacu-plugin-path");a(this).prop("checked")&&(e.hidePluginLoadExceptionArea(b),a('.wpacu_plugin_unload_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide"),a('.wpacu_plugin_unload_site_wide[data-wpacu-plugin-path="'+b+'"]').parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"),a('.wpacu_plugin_unload_regex_radio[data-wpacu-plugin-path="'+b+'"]').parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"))}),a(".wpacu_plugin_unload_site_wide").on("click",function(){var b=a(this).attr("data-wpacu-plugin-path");a(this).prop("checked")?(a(this).parent("label").addClass("wpacu_plugin_unload_rule_input_checked"),a('.wpacu_plugin_unload_regex_radio[data-wpacu-plugin-path="'+b+'"]').parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"),a('.wpacu_plugin_unload_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide"),e.showPluginLoadExceptionArea(b)):(a(this).parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"),a('.wrap_plugin_load_exception_options[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide").find('input[type="checkbox"]').prop("disabled",!0))}),a(".wpacu_plugin_unload_regex_radio").on("click",function(){var b=a(this).attr("data-wpacu-plugin-path");a(this).prop("checked")?(a(this).parent("label").addClass("wpacu_plugin_unload_rule_input_checked"),a('.wpacu_plugin_unload_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').removeClass("wpacu_hide"),e.showPluginLoadExceptionArea(b),a('.wpacu_plugin_unload_site_wide[data-wpacu-plugin-path="'+b+'"]').prop("checked",!1).parent("label").removeClass("wpacu_plugin_unload_rule_input_checked")):(a('.wpacu_plugin_unload_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide"),a(this).parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"),a('.wrap_plugin_load_exception_options[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide"))}),a(".wpacu_plugin_load_exception_regex").on("click",function(){var b=a(this).attr("data-wpacu-plugin-path");a(this).prop("checked")?a('.wpacu_load_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').removeClass("wpacu_hide"):a('.wpacu_load_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide")})},showPluginLoadExceptionArea:function(b){a('.wrap_plugin_load_exception_options[data-wpacu-plugin-path="'+b+'"]').removeClass("wpacu_hide").find('input[type="checkbox"]').prop("disabled",!1)},hidePluginLoadExceptionArea:function(b){a('.wrap_plugin_load_exception_options[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide").find('input[type="checkbox"]').prop("disabled",!0)},showHandleLoadExceptionArea:function(b,c){var d=a("div.wpacu_exception_options_area_wrap[data-"+b+'-handle="'+c+'"]');d.parent("div").removeClass("wpacu_hide"),d.find('input[type="checkbox"]').prop("disabled",!1)},hideHandleLoadExceptionArea:function(b,c,d){if(!b.hasClass("wpacu_is_bulk_unloaded")&&!b.find(".wpacu_bulk_unload").is(":checked")){var e=a("div.wpacu_exception_options_area_wrap[data-"+d+'-handle="'+c+'"]');e.parent("div").addClass("wpacu_hide"),e.find('input[type="checkbox"]').prop("disabled",!0)}},uncheckAllOtherBulkUnloadRules:function(a,b){var c=".wpacu_bulk_unload";!1===b&&(c=".wpacu_bulk_unload:not(.wpacu_unload_it_regex_checkbox)"),a.closest("tr").find(c).not(a).prop("checked",!1).parent("label").removeClass("wpacu_input_load_checked").removeClass("wpacu_unload_checked")},checkSourcesFor404Errors:function(){var b=a("[data-wpacu-external-source]");if(!(b.length<1)){var c=b.length,d="";b.each(function(b){var e=a(this),f=e.attr("data-wpacu-external-source");d+=f+"-at-wpacu-at-",b===c-1&&jQuery.post(wpacu_object.ajax_url+"?wpacu_check_external_url",{action:wpacu_object.plugin_id+"_check_external_urls_for_status_code",wpacu_check_urls:d},function(b){var c=jQuery.parseJSON(b);a.each(c,function(b,c){a('[data-wpacu-external-source="'+c+'"]').css({color:"#cc0000"}).parent("div").find("[data-wpacu-external-source-status]").html('<small>* <em style="font-weight: 600;">'+wpacu_object.source_load_error_msg+"</em></small>")})})})}}};a(window).load(function(){e.checkSourcesFor404Errors()}),a("#wpacu_post_type_select").change(function(){a("#wpacu_post_type_form").submit()}),a("#wpacu_taxonomy_select").change(function(){a("#wpacu_taxonomy_form").submit()}),a("#wpacu_dashboard").click(function(){a(this).prop("checked")?a("#wpacu-settings-assets-retrieval-mode").show():a("#wpacu-settings-assets-retrieval-mode").hide()}),a(".wpacu-dom-get-type-selection").change(function(){a(this).is(":checked")&&(a(".wpacu-dom-get-type-info").hide(),a("#"+a(this).attr("data-target")).fadeIn("fast"))}),a("#wpacu_frontend").click(function(){a(this).prop("checked")?a("#wpacu-settings-frontend-exceptions").show():a("#wpacu-settings-frontend-exceptions").hide()}),a(".google_fonts_combine_type").change(function(){a(".wpacu_google_fonts_combine_type_area").hide(),"async"===a(this).val()?a("#wpacu_google_fonts_combine_type_async_info_area").fadeIn():"async_preload"===a(this).val()?a("#wpacu_google_fonts_combine_type_async_preload_info_area").fadeIn():a("#wpacu_google_fonts_combine_type_rb_info_area").fadeIn()}),a("#wpacu_assets_list_layout").on("click change",function(){"by-location"===a(this).val()?a("#wpacu-assets-list-by-location-selected").fadeIn("fast"):a("#wpacu-assets-list-by-location-selected").fadeOut("fast")}),a("#wpacu_disable_jquery_migrate").on("click",function(){return!a(this).is(":checked")||(!(!a(this).is(":checked")||!confirm(wpacu_object.jquery_migration_disable_confirm_msg))||(a(this).prop("checked",!1),!1))}),a("#wpacu_disable_comment_reply").on("click",function(){return!a(this).is(":checked")||(!(!a(this).is(":checked")||!confirm(wpacu_object.comment_reply_disable_confirm_msg))||(a(this).prop("checked",!1),!1))}),a("[data-target-opacity]").on("click change tick",function(){a(this).prop("checked")?a("#"+a(this).attr("data-target-opacity")).css({opacity:1}):a("#"+a(this).attr("data-target-opacity")).css({opacity:.4})}),a(".wpacu-combine-loaded-js-level").change(function(){a(this).is(":checked")&&(a(".wpacu_combine_loaded_js_level_area").removeClass("wpacu_active"),a("#"+a(this).attr("data-target")).addClass("wpacu_active"))});var f=a('#wpacu-update-button-area input[type="submit"]');f.parents("form").submit(function(){f.attr("disabled",!0),a("#wpacu-updating-settings").show()});var g=a("#wpacu-update-front-settings-area .wpacu_update_btn");if(g.parents("form").submit(function(){return g.attr("disabled",!0).addClass("wpacu_submitting"),a("#wpacu-updating-front-settings").show(),!0}),a("form#wpacu-settings-form, form#wpacu_home_page_form").submit(function(){return f.attr("disabled",!0),!0}),a(".wpacu_bulk_rule_checkbox, .wpacu_remove_preload").click(function(){var b=a(this).parents(".wpacu_bulk_change_row");a(this).prop("checked")?b.addClass("wpacu_selected"):b.removeClass("wpacu_selected")}),a(".wpacu_remove_regex").click(function(){var b=a(this).parents(".wpacu_regex_rule_row");a(this).prop("checked")?b.addClass("wpacu_enabled"):b.removeClass("wpacu_enabled")}),a(".wpacu_restore_position").click(function(){var b=a(this).parents(".wpacu_restore_position_row");a(this).prop("checked")?b.addClass("wpacu_selected"):b.removeClass("wpacu_selected")}),a(".wpacu_remove_global_attr").click(function(){var b=a(this).parents(".wpacu_remove_global_attr_row");a(this).prop("checked")?b.addClass("wpacu_selected"):b.removeClass("wpacu_selected")}),a("#wpacu_wrap_assets").length>0&&setTimeout(function(){e.load()},200),a("#wpacu-plugins-load-manager-wrap").length>0&&setTimeout(function(){e.pluginLoadManager()},200),"undefined"==typeof wpacu_object||a("#wpacu_meta_box_content").length<1)return!1;("default"===wpacu_object.list_show_status||""===wpacu_object.list_show_status||wpacu_object.override_assets_list_load)&&b(),"fetch_on_click"===wpacu_object.list_show_status&&a("#wpacu_ajax_fetch_on_click_btn").click(function(c){c.preventDefault(),a(this).hide(),a("#wpacu_fetching_assets_list_wrap").show(),b()}),a(document).on("click",".wp-admin.post-php .edit-post-header__settings button.is-primary",function(){var c=function(){if(0===a(".edit-post-header__settings .is-saving").length){if(a("#wpacu_unload_assets_area_loaded").length>0&&a("#wpacu_unload_assets_area_loaded").val()){a("#wpacu-assets-reloading").remove();var c='<span id="wpacu-assets-reloading" class="editor-post-saved-state is-wpacu-reloading">'+wpacu_object.reload_icon+wpacu_object.reload_msg+"</span>";a(".wp-admin.post-php .edit-post-header__settings").prepend(c)}a(".wpacu_asset_row").addClass("wpacu-loading"),b(),wpacuAjaxClearCache(),clearInterval(d)}},d=setInterval(c,900)})}),""!==wpacu_object.clear_cache_on_page_load&&wpacuAjaxClearCache(),""!==wpacu_object.clear_other_caches&&setTimeout(function(){wpacuClearAutoptimizeCache()},150),jQuery(document).ready(function(a){try{var b;a('input[type="hidden"][name="_wp_http_referer"]').length>0&&(b=a('input[type="hidden"][name="_wp_http_referer"]').val(),b.includes("term.php?taxonomy=")&&b.includes("message=")&&wpacuAjaxClearCache(),b.includes("post.php?post=")&&b.includes("message=")&&wpacuAjaxClearCache())}catch(a){console.log(a)}});
1
+ function wpacuTabOpenSettingsArea(a,b){a.preventDefault();var c,d,e;for(d=document.getElementsByClassName("wpacu-settings-tab-content"),c=0;c<d.length;c++)d[c].style.display="none";for(e=document.getElementsByClassName("wpacu-settings-tab-link"),c=0;c<e.length;c++)e[c].className=e[c].className.replace(" active","");document.getElementById(b).style.display="table-cell",jQuery('a[href="#'+b+'"]').addClass("active"),jQuery("#wpacu-selected-tab-area").val(b)}function wpacuBytesToSize(a){return 0===a?"N/A":(a/1024).toFixed(4)+" KB"}function wpacuAjaxClearCache(){jQuery.post(wpacu_object.ajax_url+"?wpacu_clear_cache",{action:wpacu_object.plugin_id+"_clear_cache",time_r:(new Date).getTime()},function(a){setTimeout(function(){wpacuClearAutoptimizeCache(),wpacu_object.is_frontend_view?jQuery.post(wpacu_object.ajax_url+"?wpacu_preload_guest",{action:wpacu_object.plugin_id+"_preload",page_url:wpacu_object.page_url,time_r:(new Date).getTime()}):jQuery.get(wpacu_object.page_url,{wpacu_preload:1,wpacu_no_frontend_show:1,time_r:(new Date).getTime()},function(){jQuery.post(wpacu_object.ajax_url+"?wpacu_preload_guest",{action:wpacu_object.plugin_id+"_preload",page_url:wpacu_object.page_url,time_r:(new Date).getTime()})})},150)})}function wpacuClearAutoptimizeCache(){jQuery("#wp-admin-bar-autoptimize-default li").length>0&&void 0!==autoptimize_ajax_object.ajaxurl&&void 0!==autoptimize_ajax_object.nonce&&jQuery.ajax({type:"GET",url:autoptimize_ajax_object.ajaxurl,data:{action:"autoptimize_delete_cache",nonce:autoptimize_ajax_object.nonce},dataType:"json",cache:!1,timeout:9e3,success:function(a){},error:function(a,b){}})}jQuery(document).ready(function(a){function b(){if(!a("#wpacu_ajax_fetch_assets_list_dashboard_view").length)return!1;var b={};if("direct"===wpacu_object.dom_get_type)b[wpacu_object.plugin_name+"_load"]=1,b[wpacu_object.plugin_name+"_time_r"]=(new Date).getTime(),a.ajax({method:"GET",url:wpacu_object.page_url,data:b,cache:!1,complete:function(b,d){if("error"===b.statusText){if(404===b.status)return void c(b.responseText,b.status);var e=b.responseText.replace(/(<([^>]+)>)/gi,"");try{e=String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}catch(a){console.log(a)}var f=wpacu_object.ajax_direct_fetch_error;f=f.replace(/{wpacu_output}/,e),f=f.replace(/{wpacu_status_code_error}/,b.status),a("#wpacu_meta_box_content").html(f)}}}).done(function(a){c(a)});else if("wp_remote_post"===wpacu_object.dom_get_type){var d={action:wpacu_object.plugin_name+"_get_loaded_assets",post_id:wpacu_object.post_id,page_url:wpacu_object.page_url,tag_id:wpacu_object.tag_id,wpacu_taxonomy:wpacu_object.wpacu_taxonomy,time_r:(new Date).getTime()};a.post(wpacu_object.ajax_url,d,function(b){if(!b)return!1;a("#wpacu_meta_box_content").html(b),a("#wpacu_home_page_form").length>0&&a("#submit").show(),setTimeout(function(){f.load(),setTimeout(function(){f.checkSourcesFor404Errors()},100)},200)})}}function c(b,c){if(b.lastIndexOf(wpacu_object.start_del_e)<0||b.lastIndexOf(wpacu_object.end_del_e)<0||b.lastIndexOf(wpacu_object.start_del_h)<0||b.lastIndexOf(wpacu_object.end_del_h)<0){var d=wpacu_object.ajax_direct_fetch_error_with_success_response;d=d.replace(/{wpacu_output}/,xhr.responseText.replace(/(<([^>]+)>)/gi,""));try{d=String(d).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}catch(a){console.log(a)}return void a("#wpacu_meta_box_content").html(d)}var e=b.substring(b.lastIndexOf(wpacu_object.start_del_e)+wpacu_object.start_del_e.length,b.lastIndexOf(wpacu_object.end_del_e)),g=b.substring(b.lastIndexOf(wpacu_object.start_del_h)+wpacu_object.start_del_h.length,b.lastIndexOf(wpacu_object.end_del_h)),h={action:wpacu_object.plugin_name+"_get_loaded_assets",wpacu_list_e:e,wpacu_list_h:g,post_id:wpacu_object.post_id,page_url:wpacu_object.page_url,tag_id:wpacu_object.tag_id,wpacu_taxonomy:wpacu_object.wpacu_taxonomy,time_r:(new Date).getTime()};a.post(wpacu_object.ajax_url,h,function(b){b&&(a("#wpacu_meta_box_content").html(b),404===c&&a("#wpacu_meta_box_content").prepend('<p><span class="dashicons dashicons-warning"></span> '+wpacu_object.server_returned_404_not_found+"</p><hr />"),a("#wpacu_home_page_form").length>0&&a("#submit").show(),setTimeout(function(){f.load(),a(".wpacu_asset_row").removeClass("wpacu-loading"),a("#wpacu-assets-reloading").remove(),f.checkSourcesFor404Errors()},200))})}a('input[name="wpacu_sub_tab_area"]').click(function(){a(this).prop("checked")&&a("#wpacu-selected-sub-tab-area").val(a(this).val())}),a("#wpacu_minify_css_enable, #wpacu_combine_loaded_css_enable, #wpacu_minify_js_enable, #wpacu_combine_loaded_js_enable, #wpacu_cdn_rewrite_enable, #wpacu_enable_test_mode").click(function(){a(this).prop("checked")?a('[data-linked-to="'+a(this).attr("id")+'"]').find(".wpacu-circle-status").addClass("wpacu-on").removeClass("wpacu-off"):a('[data-linked-to="'+a(this).attr("id")+'"]').find(".wpacu-circle-status").addClass("wpacu-off").removeClass("wpacu-on")}),a(document).on("click","#wpacu_inline_css_files_below_size_checkbox",function(){a(this).is(":checked")?a("#wpacu_inline_css_files_enable").prop("checked",!0).trigger("tick"):""===a("#wpacu_inline_css_files_list").val()&&a("#wpacu_inline_css_files_enable").prop("checked",!1).trigger("tick")}),a(document).on("click","#wpacu_inline_js_files_below_size_checkbox",function(){if(a(this).is(":checked")){if(!confirm(wpacu_object.inline_auto_js_files_confirm_msg))return!1;a("#wpacu_inline_js_files_enable").prop("checked",!0).trigger("tick")}else""===a("#wpacu_inline_js_files_list").val()&&a("#wpacu_inline_js_files_enable").prop("checked",!1).trigger("tick")}),a("#wpacu-mark-license-valid-button").click(function(){return confirm(wpacu_object.mark_license_valid_confirm)}),a("#wpacu-license-form").submit(function(){a("#edd_license_activate_btn").attr("disabled","disabled"),a("#edd_license_deactivate_btn").attr("disabled","disabled"),a(".wpacu-license-spinner").show()});var d,e;a("#wpacu-reset-drop-down").on("change keyup keydown mouseup mousedown click",function(){""===a(this).val()?(a("#wpacu-warning-read").removeClass("wpacu-visible"),a("#wpacu-reset-submit-btn").attr("disabled","disabled").removeClass("button-primary").addClass("button-secondary")):("reset_everything"===a(this).val()?a("#wpacu-license-data-remove-area, #wpacu-cache-assets-remove-area").addClass("wpacu-visible"):a("#wpacu-license-data-remove-area, #wpacu-cache-assets-remove-area").removeClass("wpacu-visible"),a("#wpacu-warning-read").addClass("wpacu-visible"),a("#wpacu-reset-submit-btn").removeAttr("disabled").removeClass("button-secondary").addClass("button-primary")),a(".wpacu-tools-area .wpacu-warning").hide(),d=a(this).find("option:selected"),a("#"+d.attr("data-id")).show()}),a("#wpacu-reset-submit-btn").on("click",function(){if("reset_settings"===a("#wpacu-reset-drop-down").val()?e=wpacu_object.reset_settings_confirm_msg:"reset_everything_except_settings"===a("#wpacu-reset-drop-down").val()?e=wpacu_object.reset_everything_except_settings_confirm_msg:"reset_everything"===a("#wpacu-reset-drop-down").val()&&(e=wpacu_object.reset_everything_confirm_msg),!confirm(e))return!1;a("#wpacu-action-confirmed").val("yes"),setTimeout(function(){"yes"===a("#wpacu-action-confirmed").val()&&a("#wpacu-tools-form").submit()},1e3)}),a("#wpacu-import-form").submit(function(){if(!confirm(wpacu_object.import_confirm_msg))return!1;a(this).find("button").addClass("wpacu-importing").prop("disabled",!0)});var f={load:function(){var b,c,d,e=".input-unload-on-this-page.wpacu-not-locked";a(".input-unload-on-this-page").on("click change",function(e){if(b=a(this).attr("data-handle"),c=a(this).hasClass("wpacu_unload_rule_for_style")?"style":"script",a(this).prop("checked")){if("click"===e.type&&!f.triggerAlertWhenAnyUnloadRuleIsChosen(b,c))return!1;f.uncheckAllOtherBulkUnloadRules(a(this),!1),f.showHandleLoadExceptionArea(c,b),a(this).closest("tr").addClass("wpacu_not_load")}else a(this).closest("tr").removeClass("wpacu_not_load"),d=a(this).parents(".wpacu_asset_row"),f.hideHandleLoadExceptionArea(d,b,c)}),a(".wpacu-plugin-check-all").on("click",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-plugin");a('table.wpacu_list_by_location[data-wpacu-plugin="'+c+'"]').find(e).prop("checked",!0).closest("tr").addClass("wpacu_not_load")}),a(".wpacu-plugin-uncheck-all").on("click",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-plugin");a('table.wpacu_list_by_location[data-wpacu-plugin="'+c+'"]').find(e).prop("checked",!1).closest("tr").removeClass("wpacu_not_load")}),a(".wpacu-plugin-check-load-all").on("click change",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-plugin"),d=a('table.wpacu_list_by_location[data-wpacu-plugin="'+c+'"]');d.find(".wpacu_load_it_option_one.wpacu_load_exception").prop("checked",!0).closest("tr.wpacu_is_bulk_unloaded").removeClass("wpacu_not_load"),d.find(e).prop("checked",!1).trigger("change")}),a(".wpacu-plugin-uncheck-load-all").on("click change",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-plugin"),d=a('table.wpacu_list_by_location[data-wpacu-plugin="'+c+'"]');d.find(".wpacu_load_it_option_one.wpacu_load_exception").prop("checked",!1).closest("tr.wpacu_is_bulk_unloaded").addClass("wpacu_not_load"),d.find(e).prop("checked",!1).trigger("change")}),a(".wpacu_keep_bulk_rule").click(function(){a(this).prop("checked")&&a(this).parents("li").next().removeClass("remove_rule")}),a(".wpacu_remove_bulk_rule").click(function(){a(this).prop("checked")&&a(this).parents("li").addClass("remove_rule")}),a(".wpacu_bulk_unload").on("click change",function(e){b=a(this).attr("data-handle"),c=a(this).attr("data-handle-for"),d=a("[data-"+c+'-handle-row="'+b+'"]');var g=a(this).parents("li");if(a(this).prop("checked")){if("click"===e.type&&!f.triggerAlertWhenAnyUnloadRuleIsChosen(b,c))return!1;a(this).hasClass("wpacu_unload_it_regex_checkbox")?(g.find("label").addClass("wpacu_unload_checked"),g.find("textarea").prop("disabled",!1).focus().removeClass("wpacu_disabled"),g.find(".wpacu_handle_unload_regex_input_wrap").removeClass("wpacu_hide")):(a(this).parent("label").addClass("wpacu_input_load_checked"),a(this).closest("tr").addClass("wpacu_not_load")),f.showHandleLoadExceptionArea(c,b),a(this).hasClass("wpacu_global_unload")?(f.uncheckAllOtherBulkUnloadRules(a(this),!0),a('.input-unload-on-this-page[data-handle-for="'+c+'"][data-handle="'+b+'"]').prop("checked",!1)):a(this).hasClass("wpacu_post_type_unload")&&(f.uncheckAllOtherBulkUnloadRules(a(this),!1),a('.input-unload-on-this-page[data-handle-for="'+c+'"][data-handle="'+b+'"]').prop("checked",!1))}else a(this).hasClass("wpacu_unload_it_regex_checkbox")?(g.find("label").removeClass("wpacu_unload_checked"),g.find("textarea").blur().addClass("wpacu_disabled"),""===g.find("textarea").val().trim()&&(g.find("textarea").prop("disabled",!0).val(""),g.find(".wpacu_handle_unload_regex_input_wrap").addClass("wpacu_hide"))):(a(this).parent("label").removeClass("wpacu_input_load_checked"),a(this).closest("tr").removeClass("wpacu_not_load")),f.hideHandleLoadExceptionArea(d,b,c);d.hasClass("wpacu_is_bulk_unloaded")||a(".wpacu_bulk_unload:not(.wpacu_unload_it_regex_checkbox)").is(":checked")||a(this).closest("tr").removeClass("wpacu_not_load")}),a(".wpacu_load_it_option_one.wpacu_load_exception").on("click change",function(){var b=a(this).attr("data-handle");if(a(this).prop("checked")){a(this).parent("label").addClass("wpacu_global_unload_exception");var c="";a(this).hasClass("wpacu_style")?c="style":a(this).hasClass("wpacu_script")&&(c="script"),a("#"+c+"_"+b).prop("checked",!1).trigger("change")}else a(this).parent("label").removeClass("wpacu_global_unload_exception")}),a(".wpacu_load_it_option_two").on("click change",function(){var b=a(this).parents("li");a(this).prop("checked")?(b.find("label").addClass("wpacu_bold"),b.find("textarea").prop("disabled",!1).focus().removeClass("wpacu_disabled"),b.find(".wpacu_load_regex_input_wrap").removeClass("wpacu_hide")):(b.find("label").removeClass("wpacu_bold"),b.find("textarea").blur().addClass("wpacu_disabled"),""===b.find("textarea").val().trim()&&(b.find("textarea").prop("disabled",!0).val(""),b.find(".wpacu_load_regex_input_wrap").addClass("wpacu_hide")))}),a(".wpacu_script_attr_rule_input").on("click change",function(){a(this).is(":checked")&&(a(this).parents("ul").find(".wpacu_script_attr_rule_input").not(a(this)).prop("checked",!1),a(this).hasClass("wpacu_script_attr_rule_global")&&a(this).parents("ul").find(".wpacu-script-attr-make-exception").removeClass("wpacu_hide")),a(this).parents("ul").find(".wpacu_script_attr_rule_global").is(":checked")||a(this).parents("ul").find(".wpacu-script-attr-make-exception").addClass("wpacu_hide")}),a(".wpacu-add-handle-note").on("click",function(b){b.preventDefault();var c,d,e=a(this).attr("data-handle");a(this).hasClass("wpacu-for-script")?c=a('.wpacu-handle-notes-field[data-script-handle="'+e+'"]'):a(this).hasClass("wpacu-for-style")&&(c=a('.wpacu-handle-notes-field[data-style-handle="'+e+'"]')),c.length<1||(d=c.find(":input"),c.is(":hidden")?(c.show(),d.prop("disabled",!1)):(c.hide(),""===d.val().trim()&&"true"===d.attr("data-wpacu-is-empty-on-page-load")&&d.prop("disabled",!0).val("")))}),a(".wpacu-external-file-size").on("click",function(b){b.preventDefault();var c,d=a(this),e=d.attr("data-src");d.hide(),c=d.next(),c.show(),e.includes("/?")?a.get(e,{},function(a,b,d){if("success"!==b)return"N/A";c.html(wpacuBytesToSize(a.length))}):a.post(wpacu_object.ajax_url,{action:wpacu_object.plugin_id+"_get_external_file_size",wpacu_remote_file:e},function(a){c.html(a)})}),a(".wpacu_handle_row_expand_contract").on("click",function(b){b.preventDefault();var c=a(this).attr("data-wpacu-handle"),d=a(this).attr("data-wpacu-handle-for");a(this).find("span").hasClass("dashicons-minus")?(a(this).parents("td").attr("data-wpacu-row-status","contracted").find(".wpacu_handle_row_expanded_area").addClass("wpacu_hide"),a(this).find("span").removeClass("dashicons-minus").addClass("dashicons-plus"),a("#wpacu_"+d+"_"+c+"_row_contracted_area").val("1")):a(this).find("span").hasClass("dashicons-plus")&&(a(this).parents("td").attr("data-wpacu-row-status","expanded").find(".wpacu_handle_row_expanded_area").removeClass("wpacu_hide"),a(this).find("span").removeClass("dashicons-plus").addClass("dashicons-minus"),a("#wpacu_"+d+"_"+c+"_row_contracted_area").val(""))});a('[data-is-hardcoded-asset="true"]').length>0&&(a.each(a('[data-is-hardcoded-asset="true"]'),function(b,c){f.updateHardcodedDataHiddenFieldStatus(a(this))}),a('[data-is-hardcoded-asset="true"]').on("click",".wpacu_unload_rule_input",function(){f.updateHardcodedDataHiddenFieldStatus(a(this).parents("[data-is-hardcoded-asset]"))}))},updateHardcodedDataHiddenFieldStatus:function(b){var c=!1;b.is("[data-style-handle-row]")?c=b.attr("data-style-handle-row"):b.is("[data-script-handle-row]")&&(c=b.attr("data-script-handle-row")),c&&(b.find(".wpacu_unload_rule_input:checked").length>0||b.hasClass("wpacu_not_load")?a("#"+c+"_hardcoded_data").prop("disabled",!1):a("#"+c+"_hardcoded_data").prop("disabled",!0))},triggerAlertWhenAnyUnloadRuleIsChosen:function(b,c){if("dashicons"===b&&"style"===c&&a('input[name="wpacu_ignore_child[styles][nf-display]').length>0&&!confirm(wpacu_object.dashicons_unload_alert_ninja_forms))return!1;if("script"===c){if(("jquery"===b||"jquery-core"===b)&&a("#script_jquery_ignore_children").length>0&&!confirm(wpacu_object.jquery_unload_alert))return!1;if(("backbone"===b||"underscore"===b)&&!confirm(wpacu_object.sensitive_library_unload_alert))return!1}return!0},pluginLoadManager:function(){a(".wpacu_plugin_load_it").on("click",function(){var b=a(this).attr("data-wpacu-plugin-path");a(this).prop("checked")&&(f.hidePluginLoadExceptionArea(b),a('.wpacu_plugin_unload_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide"),a('.wpacu_plugin_unload_site_wide[data-wpacu-plugin-path="'+b+'"]').parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"),a('.wpacu_plugin_unload_regex_radio[data-wpacu-plugin-path="'+b+'"]').parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"))}),a(".wpacu_plugin_unload_site_wide").on("click",function(){var b=a(this).attr("data-wpacu-plugin-path");a(this).prop("checked")?(a(this).parent("label").addClass("wpacu_plugin_unload_rule_input_checked"),a('.wpacu_plugin_unload_regex_radio[data-wpacu-plugin-path="'+b+'"]').parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"),a('.wpacu_plugin_unload_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide"),f.showPluginLoadExceptionArea(b)):(a(this).parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"),a('.wrap_plugin_load_exception_options[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide").find('input[type="checkbox"]').prop("disabled",!0))}),a(".wpacu_plugin_unload_regex_radio").on("click",function(){var b=a(this).attr("data-wpacu-plugin-path");a(this).prop("checked")?(a(this).parent("label").addClass("wpacu_plugin_unload_rule_input_checked"),a('.wpacu_plugin_unload_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').removeClass("wpacu_hide"),f.showPluginLoadExceptionArea(b),a('.wpacu_plugin_unload_site_wide[data-wpacu-plugin-path="'+b+'"]').prop("checked",!1).parent("label").removeClass("wpacu_plugin_unload_rule_input_checked")):(a('.wpacu_plugin_unload_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide"),a(this).parent("label").removeClass("wpacu_plugin_unload_rule_input_checked"),a('.wrap_plugin_load_exception_options[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide"))}),a(".wpacu_plugin_load_exception_regex").on("click",function(){var b=a(this).attr("data-wpacu-plugin-path");a(this).prop("checked")?a('.wpacu_load_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').removeClass("wpacu_hide"):a('.wpacu_load_regex_input_wrap[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide")})},showPluginLoadExceptionArea:function(b){a('.wrap_plugin_load_exception_options[data-wpacu-plugin-path="'+b+'"]').removeClass("wpacu_hide").find('input[type="checkbox"]').prop("disabled",!1)},hidePluginLoadExceptionArea:function(b){a('.wrap_plugin_load_exception_options[data-wpacu-plugin-path="'+b+'"]').addClass("wpacu_hide").find('input[type="checkbox"]').prop("disabled",!0)},showHandleLoadExceptionArea:function(b,c){var d=a("div.wpacu_exception_options_area_wrap[data-"+b+'-handle="'+c+'"]');d.parent("div").removeClass("wpacu_hide"),d.find('input[type="checkbox"]').prop("disabled",!1)},hideHandleLoadExceptionArea:function(b,c,d){if(!b.hasClass("wpacu_is_bulk_unloaded")&&!b.find(".wpacu_bulk_unload").is(":checked")){var e=a("div.wpacu_exception_options_area_wrap[data-"+d+'-handle="'+c+'"]');e.parent("div").addClass("wpacu_hide"),e.find('input[type="checkbox"]').prop("disabled",!0)}},uncheckAllOtherBulkUnloadRules:function(a,b){var c=".wpacu_bulk_unload";!1===b&&(c=".wpacu_bulk_unload:not(.wpacu_unload_it_regex_checkbox)"),a.closest("tr").find(c).not(a).prop("checked",!1).parent("label").removeClass("wpacu_input_load_checked").removeClass("wpacu_unload_checked")},checkSourcesFor404Errors:function(){var b=a("[data-wpacu-external-source]");if(!(b.length<1)){var c=b.length,d="";b.each(function(b){var e=a(this),f=e.attr("data-wpacu-external-source");d+=f+"-at-wpacu-at-",b===c-1&&jQuery.post(wpacu_object.ajax_url+"?wpacu_check_external_url",{action:wpacu_object.plugin_id+"_check_external_urls_for_status_code",wpacu_check_urls:d},function(b){var c=jQuery.parseJSON(b);a.each(c,function(b,c){a('[data-wpacu-external-source="'+c+'"]').css({color:"#cc0000"}).parent("div").find("[data-wpacu-external-source-status]").html('<small>* <em style="font-weight: 600;">'+wpacu_object.source_load_error_msg+"</em></small>")})})})}}};a(window).load(function(){f.checkSourcesFor404Errors()}),a("#wpacu_post_type_select").change(function(){a("#wpacu_post_type_form").submit()}),a("#wpacu_taxonomy_select").change(function(){a("#wpacu_taxonomy_form").submit()}),a("#wpacu_dashboard").click(function(){a(this).prop("checked")?a("#wpacu-settings-assets-retrieval-mode").show():a("#wpacu-settings-assets-retrieval-mode").hide()}),a(".wpacu-dom-get-type-selection").change(function(){a(this).is(":checked")&&(a(".wpacu-dom-get-type-info").hide(),a("#"+a(this).attr("data-target")).fadeIn("fast"))}),a("#wpacu_frontend").click(function(){a(this).prop("checked")?a("#wpacu-settings-frontend-exceptions").show():a("#wpacu-settings-frontend-exceptions").hide()}),a(".google_fonts_combine_type").change(function(){a(".wpacu_google_fonts_combine_type_area").hide(),"async"===a(this).val()?a("#wpacu_google_fonts_combine_type_async_info_area").fadeIn():"async_preload"===a(this).val()?a("#wpacu_google_fonts_combine_type_async_preload_info_area").fadeIn():a("#wpacu_google_fonts_combine_type_rb_info_area").fadeIn()}),a("#wpacu_assets_list_layout").on("click change",function(){"by-location"===a(this).val()?a("#wpacu-assets-list-by-location-selected").fadeIn("fast"):a("#wpacu-assets-list-by-location-selected").fadeOut("fast")}),a("#wpacu_disable_jquery_migrate").on("click",function(){return!a(this).is(":checked")||(!(!a(this).is(":checked")||!confirm(wpacu_object.jquery_migration_disable_confirm_msg))||(a(this).prop("checked",!1),!1))}),a("#wpacu_disable_comment_reply").on("click",function(){return!a(this).is(":checked")||(!(!a(this).is(":checked")||!confirm(wpacu_object.comment_reply_disable_confirm_msg))||(a(this).prop("checked",!1),!1))}),a("[data-target-opacity]").on("click change tick",function(){a(this).prop("checked")?a("#"+a(this).attr("data-target-opacity")).css({opacity:1}):a("#"+a(this).attr("data-target-opacity")).css({opacity:.4})}),a(".wpacu-combine-loaded-js-level").change(function(){a(this).is(":checked")&&(a(".wpacu_combine_loaded_js_level_area").removeClass("wpacu_active"),a("#"+a(this).attr("data-target")).addClass("wpacu_active"))});var g=a('#wpacu-update-button-area input[type="submit"]');g.parents("form").submit(function(){g.attr("disabled",!0),a("#wpacu-updating-settings").show()});var h=a("#wpacu-update-front-settings-area .wpacu_update_btn");if(h.parents("form").submit(function(){return h.attr("disabled",!0).addClass("wpacu_submitting"),a("#wpacu-updating-front-settings").show(),!0}),a("form#wpacu-settings-form, form#wpacu_home_page_form").submit(function(){return g.attr("disabled",!0),!0}),a(".wpacu_bulk_rule_checkbox, .wpacu_remove_preload").click(function(){var b=a(this).parents(".wpacu_bulk_change_row");a(this).prop("checked")?b.addClass("wpacu_selected"):b.removeClass("wpacu_selected")}),a(".wpacu_remove_regex").click(function(){var b=a(this).parents(".wpacu_regex_rule_row");a(this).prop("checked")?b.addClass("wpacu_enabled"):b.removeClass("wpacu_enabled")}),a(".wpacu_restore_position").click(function(){var b=a(this).parents(".wpacu_restore_position_row");a(this).prop("checked")?b.addClass("wpacu_selected"):b.removeClass("wpacu_selected")}),a(".wpacu_remove_global_attr").click(function(){var b=a(this).parents(".wpacu_remove_global_attr_row");a(this).prop("checked")?b.addClass("wpacu_selected"):b.removeClass("wpacu_selected")}),a("#wpacu_wrap_assets").length>0&&setTimeout(function(){f.load()},200),a("#wpacu-plugins-load-manager-wrap").length>0&&setTimeout(function(){f.pluginLoadManager()},200),"undefined"==typeof wpacu_object||a("#wpacu_meta_box_content").length<1)return!1;("default"===wpacu_object.list_show_status||""===wpacu_object.list_show_status||wpacu_object.override_assets_list_load)&&b(),"fetch_on_click"===wpacu_object.list_show_status&&a("#wpacu_ajax_fetch_on_click_btn").click(function(c){c.preventDefault(),a(this).hide(),a("#wpacu_fetching_assets_list_wrap").show(),b()}),a(document).on("click",".wp-admin.post-php .edit-post-header__settings button.is-primary",function(){var c=function(){if(0===a(".edit-post-header__settings .is-saving").length){if(a("#wpacu_unload_assets_area_loaded").length>0&&a("#wpacu_unload_assets_area_loaded").val()){a("#wpacu-assets-reloading").remove();var c='<span id="wpacu-assets-reloading" class="editor-post-saved-state is-wpacu-reloading">'+wpacu_object.reload_icon+wpacu_object.reload_msg+"</span>";a(".wp-admin.post-php .edit-post-header__settings").prepend(c)}a(".wpacu_asset_row").addClass("wpacu-loading"),b(),wpacuAjaxClearCache(),clearInterval(d)}},d=setInterval(c,900)})}),""!==wpacu_object.clear_cache_on_page_load&&wpacuAjaxClearCache(),""!==wpacu_object.clear_other_caches&&setTimeout(function(){wpacuClearAutoptimizeCache()},150),jQuery(document).ready(function(a){try{var b;a('input[type="hidden"][name="_wp_http_referer"]').length>0&&(b=a('input[type="hidden"][name="_wp_http_referer"]').val(),b.includes("term.php?taxonomy=")&&b.includes("message=")&&wpacuAjaxClearCache(),b.includes("post.php?post=")&&b.includes("message=")&&wpacuAjaxClearCache())}catch(a){console.log(a)}});
classes/CleanUp.php CHANGED
@@ -1,6 +1,8 @@
1
<?php
2
namespace WpAssetCleanUp;
3
4
/**
5
* Class CleanUp
6
* @package WpAssetCleanUp
@@ -23,7 +25,7 @@ class CleanUp
23
*/
24
public function doClean()
25
{
26
- if (Main::instance()->preventAssetsSettings()) {
27
return;
28
}
29
@@ -45,6 +47,10 @@ class CleanUp
45
if ($settings['remove_rest_api_link'] == 1) {
46
// <link rel='https://api.w.org/' href='https://yourwebsite.com/wp-json/' />
47
remove_action('wp_head', 'rest_output_link_wp_head');
48
}
49
50
// Remove "Shortlink"?
@@ -54,8 +60,7 @@ class CleanUp
54
55
// link: <https://yourdomainname.com/wp-json/>; rel="https://api.w.org/", <https://yourdomainname.com/?p=[post_id_here]>; rel=shortlink
56
remove_action('template_redirect', 'wp_shortlink_header', 11);
57
-
58
- }
59
60
// Remove "Post's Relational Links"?
61
if ($settings['remove_posts_rel_links'] == 1) {
@@ -143,105 +148,128 @@ class CleanUp
143
*/
144
public static function removeMetaGenerators($htmlSource)
145
{
146
- if (stripos($htmlSource, '<meta') === false) {
147
- return $htmlSource;
148
- }
149
150
- // Use DOMDocument to alter the HTML Source and Remove the tags
151
- $htmlSourceOriginal = $htmlSource;
152
153
- if (function_exists('libxml_use_internal_errors')
154
- && function_exists('libxml_clear_errors')
155
- && class_exists('DOMDocument'))
156
- {
157
- $document = new \DOMDocument();
158
- libxml_use_internal_errors(true);
159
160
- $document->loadHTML($htmlSource);
161
162
- $domUpdated = false;
163
164
- foreach ($document->getElementsByTagName('meta') as $tagObject) {
165
- $nameAttrValue = $tagObject->getAttribute('name');
166
167
- if ($nameAttrValue === 'generator') {
168
- $outerTag = $outerTagRegExp = trim(self::getOuterHTML($tagObject));
169
170
- // As DOMDocument doesn't retrieve the exact string, some alterations to the RegEx have to be made
171
- // Leave no room for errors as all sort of characters can be within the "content" attribute
172
- $last2Chars = substr($outerTag, -2);
173
174
- if ($last2Chars === '">' || $last2Chars === "'>") {
175
- $tagWithoutLastChar = substr($outerTag, 0, -1);
176
- $outerTagRegExp = preg_quote($tagWithoutLastChar, '/').'(.*?)>';
177
- }
178
179
- $outerTagRegExp = str_replace(
180
- array('"', '&lt;', '&gt;'),
181
- array('(["\'])', '(<|&lt;)', '(>|&gt;)'),
182
- $outerTagRegExp
183
- );
184
185
- if (strpos($outerTagRegExp, '<meta') !== false) {
186
- preg_match_all('#' . $outerTagRegExp . '#si', $htmlSource, $matches);
187
188
- if (isset($matches[0][0]) && ! empty($matches[0][0]) && strip_tags($matches[0][0]) === '') {
189
- $htmlSource = str_replace( $matches[0][0], '', $htmlSource );
190
}
191
192
- if ($htmlSource !== $htmlSourceOriginal) {
193
- $domUpdated = true;
194
}
195
}
196
}
197
- }
198
-
199
- libxml_clear_errors();
200
-
201
- if ($domUpdated) {
202
- return $htmlSource;
203
- }
204
- }
205
206
- // DOMDocument is not enabled. Use the RegExp instead (not as smooth, but does its job)!
207
- preg_match_all('#<meta[^>]*name(\s+|)=(\s+|)("|\')generator("|\').*("|\'|\/)(\s+|)>#Usmi', $htmlSource, $matches);
208
209
- if (isset($matches[0]) && ! empty($matches[0])) {
210
- foreach ($matches[0] as $metaTag) {
211
- if (strip_tags($metaTag) === '') { // make sure the full tag was extracted
212
- $htmlSource = str_replace($metaTag, '', $htmlSource);
213
- }
214
}
215
}
216
217
return $htmlSource;
218
}
219
220
/**
221
* @param $htmlSource
222
*
223
- * @return mixed
224
*/
225
- public static function removeHtmlComments($htmlSource)
226
{
227
// No comments? Do not continue
228
if (strpos($htmlSource, '<!--') === false) {
229
return $htmlSource;
230
}
231
232
- if (! (function_exists('libxml_use_internal_errors')
233
- && function_exists('libxml_clear_errors')
234
- && class_exists('DOMDocument')))
235
- {
236
return $htmlSource;
237
}
238
239
- $domComments = new \DOMDocument();
240
- libxml_use_internal_errors(true);
241
242
- $domComments->loadHTML($htmlSource);
243
244
- $xpathComments = new \DOMXPath($domComments);
245
$comments = $xpathComments->query('//comment()');
246
247
libxml_clear_errors();
@@ -278,18 +306,21 @@ class CleanUp
278
}
279
}
280
281
foreach ($comments as $comment) {
282
- $entireComment = self::getOuterHTML($comment);
283
284
// Do not strip MSIE conditional comments
285
- if (strpos($entireComment, '<!--<![endif]-->') !== false ||
286
- preg_match('#<!--\[if(.*?)]>(.*?)<!-->#si', $entireComment) ||
287
- preg_match('#<!--\[if(.*?)\[endif]-->#si', $entireComment)) {
288
continue;
289
}
290
291
// Any exceptions set in "Strip HTML comments?" textarea?
292
- if (Main::instance()->settings['remove_html_comments_exceptions']) {
293
$removeHtmlCommentsExceptions = trim(Main::instance()->settings['remove_html_comments_exceptions']);
294
295
if (strpos($removeHtmlCommentsExceptions, "\n") !== false) {
@@ -305,14 +336,15 @@ class CleanUp
305
}
306
}
307
308
- $htmlSource = str_replace(
309
- array(
310
- $entireComment,
311
- '<!--' . $comment->nodeValue . '-->'
312
- ),
313
- '',
314
- $htmlSource
315
- );
316
}
317
318
if (! empty($commentsWithinQuotes)) {
@@ -332,7 +364,6 @@ class CleanUp
332
public static function getOuterHTML($e)
333
{
334
$doc = new \DOMDocument();
335
-
336
libxml_use_internal_errors( true );
337
338
$doc->appendChild($doc->importNode($e, true));
1
<?php
2
namespace WpAssetCleanUp;
3
4
+ use WpAssetCleanUp\OptimiseAssets\OptimizeCommon;
5
+
6
/**
7
* Class CleanUp
8
* @package WpAssetCleanUp
25
*/
26
public function doClean()
27
{
28
+ if (Plugin::preventAnyChanges() || Main::instance()->preventAssetsSettings()) {
29
return;
30
}
31
47
if ($settings['remove_rest_api_link'] == 1) {
48
// <link rel='https://api.w.org/' href='https://yourwebsite.com/wp-json/' />
49
remove_action('wp_head', 'rest_output_link_wp_head');
50
+
51
+ // Removes the following printed within "Response headers":
52
+ // <https://yourwebsite.com/wp-json/>; rel="https://api.w.org/"
53
+ remove_action( 'template_redirect', 'rest_output_link_header', 11 );
54
}
55
56
// Remove "Shortlink"?
60
61
// link: <https://yourdomainname.com/wp-json/>; rel="https://api.w.org/", <https://yourdomainname.com/?p=[post_id_here]>; rel=shortlink
62
remove_action('template_redirect', 'wp_shortlink_header', 11);
63
+ }
64
65
// Remove "Post's Relational Links"?
66
if ($settings['remove_posts_rel_links'] == 1) {
148
*/
149
public static function removeMetaGenerators($htmlSource)
150
{
151
+ $fetchMethod = 'dom'; // 'regex' or 'dom'
152
+
153
+ if ($fetchMethod === 'regex') {
154
+ preg_match_all(
155
+ '/<meta.*name=(|\'|")generator(\\1).*content=(|\'|")(.*?)(|\'|").*?>/i',
156
+ $htmlSource,
157
+ $matchesSourcesFromTags,
158
+ PREG_SET_ORDER
159
+ );
160
161
+ preg_match_all(
162
+ '/<meta.*content=(|\'|")(.*?)(\\1).*name=(|\'|")generator(\\2).*?>/i',
163
+ $htmlSource,
164
+ $matchesSourcesFromTagsTwo,
165
+ PREG_SET_ORDER
166
+ );
167
168
+ $matchesSourcesFromTags = array_merge($matchesSourcesFromTags, $matchesSourcesFromTagsTwo);
169
170
+ if (empty($matchesSourcesFromTags)) {
171
+ return $htmlSource;
172
+ }
173
174
+ $metaTagsToStrip = array();
175
176
+ foreach ($matchesSourcesFromTags as $matchesResults) {
177
+ if (isset($matchesResults[0]) && ($matchedTag = $matchesResults[0])) {
178
+ if (strip_tags($matchedTag) !== '') { // Needs to be a proper match (very rare cases, but it can happen)
179
+ continue;
180
+ }
181
182
+ $metaTagsToStrip[$matchedTag] = '';
183
+ }
184
+ }
185
186
+ $htmlSource = strtr($htmlSource, $metaTagsToStrip);
187
+ } elseif ($fetchMethod === 'dom') {
188
+ if ( function_exists( 'libxml_use_internal_errors' ) && function_exists( 'libxml_clear_errors' ) && class_exists( '\DOMDocument' ) ) {
189
+ if ($htmlSource === '') {
190
+ return $htmlSource;
191
+ }
192
193
+ $domTag = OptimizeCommon::getDomLoadedTag($htmlSource, 'removeMetaGenerators');
194
195
+ $metaTagsToStrip = array();
196
+
197
+ foreach ( $domTag->getElementsByTagName( 'meta' ) as $tagObject ) {
198
+ $nameAttrValue = $tagObject->getAttribute( 'name' );
199
+
200
+ if ( $nameAttrValue === 'generator' ) {
201
+ $outerTag = $outerTagRegExp = trim( self::getOuterHTML( $tagObject ) );
202
203
+ // As DOMDocument doesn't retrieve the exact string, some alterations to the RegEx have to be made
204
+ // Leave no room for errors as all sort of characters can be within the "content" attribute
205
+ $last2Chars = substr( $outerTag, - 2 );
206
207
+ if ( $last2Chars === '">' || $last2Chars === "'>" ) {
208
+ $tagWithoutLastChar = substr( $outerTag, 0, - 1 );
209
+ $outerTagRegExp = preg_quote( $tagWithoutLastChar, '/' ) . '(.*?)>';
210
}
211
212
+ $outerTagRegExp = str_replace(
213
+ array( '"', '&lt;', '&gt;' ),
214
+ array( '("|\'|)', '(<|&lt;)', '(>|&gt;)' ),
215
+ $outerTagRegExp
216
+ );
217
+
218
+ if ( strpos( $outerTagRegExp, '<meta' ) !== false ) {
219
+ preg_match_all( '#' . $outerTagRegExp . '#si', $htmlSource, $matches );
220
+
221
+ if ( isset( $matches[0][0] ) && ! empty( $matches[0][0] ) && strip_tags( $matches[0][0] ) === '' ) {
222
+ $metaTagsToStrip[$matches[0][0]] = '';
223
+ }
224
}
225
}
226
}
227
228
+ $htmlSource = strtr($htmlSource, $metaTagsToStrip);
229
230
+ libxml_clear_errors();
231
}
232
}
233
234
+ /* [wpacu_timing] */
235
+ Misc::scriptExecTimer( 'alter_html_source_for_remove_meta_generators',
236
+ 'end' ); /* [/wpacu_timing] */
237
return $htmlSource;
238
}
239
240
/**
241
* @param $htmlSource
242
+ * @param bool $ignoreExceptions
243
+ * @param $for
244
*
245
+ * @return string|string[]
246
*/
247
+ public static function removeHtmlComments($htmlSource, $ignoreExceptions = false, $for = 'cleaner_dom_to_fetch')
248
{
249
// No comments? Do not continue
250
if (strpos($htmlSource, '<!--') === false) {
251
return $htmlSource;
252
}
253
254
+ if (! (function_exists('libxml_use_internal_errors') && function_exists('libxml_clear_errors') && class_exists('\DOMDocument'))) {
255
return $htmlSource;
256
}
257
258
+ $domTag = '';
259
+
260
+ if ($for === 'cleaner_dom_to_fetch') {
261
+ $domTag = OptimizeCommon::getDomLoadedTag($htmlSource, 'removeHtmlComments');
262
+ }
263
+
264
+ if ($for === 'final_output') {
265
+ $domTag = OptimizeCommon::getDomLoadedTag($htmlSource, 'removeHtmlCommentsFinal');
266
+ }
267
268
+ if (! $domTag) {
269
+ return $htmlSource;
270
+ }
271
272
+ $xpathComments = new \DOMXPath($domTag);
273
$comments = $xpathComments->query('//comment()');
274
275
libxml_clear_errors();
306
}
307
}
308
309
+ $stripCommentsList = array();
310
+
311
foreach ($comments as $comment) {
312
+ $entireComment = '<!--' . $comment->nodeValue . '-->';
313
314
// Do not strip MSIE conditional comments
315
+ if ( strpos( $entireComment, '<!--<![endif]-->' ) !== false ||
316
+ preg_match( '#<!--\[if(.*?)]>(.*?)<!-->#si', $entireComment ) ||
317
+ preg_match( '#<!--\[if(.*?)\[endif]-->#si', $entireComment ) ) {
318
continue;
319
}
320
321
// Any exceptions set in "Strip HTML comments?" textarea?
322
+ // $ignoreExceptions has to be set to false (as it is by default)
323
+ if (! $ignoreExceptions && Main::instance()->settings['remove_html_comments_exceptions']) {
324
$removeHtmlCommentsExceptions = trim(Main::instance()->settings['remove_html_comments_exceptions']);
325
326
if (strpos($removeHtmlCommentsExceptions, "\n") !== false) {
336
}
337
}
338
339
+ if (strlen($entireComment) < 200) {
340
+ $stripCommentsList[ $entireComment ] = '';
341
+ } else {
342
+ $htmlSource = str_replace($entireComment, '', $htmlSource);
343
+ }
344
+ }
345
+
346
+ if (! empty($stripCommentsList)) {
347
+ $htmlSource = strtr( $htmlSource, $stripCommentsList );
348
}
349
350
if (! empty($commentsWithinQuotes)) {
364
public static function getOuterHTML($e)
365
{
366
$doc = new \DOMDocument();
367
libxml_use_internal_errors( true );
368
369
$doc->appendChild($doc->importNode($e, true));
classes/Debug.php CHANGED
@@ -18,11 +18,13 @@ class Debug
18
add_action('wp_footer', array($this, 'showDebugOptions'), PHP_INT_MAX);
19
}
20
21
- add_action('wp', static function() {
22
- if ( isset( $_GET['wpacu_get_cache_dir_size'] ) && Menu::userCanManageAssets() ) { // Only print within the Dashboard
23
- self::printCacheDirInfo();
24
- }
25
- });
26
}
27
28
/**
@@ -178,9 +180,7 @@ class Debug
178
<li>From CSS file to Inline: {wpacu_alter_html_source_for_inline_css_exec_time}</li>
179
<li>Update Original to Optimized: {wpacu_alter_html_source_original_to_optimized_css_exec_time}</li>
180
<li>Preloads: {wpacu_alter_html_source_for_preload_css_exec_time}</li>
181
- <!-- removeIf(development) -->
182
- <!--<li>Dynamic Loaded CSS (if any): {wpacu_alter_html_source_for_dynamic_loaded_css_exec_time}</li>-->
183
- <!-- endRemoveIf(development) -->
184
<li>Combine: {wpacu_alter_html_source_for_combine_css_exec_time}</li>
185
<li>Minify Inline Tags: {wpacu_alter_html_source_for_minify_inline_style_tags_exec_time}</li>
186
<li>Unload (ignore dependencies): {wpacu_alter_html_source_unload_ignore_deps_css_exec_time}</li>
@@ -191,9 +191,7 @@ class Debug
191
<ul>
192
<li>Update Original to Optimized: {wpacu_alter_html_source_original_to_optimized_js_exec_time}</li>
193
<li>Preloads: {wpacu_alter_html_source_for_preload_js_exec_time}</li>
194
- <!-- removeIf(development) -->
195
- <!--<li>Dynamic Loaded JS (if any): {wpacu_alter_html_source_for_dynamic_loaded_js_exec_time}</li>-->
196
- <!-- endRemoveIf(development) -->
197
<li>Combine: {wpacu_alter_html_source_for_combine_js_exec_time}</li>
198
<li>Unload (ignore dependencies): {wpacu_alter_html_source_unload_ignore_deps_js_exec_time}</li>
199
<li>Move any inline wih jQuery code after jQuery library: {wpacu_alter_html_source_move_inline_jquery_after_src_tag_exec_time}</li>
18
add_action('wp_footer', array($this, 'showDebugOptions'), PHP_INT_MAX);
19
}
20
21
+ foreach(array('wp', 'admin_init') as $wpacuActionHook) {
22
+ add_action( $wpacuActionHook, static function() {
23
+ if ( isset( $_GET['wpacu_get_cache_dir_size'] ) && Menu::userCanManageAssets() ) {
24
+ self::printCacheDirInfo();
25
+ }
26
+ });
27
+ }
28
}
29
30
/**
180
<li>From CSS file to Inline: {wpacu_alter_html_source_for_inline_css_exec_time}</li>
181
<li>Update Original to Optimized: {wpacu_alter_html_source_original_to_optimized_css_exec_time}</li>
182
<li>Preloads: {wpacu_alter_html_source_for_preload_css_exec_time}</li>
183
+ <!-- -->
184
<li>Combine: {wpacu_alter_html_source_for_combine_css_exec_time}</li>
185
<li>Minify Inline Tags: {wpacu_alter_html_source_for_minify_inline_style_tags_exec_time}</li>
186
<li>Unload (ignore dependencies): {wpacu_alter_html_source_unload_ignore_deps_css_exec_time}</li>
191
<ul>
192
<li>Update Original to Optimized: {wpacu_alter_html_source_original_to_optimized_js_exec_time}</li>
193
<li>Preloads: {wpacu_alter_html_source_for_preload_js_exec_time}</li>
194
+ <!-- -->
195
<li>Combine: {wpacu_alter_html_source_for_combine_js_exec_time}</li>
196
<li>Unload (ignore dependencies): {wpacu_alter_html_source_unload_ignore_deps_js_exec_time}</li>
197
<li>Move any inline wih jQuery code after jQuery library: {wpacu_alter_html_source_move_inline_jquery_after_src_tag_exec_time}</li>
classes/HardcodedAssets.php CHANGED
@@ -1,7 +1,6 @@
1
<?php
2
namespace WpAssetCleanUp;
3
4
- use WpAssetCleanUp\OptimiseAssets\MinifyJs;
5
use WpAssetCleanUp\OptimiseAssets\OptimizeCommon;
6
use WpAssetCleanUp\OptimiseAssets\OptimizeJs;
7
@@ -83,7 +82,7 @@ class HardcodedAssets
83
*/
84
public static function addHardcodedAssetsForEditFrontEndView($htmlSource)
85
{
86
- if ( ! ($anyHardCodedAssets = wp_cache_get('wpacu_hardcoded_assets_encoded')) ) {
87
$htmlSource = str_replace( '{wpacu_assets_collapsible_wrap_hardcoded_list}', '', $htmlSource);
88
return $htmlSource;
89
}
@@ -91,7 +90,7 @@ class HardcodedAssets
91
$jsonH = base64_decode($anyHardCodedAssets);
92
93
$wpacuPrintHardcodedManagementList = static function($jsonH) {
94
- $data = wp_cache_get('wpacu_settings_frontend_data') ?: array();
95
$data['do_not_print_list'] = true;
96
$data['all']['hardcoded'] = (array)json_decode($jsonH, ARRAY_A);
97
ob_start();
@@ -126,7 +125,7 @@ class HardcodedAssets
126
*/
127
public static function getAll($htmlSource, $encodeIt = true)
128
{
129
- $htmlSourceAlt = self::removeHtmlCommentsExceptMSIE($htmlSource);
130
131
$collectLinkStyles = true; // default
132
$collectScripts = true; // default
@@ -140,7 +139,6 @@ class HardcodedAssets
140
/*
141
* [START] Collect Hardcoded LINK (stylesheet) & STYLE tags
142
*/
143
- // Extract all the LINK tag that do not have "data-wpacu-debug-style-handle="
144
preg_match_all( '#(?=(?P<link_tag><link[^>]*stylesheet[^>]*(>)))|(?=(?P<style_tag><style[^>]*?>.*</style>))#Umsi',
145
$htmlSourceAlt, $matchesSourcesFromTags, PREG_SET_ORDER );
146
@@ -246,7 +244,6 @@ class HardcodedAssets
246
}
247
248
$allInlineAssocWithJsHandle = array_unique($allInlineAssocWithJsHandle);
249
-
250
}
251
252
// Go through the hardcoded SCRIPT tags
@@ -370,7 +367,7 @@ class HardcodedAssets
370
371
if (self::useBufferingForEditFrontEndView()) {
372
// Triggered within the front-end view (when admin is logged-in and manages the assets)
373
- wp_cache_set( 'wpacu_hardcoded_content_within_conditional_comments', $tagsWithinConditionalComments );
374
} elseif (Main::instance()->isGetAssetsCall) {
375
// AJAX call within the Dashboard
376
$hardCodedAssets['within_conditional_comments'] = $tagsWithinConditionalComments;
@@ -388,6 +385,7 @@ class HardcodedAssets
388
*
389
* @return mixed
390
*/
391
public static function removeHtmlCommentsExceptMSIE($htmlSource)
392
{
393
// No comments? Do not continue
@@ -395,29 +393,28 @@ class HardcodedAssets
395
return $htmlSource;
396
}
397
398
- if (! (function_exists('libxml_use_internal_errors')
399
- && function_exists('libxml_clear_errors')
400
- && class_exists('DOMDocument')))
401
- {
402
return $htmlSource;
403
}
404
405
- $domComments = new \DOMDocument();
406
- libxml_use_internal_errors(true);
407
-
408
preg_match_all('#<!--\[if(.*?)]>(<!-->|-->|\s|)(.*?)(<!--<!|<!)\[endif]-->#si', $htmlSource, $matchedMSIEComments);
409
410
- $htmlSourceAlt = $htmlSource;
411
412
if (isset($matchedMSIEComments[0]) && ! empty($matchedMSIEComments[0])) {
413
foreach ($matchedMSIEComments[0] as $matchedMSIEComment) {
414
- $htmlSourceAlt = str_replace($matchedMSIEComment, '', $htmlSourceAlt);
415
}
416
}
417
418
- $domComments->loadHTML($htmlSourceAlt); // fetch from the altered HTML (without the MSIE comments)
419
420
- $xpathComments = new \DOMXPath($domComments);
421
$comments = $xpathComments->query('//comment()');
422
423
libxml_clear_errors();
@@ -475,6 +472,8 @@ class HardcodedAssets
475
476
return $htmlSource;
477
}
478
479
/**
480
* @param $htmlSource
1
<?php
2
namespace WpAssetCleanUp;
3
4
use WpAssetCleanUp\OptimiseAssets\OptimizeCommon;
5
use WpAssetCleanUp\OptimiseAssets\OptimizeJs;
6
82
*/
83
public static function addHardcodedAssetsForEditFrontEndView($htmlSource)
84
{
85
+ if ( ! ($anyHardCodedAssets = ObjectCache::wpacu_cache_get('wpacu_hardcoded_assets_encoded')) ) {
86
$htmlSource = str_replace( '{wpacu_assets_collapsible_wrap_hardcoded_list}', '', $htmlSource);
87
return $htmlSource;
88
}
90
$jsonH = base64_decode($anyHardCodedAssets);
91
92
$wpacuPrintHardcodedManagementList = static function($jsonH) {
93
+ $data = ObjectCache::wpacu_cache_get('wpacu_settings_frontend_data') ?: array();
94
$data['do_not_print_list'] = true;
95
$data['all']['hardcoded'] = (array)json_decode($jsonH, ARRAY_A);
96
ob_start();
125
*/
126
public static function getAll($htmlSource, $encodeIt = true)
127
{
128
+ $htmlSourceAlt = CleanUp::removeHtmlComments($htmlSource, true);
129
130
$collectLinkStyles = true; // default
131
$collectScripts = true; // default
139
/*
140
* [START] Collect Hardcoded LINK (stylesheet) & STYLE tags
141
*/
142
preg_match_all( '#(?=(?P<link_tag><link[^>]*stylesheet[^>]*(>)))|(?=(?P<style_tag><style[^>]*?>.*</style>))#Umsi',
143
$htmlSourceAlt, $matchesSourcesFromTags, PREG_SET_ORDER );
144
244
}
245
246
$allInlineAssocWithJsHandle = array_unique($allInlineAssocWithJsHandle);
247
}
248
249
// Go through the hardcoded SCRIPT tags
367
368
if (self::useBufferingForEditFrontEndView()) {
369
// Triggered within the front-end view (when admin is logged-in and manages the assets)
370
+ ObjectCache::wpacu_cache_set( 'wpacu_hardcoded_content_within_conditional_comments', $tagsWithinConditionalComments );
371
} elseif (Main::instance()->isGetAssetsCall) {
372
// AJAX call within the Dashboard
373
$hardCodedAssets['within_conditional_comments'] = $tagsWithinConditionalComments;
385
*
386
* @return mixed
387
*/
388
+ /*
389
public static function removeHtmlCommentsExceptMSIE($htmlSource)
390
{
391
// No comments? Do not continue
393
return $htmlSource;
394
}
395
396
+ if (! (function_exists('libxml_use_internal_errors') && function_exists('libxml_clear_errors') && class_exists('\DOMDocument'))) {
397
return $htmlSource;
398
}
399
400
+ // First, collect all MSIE comments
401
preg_match_all('#<!--\[if(.*?)]>(<!-->|-->|\s|)(.*?)(<!--<!|<!)\[endif]-->#si', $htmlSource, $matchedMSIEComments);
402
403
+ $allMSIEComments = array();
404
405
if (isset($matchedMSIEComments[0]) && ! empty($matchedMSIEComments[0])) {
406
foreach ($matchedMSIEComments[0] as $matchedMSIEComment) {
407
+ $allMSIEComments[] = $matchedMSIEComment;
408
}
409
}
410
411
+ if (! ($domTag = ObjectCache::wpacu_cache_get('wpacu_html_dom_tag'))) {
412
+ $domTag = new \DOMDocument();
413
+ libxml_use_internal_errors( true );
414
+ $domTag->loadHTML( $htmlSource );
415
+ }
416
417
+ $xpathComments = new \DOMXPath($domTag);
418
$comments = $xpathComments->query('//comment()');
419
420
libxml_clear_errors();
472
473
return $htmlSource;
474
}
475
+ */
476
+ //endRemoveIf(development)
477
478
/**
479
* @param $htmlSource
classes/ImportExport.php CHANGED
@@ -265,7 +265,7 @@ SQL;
265
266
if (! empty($importedList)) {
267
// After import was completed, clear all CSS/JS cache
268
- OptimizeCommon::clearAllCache();
269
270
set_transient('wpacu_import_done', json_encode($importedList), 30);
271
265
266
if (! empty($importedList)) {
267
// After import was completed, clear all CSS/JS cache
268
+ OptimizeCommon::clearCache();
269
270
set_transient('wpacu_import_done', json_encode($importedList), 30);
271
classes/Main.php CHANGED
@@ -258,7 +258,7 @@ class Main
258
// "Direct" AJAX call or "WP Remote Post" method used?
259
// Do not trigger the admin bar as it's not relevant
260
if ($this->isAjaxCall || $this->isGetAssetsCall) {
261
- Misc::noAdminBarLoad();
262
}
263
264
// This is triggered AFTER "saveSettings" from 'Settings' class
@@ -315,6 +315,10 @@ class Main
315
);
316
}
317
318
// Alter for debugging purposes; triggers before anything else
319
// e.g. you're working on a website and there is no Dashboard access and you want to determine the handle name
320
// if the handle name is not showing up, then the LINK stylesheet has been hardcoded (not enqueued the WordPress way)
@@ -322,25 +326,15 @@ class Main
322
$styleTag = str_replace('<link ', '<link data-wpacu-debug-style-handle=\'' . $tagHandle . '\' ', $styleTag);
323
}
324
325
- if (strpos($styleTag, 'data-wpacu-style-handle') === false
326
- && Menu::userCanManageAssets()
327
- && self::instance()->isFrontendEditView) {
328
- $styleTag = str_replace('<script ', '<script data-wpacu-style-handle=\'' . $tagHandle . '\' ', $styleTag);
329
}
330
331
- if ( Plugin::preventAnyChanges() || self::isTestModeActive() ) {
332
- return $styleTag;
333
- }
334
-
335
- if (strpos($styleTag, 'data-wpacu-style-handle') === false) {
336
- $styleTag = str_replace( '<link ', '<link data-wpacu-style-handle=\'' . $tagHandle . '\' ', $styleTag );
337
- }
338
-
339
- return $styleTag;
340
}, 10, 2);
341
342
add_filter('script_loader_tag', static function($scriptTag, $tagHandle) {
343
- // Alter for debugging purposes; triggers before anything else
344
// e.g. you're working on a website and there is no Dashboard access and you want to determine the handle name
345
// if the handle name is not showing up, then the SCRIPT has been hardcoded (not enqueued the WordPress way)
346
if (array_key_exists('wpacu_show_handle_names', $_GET)) {
@@ -369,7 +363,7 @@ class Main
369
$scriptTag = str_replace('<script ', '<script data-wpacu-jquery-migrate-handle=1 ', $scriptTag);
370
}
371
372
- return $scriptTag;
373
}, 10, 2);
374
375
Preloads::instance()->init();
@@ -427,7 +421,7 @@ SQL;
427
// Fetch the page in the background to see what scripts/styles are already loading
428
if ($this->isGetAssetsCall || $this->frontendShow()) {
429
if ($this->isGetAssetsCall) {
430
- Misc::noAdminBarLoad();
431
}
432
433
// Save CSS handles list that is printed in the <HEAD>
@@ -577,21 +571,21 @@ SQL;
577
global $wp_styles;
578
579
if (current_action() === 'wp_print_styles') {
580
- wp_cache_set('wpacu_styles_object_after_wp_print_styles', $wp_styles);
581
}
582
583
$list = array();
584
585
if (current_action() === 'wp_print_footer_scripts') {
586
- $cachedWpStyles = wp_cache_get('wpacu_styles_object_after_wp_print_styles');
587
if (isset($cachedWpStyles->registered) && count($cachedWpStyles->registered) === count($wp_styles->registered)) {
588
// The list was already generated in "wp_print_styles" and the number of registered assets are the same
589
// Save resources and do not re-generate it
590
- $list = wp_cache_get('wpacu_styles_handles_marked_for_unload');
591
}
592
}
593
594
- if ( empty($list) ) {
595
// [wpacu_lite]
596
$nonAssetConfigPage = ( ! $this->isUpdateable && ! Misc::getShowOnFront() );
597
// [/wpacu_lite]
@@ -616,6 +610,10 @@ SQL;
616
$list = (array) $jsonList->styles;
617
}
618
619
// Any global unloaded styles? Append them
620
if ( ! empty( $globalUnload['styles'] ) ) {
621
foreach ( $globalUnload['styles'] as $handleStyle ) {
@@ -672,7 +670,7 @@ SQL;
672
}
673
674
if ( isset( $this->wpAllStyles['registered'] ) && ! empty( $this->wpAllStyles['registered'] ) ) {
675
- wp_cache_set( 'wpacu_all_styles_handles', array_keys( $this->wpAllStyles['registered'] ) );
676
}
677
678
// e.g. for test/debug mode or AJAX calls (where all assets have to load)
@@ -728,7 +726,8 @@ SQL;
728
$handle = trim($handle);
729
730
// Ignore auto generated handles for the hardcoded CSS as they were added for reference purposes
731
- if (strpos($handle, 'wpacu_hardcoded_link_') === 0) {
732
continue;
733
}
734
@@ -746,7 +745,7 @@ SQL;
746
}
747
748
if (current_action() === 'wp_print_styles') {
749
- wp_cache_set( 'wpacu_styles_handles_marked_for_unload', $list );
750
}
751
752
/* [wpacu_timing] */ Misc::scriptExecTimer( 'filter_dequeue_styles', 'end' ); /* [/wpacu_timing] */
@@ -862,17 +861,17 @@ SQL;
862
global $wp_scripts;
863
864
if (current_action() === 'wp_print_scripts') {
865
- wp_cache_set('wpacu_scripts_object_after_wp_print_scripts', $wp_scripts);
866
}
867
868
$list = array();
869
870
if (current_action() === 'wp_print_footer_scripts') {
871
- $cachedWpScripts = wp_cache_get('wpacu_scripts_object_after_wp_print_scripts');
872
if (isset($cachedWpScripts->registered) && count($cachedWpScripts->registered) === count($wp_scripts->registered)) {
873
// The list was already generated in "wp_print_scripts" and the number of registered assets are the same
874
// Save resources and do not re-generate it
875
- $list = wp_cache_get('wpacu_scripts_handles_marked_for_unload');
876
}
877
}
878
@@ -983,7 +982,6 @@ SQL;
983
if ( empty( $list ) ) {
984
/* [wpacu_timing] */
985
Misc::scriptExecTimer( 'filter_dequeue_scripts', 'end' ); /* [/wpacu_timing] */
986
-
987
return;
988
}
989
@@ -991,7 +989,6 @@ SQL;
991
if ( array_key_exists( 'wpacu_no_js_unload', $_GET ) || $this->preventAssetsSettings() ) {
992
/* [wpacu_timing] */
993
Misc::scriptExecTimer( 'filter_dequeue_scripts', 'end' ); /* [/wpacu_timing] */
994
-
995
return;
996
}
997
}
@@ -1001,6 +998,10 @@ SQL;
1001
foreach ($list as $handle) {
1002
$handle = trim($handle);
1003
1004
// Special Action for 'jquery-migrate' handler as its tied to 'jquery'
1005
if ($handle === 'jquery-migrate' && isset($this->wpAllScripts['registered']['jquery'])) {
1006
$jQueryRegScript = $this->wpAllScripts['registered']['jquery'];
@@ -1016,10 +1017,6 @@ SQL;
1016
continue;
1017
}
1018
1019
- if (array_key_exists('wpacu_debug', $_GET)) {
1020
- $this->allUnloadedAssets['js'][] = $handle;
1021
- }
1022
-
1023
if (isset($ignoreChildParentList['scripts'], $this->wpAllScripts['registered'][$handle]->src) && is_array($ignoreChildParentList['scripts']) && array_key_exists($handle, $ignoreChildParentList['scripts'])) {
1024
// Do not dequeue it as it's "children" will also be dequeued (ignore rule is applied)
1025
// It will be stripped by cleaning its SCRIPT tag from the HTML Source
@@ -1042,7 +1039,7 @@ SQL;
1042
}
1043
1044
if (current_action() === 'wp_print_scripts') {
1045
- wp_cache_set( 'wpacu_scripts_handles_marked_for_unload', $list );
1046
}
1047
1048
/* [wpacu_timing] */ Misc::scriptExecTimer( 'filter_dequeue_scripts', 'end' ); /* [/wpacu_timing] */
@@ -1555,6 +1552,8 @@ SQL;
1555
return;
1556
}
1557
1558
// Prevent plugins from altering the DOM
1559
add_filter('w3tc_minify_enable', '__return_false');
1560
@@ -1834,7 +1833,7 @@ SQL;
1834
1835
$data['ignore_child'] = $this->getIgnoreChildren();
1836
1837
- wp_cache_set('wpacu_settings_frontend_data', $data);
1838
$this->parseTemplate('settings-frontend', $data, true);
1839
} elseif ($isDashboardEditView) {
1840
// AJAX call (not the classic WP one) from the WP Dashboard
@@ -1863,6 +1862,8 @@ SQL;
1863
exit();
1864
});
1865
}
1866
}
1867
1868
/**
@@ -2000,17 +2001,11 @@ SQL;
2000
$data['all']['hardcoded'] = (array) json_decode( $jsonH, ARRAY_A );
2001
2002
if (isset($data['all']['hardcoded']['within_conditional_comments']) && ! empty($data['all']['hardcoded']['within_conditional_comments'])) {
2003
- wp_cache_set( 'wpacu_hardcoded_content_within_conditional_comments', $data['all']['hardcoded']['within_conditional_comments'] );
2004
}
2005
}
2006
// [END] Hardcoded (if any)
2007
2008
- // [wpacu_pro]
2009
- if (isset($data['all']['unloaded_plugins']) && ! empty($data['all']['unloaded_plugins'])) {
2010
- wp_cache_add('wpacu_filtered_plugins', $data['all']['unloaded_plugins']);
2011
- }
2012
- // [/wpacu_pro]
2013
-
2014
if ($data['plugin_settings']['assets_list_layout'] === 'by-location') {
2015
$data['all'] = Sorting::appendLocation($data['all']);
2016
} else {
@@ -2241,7 +2236,7 @@ SQL;
2241
$data['all']['scripts'][$key]->wp = false;
2242
}
2243
2244
- $initialScriptPos = wp_cache_get($obj->handle, 'wpacu_scripts_initial_positions');
2245
2246
if ($initialScriptPos === 'body' || in_array($obj->handle, $this->assetsInFooter['scripts'])) {
2247
$data['all']['scripts'][$key]->position = 'body';
@@ -2411,7 +2406,7 @@ SQL;
2411
} else {
2412
if ($wooCommerceShopPageId > 0 && Misc::isHomePage() && strpos(get_site_url(), '://') !== false) {
2413
list($siteUrlAfterProtocol) = explode('://', get_site_url());
2414
- $currentPageUrlAfterProtocol = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
2415
2416
if ($siteUrlAfterProtocol != $currentPageUrlAfterProtocol && (strpos($siteUrlAfterProtocol,
2417
'/shop') !== false)
258
// "Direct" AJAX call or "WP Remote Post" method used?
259
// Do not trigger the admin bar as it's not relevant
260
if ($this->isAjaxCall || $this->isGetAssetsCall) {
261
+ add_filter('show_admin_bar', '__return_false');
262
}
263
264
// This is triggered AFTER "saveSettings" from 'Settings' class
315
);
316
}
317
318
+ if ( Plugin::preventAnyChanges() || self::isTestModeActive() ) {
319
+ return $styleTag;
320
+ }
321
+
322
// Alter for debugging purposes; triggers before anything else
323
// e.g. you're working on a website and there is no Dashboard access and you want to determine the handle name
324
// if the handle name is not showing up, then the LINK stylesheet has been hardcoded (not enqueued the WordPress way)
326
$styleTag = str_replace('<link ', '<link data-wpacu-debug-style-handle=\'' . $tagHandle . '\' ', $styleTag);
327
}
328
329
+ if (strpos($styleTag, 'data-wpacu-style-handle') === false) {
330
+ $styleTag = str_replace('<link ', '<link data-wpacu-style-handle=\'' . $tagHandle . '\' ', $styleTag);
331
}
332
333
+ return $styleTag;
334
}, 10, 2);
335
336
add_filter('script_loader_tag', static function($scriptTag, $tagHandle) {
337
+ // Alter for debugging purposes; triggers before anything else
338
// e.g. you're working on a website and there is no Dashboard access and you want to determine the handle name
339
// if the handle name is not showing up, then the SCRIPT has been hardcoded (not enqueued the WordPress way)
340
if (array_key_exists('wpacu_show_handle_names', $_GET)) {
363
$scriptTag = str_replace('<script ', '<script data-wpacu-jquery-migrate-handle=1 ', $scriptTag);
364
}
365
366
+ return $scriptTag;
367
}, 10, 2);
368
369
Preloads::instance()->init();
421
// Fetch the page in the background to see what scripts/styles are already loading
422
if ($this->isGetAssetsCall || $this->frontendShow()) {
423
if ($this->isGetAssetsCall) {
424
+ add_filter('show_admin_bar', '__return_false');
425
}
426
427
// Save CSS handles list that is printed in the <HEAD>
571
global $wp_styles;
572
573
if (current_action() === 'wp_print_styles') {
574
+ ObjectCache::wpacu_cache_set('wpacu_styles_object_after_wp_print_styles', $wp_styles);
575
}
576
577
$list = array();
578
579
if (current_action() === 'wp_print_footer_scripts') {
580
+ $cachedWpStyles = ObjectCache::wpacu_cache_get('wpacu_styles_object_after_wp_print_styles');
581
if (isset($cachedWpStyles->registered) && count($cachedWpStyles->registered) === count($wp_styles->registered)) {
582
// The list was already generated in "wp_print_styles" and the number of registered assets are the same
583
// Save resources and do not re-generate it
584
+ $list = ObjectCache::wpacu_cache_get('wpacu_styles_handles_marked_for_unload');
585
}
586
}
587
588
+ if ( empty($list) || ! is_array($list) ) {
589
// [wpacu_lite]
590
$nonAssetConfigPage = ( ! $this->isUpdateable && ! Misc::getShowOnFront() );
591
// [/wpacu_lite]
610
$list = (array) $jsonList->styles;
611
}
612
613
+ if (! is_array($list)) {
614
+ $list = array();
615
+ }
616
+
617
// Any global unloaded styles? Append them
618
if ( ! empty( $globalUnload['styles'] ) ) {
619
foreach ( $globalUnload['styles'] as $handleStyle ) {
670
}
671
672
if ( isset( $this->wpAllStyles['registered'] ) && ! empty( $this->wpAllStyles['registered'] ) ) {
673
+ ObjectCache::wpacu_cache_set( 'wpacu_all_styles_handles', array_keys( $this->wpAllStyles['registered'] ) );
674
}
675
676
// e.g. for test/debug mode or AJAX calls (where all assets have to load)
726
$handle = trim($handle);
727
728
// Ignore auto generated handles for the hardcoded CSS as they were added for reference purposes
729
+ // They will get stripped later on via OptimizeCommon.php
730
+ if (strpos($handle, 'wpacu_hardcoded_link_') === 0) {
731
continue;
732
}
733
745
}
746
747
if (current_action() === 'wp_print_styles') {
748
+ ObjectCache::wpacu_cache_set( 'wpacu_styles_handles_marked_for_unload', $list );
749
}
750
751
/* [wpacu_timing] */ Misc::scriptExecTimer( 'filter_dequeue_styles', 'end' ); /* [/wpacu_timing] */
861
global $wp_scripts;
862
863
if (current_action() === 'wp_print_scripts') {
864
+ ObjectCache::wpacu_cache_set('wpacu_scripts_object_after_wp_print_scripts', $wp_scripts);
865
}
866
867
$list = array();
868
869
if (current_action() === 'wp_print_footer_scripts') {
870
+ $cachedWpScripts = ObjectCache::wpacu_cache_get('wpacu_scripts_object_after_wp_print_scripts');
871
if (isset($cachedWpScripts->registered) && count($cachedWpScripts->registered) === count($wp_scripts->registered)) {
872
// The list was already generated in "wp_print_scripts" and the number of registered assets are the same
873
// Save resources and do not re-generate it
874
+ $list = ObjectCache::wpacu_cache_get('wpacu_scripts_handles_marked_for_unload');
875
}
876
}
877
982
if ( empty( $list ) ) {
983
/* [wpacu_timing] */
984
Misc::scriptExecTimer( 'filter_dequeue_scripts', 'end' ); /* [/wpacu_timing] */
985
return;
986
}
987
989
if ( array_key_exists( 'wpacu_no_js_unload', $_GET ) || $this->preventAssetsSettings() ) {
990
/* [wpacu_timing] */
991
Misc::scriptExecTimer( 'filter_dequeue_scripts', 'end' ); /* [/wpacu_timing] */
992
return;
993
}
994
}
998
foreach ($list as $handle) {
999
$handle = trim($handle);
1000
1001
+ if (array_key_exists('wpacu_debug', $_GET)) {
1002
+ $this->allUnloadedAssets['js'][] = $handle;
1003
+ }
1004
+
1005
// Special Action for 'jquery-migrate' handler as its tied to 'jquery'
1006
if ($handle === 'jquery-migrate' && isset($this->wpAllScripts['registered']['jquery'])) {
1007
$jQueryRegScript = $this->wpAllScripts['registered']['jquery'];
1017
continue;
1018
}
1019
1020
if (isset($ignoreChildParentList['scripts'], $this->wpAllScripts['registered'][$handle]->src) && is_array($ignoreChildParentList['scripts']) && array_key_exists($handle, $ignoreChildParentList['scripts'])) {
1021
// Do not dequeue it as it's "children" will also be dequeued (ignore rule is applied)
1022
// It will be stripped by cleaning its SCRIPT tag from the HTML Source
1039
}
1040
1041
if (current_action() === 'wp_print_scripts') {
1042
+ ObjectCache::wpacu_cache_set( 'wpacu_scripts_handles_marked_for_unload', $list );
1043
}
1044
1045
/* [wpacu_timing] */ Misc::scriptExecTimer( 'filter_dequeue_scripts', 'end' ); /* [/wpacu_timing] */
1552
return;
1553
}
1554
1555
+ /* [wpacu_timing] */ $wpacuTimingName = 'output_css_js_manager'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
1556
+
1557
// Prevent plugins from altering the DOM
1558
add_filter('w3tc_minify_enable', '__return_false');
1559
1833
1834
$data['ignore_child'] = $this->getIgnoreChildren();
1835
1836
+ ObjectCache::wpacu_cache_set('wpacu_settings_frontend_data', $data);
1837
$this->parseTemplate('settings-frontend', $data, true);
1838
} elseif ($isDashboardEditView) {
1839
// AJAX call (not the classic WP one) from the WP Dashboard
1862
exit();
1863
});
1864
}
1865
+
1866
+ /* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
1867
}
1868
1869
/**
2001
$data['all']['hardcoded'] = (array) json_decode( $jsonH, ARRAY_A );
2002
2003
if (isset($data['all']['hardcoded']['within_conditional_comments']) && ! empty($data['all']['hardcoded']['within_conditional_comments'])) {
2004
+ ObjectCache::wpacu_cache_set( 'wpacu_hardcoded_content_within_conditional_comments', $data['all']['hardcoded']['within_conditional_comments'] );
2005
}
2006
}
2007
// [END] Hardcoded (if any)
2008
2009
if ($data['plugin_settings']['assets_list_layout'] === 'by-location') {
2010
$data['all'] = Sorting::appendLocation($data['all']);
2011
} else {
2236
$data['all']['scripts'][$key]->wp = false;
2237
}
2238
2239
+ $initialScriptPos = ObjectCache::wpacu_cache_get($obj->handle, 'wpacu_scripts_initial_positions');
2240
2241
if ($initialScriptPos === 'body' || in_array($obj->handle, $this->assetsInFooter['scripts'])) {
2242
$data['all']['scripts'][$key]->position = 'body';
2406
} else {
2407
if ($wooCommerceShopPageId > 0 && Misc::isHomePage() && strpos(get_site_url(), '://') !== false) {
2408
list($siteUrlAfterProtocol) = explode('://', get_site_url());
2409
+ $currentPageUrlAfterProtocol = parse_url(site_url(), PHP_URL_HOST) . $_SERVER['REQUEST_URI'];
2410
2411
if ($siteUrlAfterProtocol != $currentPageUrlAfterProtocol && (strpos($siteUrlAfterProtocol,
2412
'/shop') !== false)
classes/Misc.php CHANGED
@@ -1,6 +1,8 @@
1
<?php
2
namespace WpAssetCleanUp;
3
4
/**
5
* Class Misc
6
* contains various common functions that are used by the plugin
@@ -31,16 +33,6 @@ class Misc
31
*/
32
public $activeCachePlugins = array();
33
34
- /**
35
- * Misc constructor.
36
- */
37
- public function __construct()
38
- {
39
- if (isset($_REQUEST['wpacuNoAdminBar'])) {
40
- self::noAdminBarLoad();
41
- }
42
- }
43
-
44
/**
45
* @var
46
*/
@@ -336,6 +328,50 @@ class Misc
336
return array();
337
}
338
339
/**
340
* @return bool
341
*/
@@ -356,14 +392,6 @@ class Misc
356
return self::$showOnFront;
357
}
358
359
- /**
360
- *
361
- */
362
- public static function noAdminBarLoad()
363
- {
364
- add_filter('show_admin_bar', '__return_false');
365
- }
366
-
367
/**
368
* @param $plugin
369
*
@@ -418,12 +446,12 @@ class Misc
418
*/
419
public static function getW3tcMasterConfig()
420
{
421
- if (! wp_cache_get('wpacu_w3tc_master_config')) {
422
$w3tcConfigMasterFile = WP_CONTENT_DIR . '/w3tc-config/master.php';
423
$w3tcMasterConfig = FileSystem::file_get_contents($w3tcConfigMasterFile);
424
- wp_cache_set('wpacu_w3tc_master_config', trim($w3tcMasterConfig));
425
} else {
426
- $w3tcMasterConfig = wp_cache_get('wpacu_w3tc_master_config');
427
}
428
429
return $w3tcMasterConfig;
@@ -721,8 +749,8 @@ SQL;
721
722
$relSrc = str_replace( site_url(), '', $srcAlt );
723
724
- if (strpos($relSrc, '/wp-content/plugins') !== 0) {
725
- list (,$relSrc) = '/wp-content/plugins' . explode('/wp-content/plugins', $relSrc);
726
}
727
728
if (strpos($relSrc, $relPluginsUrl) !== false) {
@@ -1071,16 +1099,10 @@ SQL;
1071
1072
if ($action === 'start') {
1073
$startTime = (microtime(true) * 1000);
1074
-
1075
- // Do not overwrite it if it's already there (e.g. in a function called several times)
1076
- if (wp_cache_get($wpacuStartTimeName, 'wpacu_exec_time')) {
1077
- return '';
1078
- }
1079
-
1080
- wp_cache_set($wpacuStartTimeName, $startTime, 'wpacu_exec_time');
1081
}
1082
1083
- if ($action === 'end' && ($startTime = wp_cache_get($wpacuStartTimeName, 'wpacu_exec_time'))) {
1084
// End clock time in seconds
1085
$endTime = (microtime(true) * 1000);
1086
$scriptExecTime = ($endTime !== $startTime && $endTime > $startTime) ? ($endTime - $startTime) : 0;
@@ -1088,11 +1110,11 @@ SQL;
1088
// Calculate script execution time
1089
// Is there an existing exec time (e.g. from a function called several times)?
1090
// Append it to the total execution time
1091
- if ($scriptExecTimeExisting = wp_cache_get($wpacuExecTimeName, 'wpacu_exec_time')) {
1092
$scriptExecTime += $scriptExecTimeExisting;
1093
}
1094
1095
- wp_cache_set($wpacuExecTimeName, $scriptExecTime, 'wpacu_exec_time');
1096
return $scriptExecTime;
1097
}
1098
@@ -1106,10 +1128,10 @@ SQL;
1106
*/
1107
public static function getTimingValues($wpacuCacheKey)
1108
{
1109
- $wpacuExecTiming = wp_cache_get( $wpacuCacheKey, 'wpacu_exec_time' ) ?: 0;
1110
1111
$wpacuTimingFormatMs = str_replace('.00', '', number_format($wpacuExecTiming, 2));
1112
- $wpacuTimingFormatS = str_replace('.00', '', number_format(($wpacuExecTiming / 1000), 3));
1113
1114
return array('ms' => $wpacuTimingFormatMs, 's' => $wpacuTimingFormatS);
1115
}
1
<?php
2
namespace WpAssetCleanUp;
3
4
+ use WpAssetCleanUp\OptimiseAssets\OptimizeCommon;
5
+
6
/**
7
* Class Misc
8
* contains various common functions that are used by the plugin
33
*/
34
public $activeCachePlugins = array();
35
36
/**
37
* @var
38
*/
328
return array();
329
}
330
331
+ /**
332
+ * @param bool $clean
333
+ *
334
+ * @return mixed|string
335
+ */
336
+ public static function getCurrentPageUrl($clean = true)
337
+ {
338
+ $currentPageUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . parse_url(site_url(), PHP_URL_HOST) . $_SERVER['REQUEST_URI'];
339
+
340
+ if ($clean && strpos($currentPageUrl, '?') !== false) {
341
+ list($currentPageUrl) = explode('?', $currentPageUrl);
342
+ }
343
+
344
+ return $currentPageUrl;
345
+ }
346
+
347
+ /**
348
+ * @param $src
349
+ * @param $assetKey
350
+ *
351
+ * @return string|string[]
352
+ */
353
+ public static function assetFromHrefToRelativeUri($src, $assetKey)
354
+ {
355
+ // Make the "src" relative in case the information will be imported from Staging to Live, it won't show the handle's link referencing to the staging URL in the "Overview" page and other similar pages as it's confusing
356
+ $localAssetPath = OptimizeCommon::getLocalAssetPath($src, (($assetKey === 'styles') ? 'css' : 'js'));
357
+
358
+ $relSrc = $src;
359
+
360
+ if ($localAssetPath) {
361
+ $relSrc = str_replace(ABSPATH, '', $relSrc);
362
+ }
363
+
364
+ $relSrc = str_replace(site_url(), '', $relSrc);
365
+
366
+ // Does it start with '//'? (protocol is missing) - the replacement above wasn't made
367
+ if (strpos($relSrc, '//') === 0) {
368
+ $siteUrlNoProtocol = str_replace(array('http:', 'https:'), '', site_url());
369
+ $relSrc = str_replace($siteUrlNoProtocol, '', $relSrc);
370
+ }
371
+
372
+ return $relSrc;
373
+ }
374
+
375
/**
376
* @return bool
377
*/
392
return self::$showOnFront;
393
}
394
395
/**
396
* @param $plugin
397
*
446
*/
447
public static function getW3tcMasterConfig()
448
{
449
+ if (! ObjectCache::wpacu_cache_get('wpacu_w3tc_master_config')) {
450
$w3tcConfigMasterFile = WP_CONTENT_DIR . '/w3tc-config/master.php';
451
$w3tcMasterConfig = FileSystem::file_get_contents($w3tcConfigMasterFile);
452
+ ObjectCache::wpacu_cache_set('wpacu_w3tc_master_config', trim($w3tcMasterConfig));
453
} else {
454
+ $w3tcMasterConfig = ObjectCache::wpacu_cache_get('wpacu_w3tc_master_config');
455
}
456
457
return $w3tcMasterConfig;
749
750
$relSrc = str_replace( site_url(), '', $srcAlt );
751
752
+ if (strpos($relSrc, '/wp-content/plugins') !== false) {
753
+ list (,$relSrc) = explode('/wp-content/plugins', $relSrc);
754
}
755
756
if (strpos($relSrc, $relPluginsUrl) !== false) {
1099
1100
if ($action === 'start') {
1101
$startTime = (microtime(true) * 1000);
1102
+ ObjectCache::wpacu_cache_set($wpacuStartTimeName, $startTime, 'wpacu_exec_time');
1103
}
1104
1105
+ if ($action === 'end' && ($startTime = ObjectCache::wpacu_cache_get($wpacuStartTimeName, 'wpacu_exec_time'))) {
1106
// End clock time in seconds
1107
$endTime = (microtime(true) * 1000);
1108
$scriptExecTime = ($endTime !== $startTime && $endTime > $startTime) ? ($endTime - $startTime) : 0;
1110
// Calculate script execution time
1111
// Is there an existing exec time (e.g. from a function called several times)?
1112
// Append it to the total execution time
1113
+ if ($scriptExecTimeExisting = ObjectCache::wpacu_cache_get($wpacuExecTimeName, 'wpacu_exec_time')) {
1114
$scriptExecTime += $scriptExecTimeExisting;
1115
}
1116
1117
+ ObjectCache::wpacu_cache_set($wpacuExecTimeName, $scriptExecTime, 'wpacu_exec_time');
1118
return $scriptExecTime;
1119
}
1120
1128
*/
1129
public static function getTimingValues($wpacuCacheKey)
1130
{
1131
+ $wpacuExecTiming = ObjectCache::wpacu_cache_get( $wpacuCacheKey, 'wpacu_exec_time' ) ?: 0;
1132
1133
$wpacuTimingFormatMs = str_replace('.00', '', number_format($wpacuExecTiming, 2));
1134
+ $wpacuTimingFormatS = str_replace(array('.00', ','), '', number_format(($wpacuExecTiming / 1000), 3));
1135
1136
return array('ms' => $wpacuTimingFormatMs, 's' => $wpacuTimingFormatS);
1137
}
classes/ObjectCache.php ADDED
@@ -0,0 +1,750 @@
1
+ <?php
2
+ namespace WpAssetCleanUp;
3
+
4
+ /**
5
+ * NOTE: This is from the original core file located /wp-includes/class-wp-object-cache.php
6
+ * Avoid the WordPress core $wp_object_cache global variable which is sometimes altered by 3rd party plugins
7
+ * This would make this plugin compatible with plugins such as "Redis Object Cache"
8
+ *
9
+ * Object Cache API: ObjectCache class
10
+ *
11
+ * @package WordPress
12
+ * @subpackage Cache
13
+ * @since 5.4.0
14
+ */
15
+
16
+ /**
17
+ * Core class that implements an object cache.
18
+ *
19
+ * The WordPress Object Cache is used to save on trips to the database. The
20
+ * Object Cache stores all of the cache data to memory and makes the cache
21
+ * contents available by using a key, which is used to name and later retrieve
22
+ * the cache contents.
23
+ *
24
+ * The Object Cache can be replaced by other caching mechanisms by placing files
25
+ * in the wp-content folder which is looked at in wp-settings. If that file
26
+ * exists, then this file will not be included.
27
+ *
28
+ * @since 2.0.0
29
+ */
30
+ class ObjectCache {
31
+
32
+ /**
33
+ * Holds the cached objects.
34
+ *
35
+ * @since 2.0.0
36
+ * @var array
37
+ */
38
+ private $cache = array();
39
+
40
+ /**
41
+ * The amount of times the cache data was already stored in the cache.
42
+ *
43
+ * @since 2.5.0
44
+ * @var int
45
+ */
46
+ public $cache_hits = 0;
47
+
48
+ /**
49
+ * Amount of times the cache did not have the request in cache.
50
+ *
51
+ * @since 2.0.0
52
+ * @var int
53
+ */
54
+ public $cache_misses = 0;
55
+
56
+ /**
57
+ * List of global cache groups.
58
+ *
59
+ * @since 3.0.0
60
+ * @var array
61
+ */
62
+ protected $global_groups = array();
63
+
64
+ /**
65
+ * The blog prefix to prepend to keys in non-global groups.
66
+ *
67
+ * @since 3.5.0
68
+ * @var string
69
+ */
70
+ private $blog_prefix;
71
+
72
+ /**
73
+ * Holds the value of is_multisite().
74
+ *
75
+ * @since 3.5.0
76
+ * @var bool
77
+ */
78
+ private $multisite;
79
+
80
+ /**
81
+ * Sets up object properties; PHP 5 style constructor.
82
+ *
83
+ * @since 2.0.8
84
+ */
85
+ public function __construct() {
86
+ $this->multisite = is_multisite();
87
+ $this->blog_prefix = $this->multisite ? get_current_blog_id() . ':' : '';
88
+ }
89
+
90
+ /**
91
+ * Makes private properties readable for backward compatibility.
92
+ *
93
+ * @since 4.0.0
94
+ *
95
+ * @param string $name Property to get.
96
+ * @return mixed Property.
97
+ */
98
+ public function __get( $name ) {
99
+ return $this->$name;
100
+ }
101
+
102
+ /**
103
+ * Makes private properties settable for backward compatibility.
104
+ *
105
+ * @since 4.0.0
106
+ *
107
+ * @param string $name Property to set.
108
+ * @param mixed $value Property value.
109
+ * @return mixed Newly-set property.
110
+ */
111
+ public function __set( $name, $value ) {
112
+ return $this->$name = $value;
113
+ }
114
+
115
+ /**
116
+ * Makes private properties checkable for backward compatibility.
117
+ *
118
+ * @since 4.0.0
119
+ *
120
+ * @param string $name Property to check if set.
121
+ * @return bool Whether the property is set.
122
+ */
123
+ public function __isset( $name ) {
124
+ return isset( $this->$name );
125
+ }
126
+
127
+ /**
128
+ * Makes private properties un-settable for backward compatibility.
129
+ *
130
+ * @since 4.0.0
131
+ *
132
+ * @param string $name Property to unset.
133
+ */
134
+ public function __unset( $name ) {
135
+ unset( $this->$name );
136
+ }
137
+
138
+ /**
139
+ * Adds data to the cache if it doesn't already exist.
140
+ *
141
+ * @since 2.0.0
142
+ *
143
+ * @uses ObjectCache::_exists() Checks to see if the cache already has data.
144
+ * @uses ObjectCache::set() Sets the data after the checking the cache
145
+ * contents existence.
146
+ *
147
+ * @param int|string $key What to call the contents in the cache.
148
+ * @param mixed $data The contents to store in the cache.
149
+ * @param string $group Optional. Where to group the cache contents. Default 'default'.
150
+ * @param int $expire Optional. When to expire the cache contents. Default 0 (no expiration).
151
+ * @return bool True on success, false if cache key and group already exist.
152
+ */
153
+ public function add( $key, $data, $group = 'default', $expire = 0 ) {
154
+ if ( wp_suspend_cache_addition() ) {
155
+ return false;
156
+ }
157
+
158
+ if ( empty( $group ) ) {
159
+ $group = 'default';
160
+ }
161
+
162
+ $id = $key;
163
+ if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
164
+ $id = $this->blog_prefix . $key;
165
+ }
166
+
167
+ if ( $this->_exists( $id, $group ) ) {
168
+ return false;
169
+ }
170
+
171
+ return $this->set( $key, $data, $group, (int) $expire );
172
+ }
173
+
174
+ /**
175
+ * Sets the list of global cache groups.
176
+ *
177
+ * @since 3.0.0
178
+ *
179
+ * @param array $groups List of groups that are global.
180
+ */
181
+ public function add_global_groups( $groups ) {
182
+ $groups = (array) $groups;
183
+
184
+ $groups = array_fill_keys( $groups, true );
185
+ $this->global_groups = array_merge( $this->global_groups, $groups );
186
+ }
187
+
188
+ /**
189
+ * Decrements numeric cache item's value.
190
+ *
191
+ * @since 3.3.0
192
+ *
193
+ * @param int|string $key The cache key to decrement.
194
+ * @param int $offset Optional. The amount by which to decrement the item's value. Default 1.
195
+ * @param string $group Optional. The group the key is in. Default 'default'.
196
+ * @return int|false The item's new value on success, false on failure.
197
+ */
198
+ public function decr( $key, $offset = 1, $group = 'default' ) {
199
+ if ( empty( $group ) ) {
200
+ $group = 'default';
201
+ }
202
+
203
+ if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
204
+ $key = $this->blog_prefix . $key;
205
+ }
206
+
207
+ if ( ! $this->_exists( $key, $group ) ) {
208
+ return false;
209
+ }
210
+
211
+ if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) {
212
+ $this->cache[ $group ][ $key ] = 0;
213
+ }
214
+
215
+ $offset = (int) $offset;
216
+
217
+ $this->cache[ $group ][ $key ] -= $offset;
218
+
219
+ if ( $this->cache[ $group ][ $key ] < 0 ) {
220
+ $this->cache[ $group ][ $key ] = 0;
221
+ }
222
+
223
+ return $this->cache[ $group ][ $key ];
224
+ }
225
+
226
+ /**
227
+ * Removes the contents of the cache key in the group.
228
+ *
229
+ * If the cache key does not exist in the group, then nothing will happen.
230
+ *
231
+ * @since 2.0.0
232
+ *
233
+ * @param int|string $key What the contents in the cache are called.
234
+ * @param string $group Optional. Where the cache contents are grouped. Default 'default'.
235
+ * @param bool $deprecated Optional. Unused. Default false.
236
+ * @return bool False if the contents weren't deleted and true on success.
237
+ */
238
+ public function delete( $key, $group = 'default', $deprecated = false ) {
239
+ if ( empty( $group ) ) {
240
+ $group = 'default';
241
+ }
242
+
243
+ if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
244
+ $key = $this->blog_prefix . $key;
245
+ }
246
+
247
+ if ( ! $this->_exists( $key, $group ) ) {
248
+ return false;
249
+ }
250
+
251
+ unset( $this->cache[ $group ][ $key ] );
252
+ return true;
253
+ }
254
+
255
+ /**
256
+ * Clears the object cache of all data.
257
+ *
258
+ * @since 2.0.0
259
+ *
260
+ * @return true Always returns true.
261
+ */
262
+ public function flush() {
263
+ $this->cache = array();
264
+
265
+ return true;
266
+ }
267
+
268
+ /**
269
+ * Retrieves the cache contents, if it exists.
270
+ *
271
+ * The contents will be first attempted to be retrieved by searching by the
272
+ * key in the cache group. If the cache is hit (success) then the contents
273
+ * are returned.
274
+ *
275
+ * On failure, the number of cache misses will be incremented.
276
+ *
277
+ * @since 2.0.0
278
+ *
279
+ * @param int|string $key What the contents in the cache are called.
280
+ * @param string $group Optional. Where the cache contents are grouped. Default 'default'.
281
+ * @param bool $force Optional. Unused. Whether to force a refetch rather than relying on the local
282
+ * cache. Default false.
283
+ * @param bool $found Optional. Whether the key was found in the cache (passed by reference).
284
+ * Disambiguates a return of false, a storable value. Default null.
285
+ * @return mixed|false The cache contents on success, false on failure to retrieve contents.
286
+ */
287
+ public function get( $key, $group = 'default', $force = false, &$found = null ) {
288
+ if ( empty( $group ) ) {
289
+ $group = 'default';
290
+ }
291
+
292
+ if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
293
+ $key = $this->blog_prefix . $key;
294
+ }
295
+
296
+ if ( $this->_exists( $key, $group ) ) {
297
+ $found = true;
298
+ $this->cache_hits += 1;
299
+ if ( is_object( $this->cache[ $group ][ $key ] ) ) {
300
+ return clone $this->cache[ $group ][ $key ];
301
+ } else {
302
+ return $this->cache[ $group ][ $key ];
303
+ }
304
+ }
305
+
306
+ $found = false;
307
+ $this->cache_misses += 1;
308
+ return false;
309
+ }
310
+
311
+ /**
312
+ * Increments numeric cache item's value.
313
+ *
314
+ * @since 3.3.0
315
+ *
316
+ * @param int|string $key The cache key to increment
317
+ * @param int $offset Optional. The amount by which to increment the item's value. Default 1.
318
+ * @param string $group Optional. The group the key is in. Default 'default'.
319
+ * @return int|false The item's new value on success, false on failure.
320
+ */
321
+ public function incr( $key, $offset = 1, $group = 'default' ) {
322
+ if ( empty( $group ) ) {
323
+ $group = 'default';
324
+ }
325
+
326
+ if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
327
+ $key = $this->blog_prefix . $key;
328
+ }
329
+
330
+ if ( ! $this->_exists( $key, $group ) ) {
331
+ return false;
332
+ }
333
+
334
+ if ( ! is_numeric( $this->cache[ $group ][ $key ] ) ) {
335
+ $this->cache[ $group ][ $key ] = 0;
336
+ }
337
+
338
+ $offset = (int) $offset;
339
+
340
+ $this->cache[ $group ][ $key ] += $offset;
341
+
342
+ if ( $this->cache[ $group ][ $key ] < 0 ) {
343
+ $this->cache[ $group ][ $key ] = 0;
344
+ }
345
+
346
+ return $this->cache[ $group ][ $key ];
347
+ }
348
+
349
+ /**
350
+ * Replaces the contents in the cache, if contents already exist.
351
+ *
352
+ * @since 2.0.0
353
+ *
354
+ * @see ObjectCache::set()
355
+ *
356
+ * @param int|string $key What to call the contents in the cache.
357
+ * @param mixed $data The contents to store in the cache.
358
+ * @param string $group Optional. Where to group the cache contents. Default 'default'.
359
+ * @param int $expire Optional. When to expire the cache contents. Default 0 (no expiration).
360
+ * @return bool False if not exists, true if contents were replaced.
361
+ */
362
+ public function replace( $key, $data, $group = 'default', $expire = 0 ) {
363
+ if ( empty( $group ) ) {
364
+ $group = 'default';
365
+ }
366
+
367
+ $id = $key;
368
+ if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
369
+ $id = $this->blog_prefix . $key;
370
+ }
371
+
372
+ if ( ! $this->_exists( $id, $group ) ) {
373
+ return false;
374
+ }
375
+
376
+ return $this->set( $key, $data, $group, (int) $expire );
377
+ }
378
+
379
+ /**
380
+ * Resets cache keys.
381
+ *
382
+ * @since 3.0.0
383
+ *
384
+ * @deprecated 3.5.0 Use switch_to_blog()
385
+ * @see switch_to_blog()
386
+ */
387
+ public function reset() {
388
+ _deprecated_function( __FUNCTION__, '3.5.0', 'switch_to_blog()' );
389
+
390
+ // Clear out non-global caches since the blog ID has changed.
391
+ foreach ( array_keys( $this->cache ) as $group ) {
392
+ if ( ! isset( $this->global_groups[ $group ] ) ) {
393
+ unset( $this->cache[ $group ] );
394
+ }
395
+ }
396
+ }
397
+
398
+ /**
399
+ * Sets the data contents into the cache.
400
+ *
401
+ * The cache contents are grouped by the $group parameter followed by the
402
+ * $key. This allows for duplicate ids in unique groups. Therefore, naming of
403
+ * the group should be used with care and should follow normal function
404
+ * naming guidelines outside of core WordPress usage.
405
+ *
406
+ * The $expire parameter is not used, because the cache will automatically
407
+ * expire for each time a page is accessed and PHP finishes. The method is
408
+ * more for cache plugins which use files.
409
+ *
410
+ * @since 2.0.0
411
+ *
412
+ * @param int|string $key What to call the contents in the cache.
413
+ * @param mixed $data The contents to store in the cache.
414
+ * @param string $group Optional. Where to group the cache contents. Default 'default'.
415
+ * @param int $expire Not Used.
416
+ * @return true Always returns true.
417
+ */
418
+ public function set( $key, $data, $group = 'default', $expire = 0 ) {
419
+ if ( empty( $group ) ) {
420
+ $group = 'default';
421
+ }
422
+
423
+ if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) ) {
424
+ $key = $this->blog_prefix . $key;
425
+ }
426
+
427
+ if ( is_object( $data ) ) {
428
+ $data = clone $data;
429
+ }
430
+
431
+ $this->cache[ $group ][ $key ] = $data;
432
+ return true;
433
+ }
434
+
435
+ /**
436
+ * Echoes the stats of the caching.
437
+ *
438
+ * Gives the cache hits, and cache misses. Also prints every cached group,
439
+ * key and the data.
440
+ *
441
+ * @since 2.0.0
442
+ */
443
+ public function stats() {
444
+ echo '<p>';
445
+ echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />";
446
+ echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />";
447
+ echo '</p>';
448
+ echo '<ul>';
449
+ foreach ( $this->cache as $group => $cache ) {
450
+ echo "<li><strong>Group:</strong> $group - ( " . number_format( strlen( serialize( $cache ) ) / KB_IN_BYTES, 2 ) . 'k )</li>';
451
+ }
452
+ echo '</ul>';
453
+ }
454
+
455
+ /**
456
+ * Switches the internal blog ID.
457
+ *
458
+ * This changes the blog ID used to create keys in blog specific groups.
459
+ *
460
+ * @since 3.5.0
461
+ *
462
+ * @param int $blog_id Blog ID.
463
+ */
464
+ public function switch_to_blog( $blog_id ) {
465
+ $blog_id = (int) $blog_id;
466
+ $this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
467
+ }
468
+
469
+ /**
470
+ * Serves as a utility function to determine whether a key exists in the cache.
471
+ *
472
+ * @since 3.4.0
473
+ *
474
+ * @param int|string $key Cache key to check for existence.
475
+ * @param string $group Cache group for the key existence check.
476
+ * @return bool Whether the key exists in the cache for the given group.
477
+ */
478
+ protected function _exists( $key, $group ) {
479
+ return isset( $this->cache[ $group ] ) && ( isset( $this->cache[ $group ][ $key ] ) || array_key_exists( $key, $this->cache[ $group ] ) );
480
+ }
481
+
482
+ /**
483
+ * [START] Functions to call (reference: /wp-includes/cache.php)
484
+ */
485
+ /**
486
+ * Adds data to the cache, if the cache key doesn't already exist.
487
+ *
488
+ * @since 2.0.0
489
+ *
490
+ * @see ObjectCache::add()
491
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
492
+ *
493
+ * @param int|string $key The cache key to use for retrieval later.
494
+ * @param mixed $data The data to add to the cache.
495
+ * @param string $group Optional. The group to add the cache to. Enables the same key
496
+ * to be used across groups. Default empty.
497
+ * @param int $expire Optional. When the cache data should expire, in seconds.
498
+ * Default 0 (no expiration).
499
+ * @return bool True on success, false if cache key and group already exist.
500
+ */
501
+ public static function wpacu_cache_add( $key, $data, $group = '', $expire = 0 ) {
502
+ global $wpacu_object_cache;
503
+
504
+ return $wpacu_object_cache->add( $key, $data, $group, (int) $expire );
505
+ }
506
+
507
+ /**
508
+ * Closes the cache.
509
+ *
510
+ * This function has ceased to do anything since WordPress 2.5. The
511
+ * functionality was removed along with the rest of the persistent cache.
512
+ *
513
+ * This does not mean that plugins can't implement this function when they need
514
+ * to make sure that the cache is cleaned up after WordPress no longer needs it.
515
+ *
516
+ * @since 2.0.0
517
+ *
518
+ * @return true Always returns true.
519
+ */
520
+ public static function wpacu_cache_close() {
521
+ return true;
522
+ }
523
+
524
+ /**
525
+ * Decrements numeric cache item's value.
526
+ *
527
+ * @since 3.3.0
528
+ *
529
+ * @see ObjectCache::decr()
530
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
531
+ *
532
+ * @param int|string $key The cache key to decrement.
533
+ * @param int $offset Optional. The amount by which to decrement the item's value. Default 1.
534
+ * @param string $group Optional. The group the key is in. Default empty.
535
+ * @return int|false The item's new value on success, false on failure.
536
+ */
537
+ public static function wpacu_cache_decr( $key, $offset = 1, $group = '' ) {
538
+ global $wpacu_object_cache;
539
+
540
+ return $wpacu_object_cache->decr( $key, $offset, $group );
541
+ }
542
+
543
+ /**
544
+ * Removes the cache contents matching key and group.
545
+ *
546
+ * @since 2.0.0
547
+ *
548
+ * @see ObjectCache::delete()
549
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
550
+ *
551
+ * @param int|string $key What the contents in the cache are called.
552
+ * @param string $group Optional. Where the cache contents are grouped. Default empty.
553
+ * @return bool True on successful removal, false on failure.
554
+ */
555
+ public static function wpacu_cache_delete( $key, $group = '' ) {
556
+ global $wpacu_object_cache;
557
+
558
+ return $wpacu_object_cache->delete( $key, $group );
559
+ }
560
+
561
+ /**
562
+ * Removes all cache items.
563
+ *
564
+ * @since 2.0.0
565
+ *
566
+ * @see ObjectCache::flush()
567
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
568
+ *
569
+ * @return bool True on success, false on failure.
570
+ */
571
+ public static function wpacu_cache_flush() {
572
+ global $wpacu_object_cache;
573
+
574
+ return $wpacu_object_cache->flush();
575
+ }
576
+
577
+ /**
578
+ * Retrieves the cache contents from the cache by key and group.
579
+ *
580
+ * @since 2.0.0
581
+ *
582
+ * @see ObjectCache::get()
583
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
584
+ *
585
+ * @param int|string $key The key under which the cache contents are stored.
586
+ * @param string $group Optional. Where the cache contents are grouped. Default empty.
587
+ * @param bool $force Optional. Whether to force an update of the local cache from the persistent
588
+ * cache. Default false.
589
+ * @param bool $found Optional. Whether the key was found in the cache (passed by reference).
590
+ * Disambiguates a return of false, a storable value. Default null.
591
+ * @return bool|mixed False on failure to retrieve contents or the cache
592
+ * contents on success
593
+ */
594
+ public static function wpacu_cache_get( $key, $group = '', $force = false, &$found = null ) {
595
+ global $wpacu_object_cache;
596
+
597
+ return $wpacu_object_cache->get( $key, $group, $force, $found );
598
+ }
599
+
600
+ /**
601
+ * Increment numeric cache item's value
602
+ *
603
+ * @since 3.3.0
604
+ *
605
+ * @see ObjectCache::incr()
606
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
607
+ *
608
+ * @param int|string $key The key for the cache contents that should be incremented.
609
+ * @param int $offset Optional. The amount by which to increment the item's value. Default 1.
610
+ * @param string $group Optional. The group the key is in. Default empty.
611
+ * @return int|false The item's new value on success, false on failure.
612
+ */
613
+ public static function wpacu_cache_incr( $key, $offset = 1, $group = '' ) {
614
+ global $wpacu_object_cache;
615
+
616
+ return $wpacu_object_cache->incr( $key, $offset, $group );
617
+ }
618
+
619
+ /**
620
+ * Sets up Object Cache Global and assigns it.
621
+ *
622
+ * @since 2.0.0
623
+ *
624
+ * @global ObjectCache $wpacu_object_cache
625
+ */
626
+ public static function wpacu_cache_init() {
627
+ $GLOBALS['wpacu_object_cache'] = new ObjectCache();
628
+ }
629
+
630
+ /**
631
+ * Replaces the contents of the cache with new data.
632
+ *
633
+ * @since 2.0.0
634
+ *
635
+ * @see ObjectCache::replace()
636
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
637
+ *
638
+ * @param int|string $key The key for the cache data that should be replaced.
639
+ * @param mixed $data The new data to store in the cache.
640
+ * @param string $group Optional. The group for the cache data that should be replaced.
641
+ * Default empty.
642
+ * @param int $expire Optional. When to expire the cache contents, in seconds.
643
+ * Default 0 (no expiration).
644
+ * @return bool False if original value does not exist, true if contents were replaced
645
+ */
646
+ public static function wpacu_cache_replace( $key, $data, $group = '', $expire = 0 ) {
647
+ global $wpacu_object_cache;
648
+
649
+ return $wpacu_object_cache->replace( $key, $data, $group, (int) $expire );
650
+ }
651
+
652
+ /**
653
+ * Saves the data to the cache.
654
+ *
655
+ * Differs from ObjectCache::wpacu_cache_add) and wp_cache_replace() in that it will always write data.
656
+ *
657
+ * @since 2.0.0
658
+ *
659
+ * @see ObjectCache::set()
660
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
661
+ *
662
+ * @param int|string $key The cache key to use for retrieval later.
663
+ * @param mixed $data The contents to store in the cache.
664
+ * @param string $group Optional. Where to group the cache contents. Enables the same key
665
+ * to be used across groups. Default empty.
666
+ * @param int $expire Optional. When to expire the cache contents, in seconds.
667
+ * Default 0 (no expiration).
668
+ * @return bool True on success, false on failure.
669
+ */
670
+ public static function wpacu_cache_set( $key, $data, $group = '', $expire = 0 ) {
671
+ global $wpacu_object_cache;
672
+
673
+ return $wpacu_object_cache->set( $key, $data, $group, (int) $expire );
674
+ }
675
+
676
+ /**
677
+ * Switches the internal blog ID.
678
+ *
679
+ * This changes the blog id used to create keys in blog specific groups.
680
+ *
681
+ * @since 3.5.0
682
+ *
683
+ * @see ObjectCache::switch_to_blog()
684
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
685
+ *
686
+ * @param int $blog_id Site ID.
687
+ */
688
+ public static function wpacu_cache_switch_to_blog( $blog_id ) {
689
+ global $wpacu_object_cache;
690
+
691
+ $wpacu_object_cache->switch_to_blog( $blog_id );
692
+ }
693
+
694
+ /**
695
+ * Adds a group or set of groups to the list of global groups.
696
+ *
697
+ * @since 2.6.0
698
+ *
699
+ * @see ObjectCache::add_global_groups()
700
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
701
+ *
702
+ * @param string|array $groups A group or an array of groups to add.
703
+ */
704
+ public static function wpacu_cache_add_global_groups( $groups ) {
705
+ global $wpacu_object_cache;
706
+
707
+ $wpacu_object_cache->add_global_groups( $groups );
708
+ }
709
+
710
+ /**
711
+ * Adds a group or set of groups to the list of non-persistent groups.
712
+ *
713
+ * @since 2.6.0
714
+ *
715
+ * @param string|array $groups A group or an array of groups to add.
716
+ */
717
+ public static function wpacu_cache_add_non_persistent_groups( $groups ) {
718
+ // Default cache doesn't persist so nothing to do here.
719
+ }
720
+
721
+ /**
722
+ * Reset internal cache keys and structures.
723
+ *
724
+ * If the cache back end uses global blog or site IDs as part of its cache keys,
725
+ * this function instructs the back end to reset those keys and perform any cleanup
726
+ * since blog or site IDs have changed since cache init.
727
+ *
728
+ * This function is deprecated. Use wp_cache_switch_to_blog() instead of this
729
+ * function when preparing the cache for a blog switch. For clearing the cache
730
+ * during unit tests, consider using wp_cache_init(). wp_cache_init() is not
731
+ * recommended outside of unit tests as the performance penalty for using it is
732
+ * high.
733
+ *
734
+ * @since 2.6.0
735
+ * @deprecated 3.5.0 ObjectCache::reset()
736
+ * @see ObjectCache::reset()
737
+ *
738
+ * @global ObjectCache $wpacu_object_cache Object cache global instance.
739
+ */
740
+ public static function wpacu_cache_reset() {
741
+ _deprecated_function( __FUNCTION__, '3.5.0', 'ObjectCache::reset()' );
742
+
743
+ global $wpacu_object_cache;
744
+
745
+ $wpacu_object_cache->reset();
746
+ }
747
+ /**
748
+ * [END] Functions to call (reference: /wp-includes/cache.php)
749
+ */
750
+ }
classes/OptimiseAssets/CombineCss.php CHANGED
@@ -5,6 +5,8 @@ use WpAssetCleanUp\Main;
5
use WpAssetCleanUp\Menu;
6
use WpAssetCleanUp\FileSystem;
7
use WpAssetCleanUp\Misc;
8
9
/**
10
* Class CombineCss
@@ -24,7 +26,7 @@ class CombineCss
24
*/
25
public static function doCombine($htmlSource)
26
{
27
- if (! (function_exists('libxml_use_internal_errors') && function_exists('libxml_clear_errors') && class_exists('DOMDocument')) && class_exists('DOMXpath')) {
28
return $htmlSource;
29
}
30
@@ -32,6 +34,9 @@ class CombineCss
32
return $htmlSource;
33
}
34
35
// Speed up processing by getting the already existing final CSS file URI
36
// This will avoid parsing the HTML DOM and determine the combined URI paths for all the CSS files
37
$storageJsonContents = OptimizeCommon::getAssetCachedData(self::$jsonStorageFile, OptimizeCss::getRelPathCssCacheDir(), 'css');
@@ -39,7 +44,13 @@ class CombineCss
39
// $uriToFinalCssFile will always be relative ONLY within WP_CONTENT_DIR . self::getRelPathCssCacheDir()
40
// which is usually "wp-content/cache/asset-cleanup/css/"
41
42
- if (empty($storageJsonContents)) {
43
$storageJsonContentsToSave = array();
44
45
/*
@@ -48,25 +59,20 @@ class CombineCss
48
// Nothing in the database records or the retrieved cached file does not exist?
49
OptimizeCommon::clearAssetCachedData(self::$jsonStorageFile);
50
51
- // Fetch the DOM
52
- $documentForCSS = new \DOMDocument();
53
-
54
- libxml_use_internal_errors(true);
55
-
56
$storageJsonContents = array();
57
58
- // Strip NOSCRIPT tags
59
- $htmlSourceAlt = preg_replace('@<(noscript)[^>]*?>.*?</\\1>@si', '', $htmlSource);
60
- $documentForCSS->loadHTML($htmlSourceAlt);
61
62
foreach (array('head', 'body') as $docLocationTag) {
63
$combinedUriPathsGroup = $localAssetsPathsGroup = $linkHrefsGroup = array();
64
65
- $docLocationElements = $documentForCSS->getElementsByTagName($docLocationTag)->item(0);
66
if ($docLocationElements === null) { continue; }
67
68
- $xpath = new \DOMXpath($documentForCSS);
69
- $linkTags = $xpath->query('/html/'.$docLocationTag.'/link[@rel="stylesheet"]');
70
if ($linkTags === null) { continue; }
71
72
foreach ($linkTags as $tagObject) {
@@ -78,22 +84,35 @@ class CombineCss
78
if (isset($linkAttributes['rel'], $linkAttributes['href']) && $linkAttributes['href']) {
79
$href = (string) $linkAttributes['href'];
80
81
- // 1) Check if there is any rel="preload" (Basic) connected to the rel="stylesheet"
82
- // making sure the file is not added to the final CSS combined file
83
84
- // 2) Only combine media "all" and the ones with no media
85
- // Do not combine media='only screen and (max-width: 768px)', media='print' etc.
86
- if (isset($linkAttributes['data-wpacu-to-be-preloaded-basic']) && $linkAttributes['data-wpacu-to-be-preloaded-basic']) {
87
- continue;
88
}
89
90
- // Separate each combined group by the "media" attribute; e.g. we don't want "all" and "print" mixed
91
- $mediaValue = (array_key_exists('media', $linkAttributes) && $linkAttributes['media']) ? $linkAttributes['media'] : 'all';
92
93
if (self::skipCombine($linkAttributes['href'])) {
94
continue;
95
}
96
97
// Was it optimized and has the URL updated? Check the Source URL to determine if it should be skipped from combining
98
if (isset($linkAttributes['data-wpacu-link-rel-href-before']) && $linkAttributes['data-wpacu-link-rel-href-before'] && self::skipCombine($linkAttributes['data-wpacu-link-rel-href-before'])) {
99
continue;
@@ -108,9 +127,16 @@ class CombineCss
108
109
// It will skip external stylesheets (from a different domain)
110
if ( $localAssetPath ) {
111
$combinedUriPathsGroup[$mediaValue][] = OptimizeCommon::getSourceRelPath($href);
112
$localAssetsPathsGroup[$mediaValue][$href] = $localAssetPath;
113
$linkHrefsGroup[$mediaValue][] = $href;
114
}
115
}
116
}
@@ -128,12 +154,14 @@ class CombineCss
128
129
$localAssetsPaths = $localAssetsPathsGroup[$mediaValue];
130
$linkHrefs = $linkHrefsGroup[$mediaValue];
131
132
- $shaOneForCombinedCss = self::generateShaOneForCombinedCss($combinedUriPaths);
133
134
$maybeDoCssCombine = self::maybeDoCssCombine(
135
$shaOneForCombinedCss,
136
$localAssetsPaths, $linkHrefs,
137
$docLocationTag
138
);
139
@@ -197,12 +225,32 @@ class CombineCss
197
$finalTagUrl = OptimizeCommon::filterWpContentUrl($cdnUrlForCss) . OptimizeCss::getRelPathCssCacheDir() . $storageJsonContentLocation['uri_to_final_css_file'];
198
199
$finalCssTagAttrs = array();
200
- $finalCssTagAttrs['rel'] = 'stylesheet';
201
- $finalCssTagAttrs['media'] = $mediaValue;
202
203
- $finalCssTag = <<<HTML
204
<link rel='stylesheet' id='wpacu-combined-css-{$docLocationTag}-{$groupLocation}' href='{$finalTagUrl}' type='text/css' media='{$mediaValue}' />
205
HTML;
206
// In case one (e.g. usually a developer) needs to alter it
207
$finalCssTag = apply_filters(
208
'wpacu_combined_css_tag',
@@ -215,18 +263,23 @@ HTML;
215
)
216
);
217
218
$htmlSourceBeforeAnyLinkTagReplacement = $htmlSource;
219
220
// Detect first LINK tag from the <$locationTag> and replace it with the final combined LINK tag
221
$firstLinkTag = OptimizeCss::getFirstLinkTag($storageJsonContentLocation['link_hrefs'][0], $htmlSource);
222
223
if ($firstLinkTag) {
224
- $htmlSource = str_replace($firstLinkTag, $finalCssTag, $htmlSource);
225
}
226
227
if ($htmlSource !== $htmlSourceBeforeAnyLinkTagReplacement) {
228
$htmlSource = self::stripJustCombinedLinkTags(
229
$storageJsonContentLocation['link_hrefs'],
230
$htmlSource
231
); // Strip the combined files to avoid duplicate code
232
@@ -247,11 +300,12 @@ HTML;
247
248
/**
249
* @param $filesSources
250
* @param $htmlSource
251
*
252
* @return mixed
253
*/
254
- public static function stripJustCombinedLinkTags($filesSources, $htmlSource)
255
{
256
preg_match_all('#<link[^>]*(stylesheet|preload)[^>]*(>)#Umi', $htmlSource, $matchesSourcesFromTags, PREG_SET_ORDER);
257
@@ -271,7 +325,7 @@ HTML;
271
$domTag->loadHTML($matchedSourceFromTag);
272
273
foreach ($domTag->getElementsByTagName('link') as $tagObject) {
274
- if (! $tagObject->hasAttributes()) { continue; }
275
276
foreach ($tagObject->attributes as $tagAttrs) {
277
if ($tagAttrs->nodeName === 'href') {
@@ -280,7 +334,7 @@ HTML;
280
if (in_array($relNodeValue, $filesSources)) {
281
$htmlSourceBeforeLinkTagReplacement = $htmlSource;
282
283
- $htmlSource = str_replace(array($matchedSourceFromTag."\n", $matchedSourceFromTag), '', $htmlSource);
284
285
if ($htmlSource !== $htmlSourceBeforeLinkTagReplacement) {
286
$linkTagsStrippedNo++;
@@ -345,19 +399,15 @@ HTML;
345
* @param $shaOneForCombinedCss
346
* @param $localAssetsPaths
347
* @param $linkHrefs
348
* @param $docLocationTag
349
*
350
* @return array
351
*/
352
- public static function maybeDoCssCombine($shaOneForCombinedCss, $localAssetsPaths, $linkHrefs, $docLocationTag)
353
{
354
- $current_user = wp_get_current_user();
355
- $dirToUserCachedFile = ((isset($current_user->ID) && $current_user->ID > 0) ? 'logged-in/' : '');
356
-
357
- $uriToFinalCssFile = $dirToUserCachedFile . $docLocationTag . '-' .$shaOneForCombinedCss . '.css';
358
-
359
- $localFinalCssFile = WP_CONTENT_DIR . OptimizeCss::getRelPathCssCacheDir() . $uriToFinalCssFile;
360
- $localDirForCssFile = WP_CONTENT_DIR . OptimizeCss::getRelPathCssCacheDir() . $dirToUserCachedFile;
361
362
// Only combine if $shaOneCombinedUriPaths.css does not exist
363
// If "?ver" value changes on any of the assets or the asset list changes in any way
@@ -379,6 +429,8 @@ HTML;
379
380
$finalCombinedCssContent .= '/*! '.str_replace(ABSPATH, '/', $localAssetsPath)." */\n";
381
$finalCombinedCssContent .= OptimizeCss::maybeFixCssContent($cssContent, $pathToAssetDir . '/') . "\n";
382
}
383
}
384
@@ -389,15 +441,9 @@ HTML;
389
$finalCombinedCssContent = FontsGoogleRemove::cleanFontFaceReferences($finalCombinedCssContent);
390
}
391
392
- if ($finalCombinedCssContent) {
393
- if ($dirToUserCachedFile !== '' && isset($current_user->ID) && $current_user->ID > 0 && ! is_dir($localDirForCssFile)) {
394
- $makeLocalDirForCss = @mkdir($localDirForCssFile);
395
-
396
- if (! $makeLocalDirForCss) {
397
- return array('uri_final_css_file' => '', 'local_final_css_file' => '');
398
- }
399
- }
400
401
FileSystem::file_put_contents($localFinalCssFile, $finalCombinedCssContent);
402
}
403
}
@@ -411,12 +457,100 @@ HTML;
411
412
/**
413
* @param $combinedUriPaths
414
*
415