function w3tc_popup(url, name, width, height) {
if (width === undefined) {
width = 800;
}
if (height === undefined) {
height = 600;
}
return window.open(url, name, 'width=' + width + ',height=' + height + ',status=no,toolbar=no,menubar=no,scrollbars=yes');
}
function w3tc_input_enable(input, enabled) {
jQuery(input).each(function() {
var me = jQuery(this);
if (enabled) {
me.removeAttr('disabled');
} else {
me.attr('disabled', 'disabled');
}
if (enabled) {
me.next('[type=hidden]').remove();
} else {
var t = me.attr('type');
if ((t != 'radio' && t != 'checkbox') || me.is(':checked')) {
me.after(jQuery('').attr({
type: 'hidden',
name: me.attr('name')
}).val(me.val()));
}
}
});
}
function w3tc_minify_js_file_clear() {
if (!jQuery('#js_files :visible').length) {
jQuery('#js_files_empty').show();
} else {
jQuery('#js_files_empty').hide();
}
}
function w3tc_minify_css_file_clear() {
if (!jQuery('#css_files :visible').length) {
jQuery('#css_files_empty').show();
} else {
jQuery('#css_files_empty').hide();
}
}
function w3tc_minify_js_file_add(theme, template, location, file) {
var append = jQuery('
File URI:
Template:
Embed Location:
' + (jQuery('#js_files li').length + 1) + '.
<\/li>');
append.find('input:text').val(file);
var select = append.find('.js_file_template');
for (var i in minify_templates[theme]) {
select.append(jQuery('').val(i).html(minify_templates[theme][i]));
}
select.val(template);
jQuery(append).find('.js_file_location').val(location);
jQuery('#js_files').append(append).find('li:last input:first').focus();
w3tc_minify_js_file_clear();
}
function w3tc_minify_css_file_add(theme, template, file) {
var append = jQuery('
File URI:
Template:
' + (jQuery('#css_files li').length + 1) + '.
<\/li>');
append.find('input:text').val(file);
var select = append.find('.css_file_template');
for (var i in minify_templates[theme]) {
select.append(jQuery('').val(i).html(minify_templates[theme][i]));
}
select.val(template);
jQuery('#css_files').append(append).find('li:last input:first').focus();
w3tc_minify_css_file_clear();
}
function w3tc_minify_js_theme(theme) {
jQuery('#js_themes').val(theme);
jQuery('#js_files :text').each(function() {
var input = jQuery(this);
if (input.attr('name').indexOf('js_files[' + theme + ']') != 0) {
input.parents('li').hide();
} else {
input.parents('li').show();
}
});
w3tc_minify_js_file_clear();
}
function w3tc_minify_css_theme(theme) {
jQuery('#css_themes').val(theme);
jQuery('#css_files :text').each(function() {
var input = jQuery(this);
if (input.attr('name').indexOf('css_files[' + theme + ']') != 0) {
input.parents('li').hide();
} else {
input.parents('li').show();
}
});
w3tc_minify_css_file_clear();
}
function w3tc_cdn_get_cnames() {
var cnames = [];
jQuery('#cdn_cnames input[type=text]').each(function() {
var cname = jQuery(this).val();
if (cname) {
var match = /^\*\.(.*)$/.exec(cname);
if (match) {
cnames = [];
for (var i = 1; i <= 10; i++) {
cnames.push('cdn' + i + '.' + match[1]);
}
return false;
}
cnames.push(cname);
}
});
return cnames;
}
function w3tc_cdn_cnames_assign() {
var li = jQuery('#cdn_cnames li'),
size = li.length;
if (size > 1) {
li.eq(0).find('.cdn_cname_delete').show();
} else {
li.eq(0).find('.cdn_cname_delete').hide();
}
jQuery(li).each(function(index) {
var label = '';
if (size > 1) {
switch (index) {
case 0:
label = '(reserved for CSS)';
break;
case 1:
label = '(reserved for JS in )';
break;
case 2:
label = '(reserved for JS after )';
break;
case 3:
label = '(reserved for JS before )';
break;
}
}
jQuery(this).find('span').text(label);
});
}
function w3tc_toggle(name, check) {
if (check === undefined) {
check = true;
}
var id = '#' + name,
cls = '.' + name;
jQuery(cls).on('click', function() {
var checked = check;
jQuery(cls).each(function() {
var _checked = jQuery(this).is(':checked');
if ((check && !_checked) || (!check && _checked)) {
checked = !check;
return false;
}
});
if (checked) {
jQuery(id).attr('checked', 'checked');
} else {
jQuery(id).removeAttr('checked');
}
});
jQuery(id).on('click', function() {
var checked = jQuery(this).is(':checked');
jQuery(cls).each(function() {
if (checked) {
jQuery(this).attr('checked', 'checked');
} else {
jQuery(this).removeAttr('checked');
}
});
});
}
function w3tc_toggle2(name, dependent_ids) {
var id = '#' + name,
dependants = '',
n;
for (n = 0; n < dependent_ids.length; n++)
dependants += (n > 0 ? ',' : '') + '#' + dependent_ids[n];
jQuery(dependants).on('click', function() {
var total_checked = true;
jQuery(dependants).each(function() {
var current_checked = jQuery(this).is(':checked');
if (!current_checked)
total_checked = false;
});
if (total_checked) {
jQuery(id).attr('checked', 'checked');
} else {
jQuery(id).removeAttr('checked');
}
});
jQuery(id).on('click', function() {
var checked = jQuery(this).is(':checked');
jQuery(dependants).each(function() {
if (checked) {
jQuery(this).attr('checked', 'checked');
} else {
jQuery(this).removeAttr('checked');
}
});
});
}
function w3tc_beforeupload_bind() {
jQuery(window).bind('beforeunload', w3tc_beforeunload);
}
function w3tc_beforeupload_unbind() {
jQuery(window).off('beforeunload', w3tc_beforeunload);
}
function w3tc_beforeunload() {
return 'Navigate away from this page without saving your changes?';
}
function w3tc_starts_with(s, starts_with) {
s = s.replace(/\n/g, '');
s = s.replace(/\s/g, '');
return s.substr(0, starts_with.length) == starts_with;
}
function w3tc_security_headers() {
var directive_description = {
browsercache_security_hsts_directive: {
maxage: 'The time, in seconds (as defined under the "Expires Header Lifetime" box of "Media & Other Files"), that the browser should remember that this site is only to be accessed using HTTPS. This only affects the site\'s main domain.',
maxagepre: 'The time, in seconds (as defined under the "Expires Header Lifetime" box of "Media & Other Files"), that the browser should remember that this site is only to be accessed using HTTPS with a request to be included in Chrome\'s HSTS preload list - a list of sites that are hardcoded into Chrome as being https only. This only affects the site\'s main domain.',
maxageinc: 'The time, in seconds (as defined under the "Expires Header Lifetime" box of "Media & Other Files"), that the browser should remember that this site is only to be accessed using HTTPS. This affects the site\'s subdomains as well.',
maxageincpre: 'The time, in seconds (as defined under the "Expires Header Lifetime" box of "Media & Other Files"), that the browser should remember that this site is only to be accessed using HTTPS with a request to be included in Chrome\'s HSTS preload list - a list of sites that are hardcoded into Chrome as being https only. This affects the site\'s subdomains as well.'
},
browsercache_security_xfo_directive: {
same: "The page can only be displayed in a frame on the same origin as the page itself.",
deny: "The page cannot be displayed in a frame, regardless of the site attempting to do so.",
allow: "The page can only be displayed in a frame on the specified URL."
},
browsercache_security_xss_directive: {
0: "Disables XSS filtering.",
1: "Enables XSS filtering (usually default in browsers). If a cross-site scripting attack is detected, the browser will sanitize the page (remove the unsafe parts).",
block: "Enables XSS filtering. Rather than sanitizing the page, the browser will prevent rendering of the page if an attack is detected."
},
browsercache_security_pkp_extra: {
maxage: 'The time, in seconds (as defined under the "Expires Header Lifetime" box of "Media & Other Files"), that the browser should remember that this site is only to be accessed using one of the defined keys. This only affects the site\'s main domain.',
maxageinc: 'The time, in seconds (as defined under the "Expires Header Lifetime" box of "Media & Other Files"), that the browser should remember that this site is only to be accessed using one of the defined keys. This affects the site\'s subdomains as well.'
},
browsercache_security_pkp_report_only: {
0: 'This instructs the browser to enforce the HPKP policy.',
1: 'This sets up HPKP without enforcement allowing you to use pinning to test its impact without the risk of a failed connection caused by your site being unreachable or HPKP being misconfigured.'
}
};
jQuery('#browsercache_security_hsts_directive,#browsercache_security_xfo_directive,#browsercache_security_xss_directive,#browsercache_security_pkp_extra,#browsercache_security_pkp_report_only').on('change',
function() {
jQuery('#' + jQuery(this).attr('id') + '_description').html('' + directive_description[jQuery(this).attr('id')][jQuery(this).val()] + '');
if (jQuery(this).attr('id') == 'browsercache_security_xfo_directive') {
if (jQuery(this).val() == 'allow') {
jQuery('#browsercache_security_xfo_allow').show();
} else {
jQuery('#browsercache_security_xfo_allow').hide();
}
}
});
if (jQuery('#browsercache_security_xfo_allow').length) {
if (jQuery('#browsercache_security_xfo_directive').val() == 'allow') {
jQuery('#browsercache_security_xfo_allow').show();
} else {
jQuery('#browsercache_security_xfo_allow').hide();
}
}
}
function w3tc_csp_reference() {
W3tc_Lightbox.open({
id: 'w3tc-overlay',
close: '',
width: 890,
height: 460,
url: ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce +
'&w3tc_action=browsercache_quick_reference',
callback: function(lightbox) {
lightbox.resize();
}
});
jQuery('div#overlay,.lightbox-content').on('click', function() {
W3tc_Lightbox.close();
});
}
/**
* Bunny CDN check.
*
* Prevent enabling Bunny CDN ("bunnycdn" engine) for both CDN and CDNFSD.
*
* @since 2.6.0
*
* @returns null
*/
function cdn_bunnycdn_check() {
// Prevents JS error for non W3TC pages.
if (typeof w3tcData === 'undefined') {
return;
}
var $cdn_enabled = jQuery('#cdn__enabled'),
$cdn_engine = jQuery('#cdn__engine'),
$cdnfsd_enabled = jQuery('#cdnfsd__enabled'),
$cdnfsd_engine = jQuery('#cdnfsd__engine'),
cdn_enabled = $cdn_enabled.is(':checked'),
cdn_engine = $cdn_engine.find(':selected').val(),
cdnfsd_enabled = $cdnfsd_enabled.is(':checked'),
cdnfsd_engine = $cdnfsd_engine.find(':selected').val(),
$cdn_inside = jQuery('#cdn .inside');
if (cdn_enabled && cdnfsd_enabled && 'bunnycdn' === cdn_engine && cdnfsd_engine === cdn_engine ) {
// Reset to what was last saved.
$cdn_enabled.prop('checked', w3tcData.cdnEnabled);
$cdn_engine.val(w3tcData.cdnEngine).change();
$cdnfsd_enabled.prop('checked', w3tcData.cdnfsdEnabled);
$cdnfsd_engine.val(w3tcData.cdnfsdEngine).change();
// Display a warning.
jQuery('', {
class: 'notice notice-warning',
id: 'w3tc-bunnycdn-warning',
text: w3tcData.bunnyCdnWarning
}).prependTo($cdn_inside);
} else {
// Remove the warning.
jQuery('#w3tc-bunnycdn-warning').remove();
}
}
/**
* Cloudfront CDN check.
*
* When CDN is enabled as "cf" or "cf2", then display a notice about possible charges.
*
* @returns null
*/
function cdn_cf_check() {
// Prevents JS error for non W3TC pages.
if (typeof w3tcData === 'undefined') {
return;
}
var cdnEnabled = jQuery('#cdn__enabled').is(':checked'),
cdnEngine = jQuery('#cdn__engine').find(':selected').val(),
cdnFlushManually = jQuery('[name="cdn__flush_manually"]').is(':checked');
// Remove any cf admin notices.
jQuery('.w3tc-cf-notice').remove();
// General page.
if (!w3tcData.cdnFlushManually && cdnEnabled && ('cf' === cdnEngine || 'cf2' === cdnEngine)) {
// Print cf admin notice.
jQuery('#cdn .inside').prepend(
'
' +
w3tcData.cfWarning +
'
'
);
}
// CDN page.
if (!cdnFlushManually && w3tcData.cdnEnabled && ('cf' === w3tcData.cdnEngine || 'cf2' === w3tcData.cdnEngine)) {
// Show warning on the CDN page for flush manually.
jQuery('#cdn-flushmanually-warning').show();
} else {
// Hide warning on the CDN page for flush manually.
jQuery('#cdn-flushmanually-warning').hide();
}
}
function set_sticky_bar_positions() {
jQuery('#w3tc > #w3tc-options-menu').css(
'top',
Math.floor(
((jQuery(window).width() > 600 && jQuery('#wpadminbar').length) ? jQuery('#wpadminbar').outerHeight() : 0) +
jQuery('#w3tc-top-nav-bar').outerHeight()
)
);
jQuery('.w3tc_form_bar').css(
'top',
Math.floor(
((jQuery(window).width() > 600 && jQuery('#wpadminbar').length) ? jQuery('#wpadminbar').outerHeight() : 0) +
jQuery('#w3tc-top-nav-bar').outerHeight() +
((jQuery('#w3tc > #w3tc-options-menu').length) ? jQuery('#w3tc > #w3tc-options-menu').outerHeight() : 0)
)
);
}
function set_footer_position() {
jQuery('#w3tc-footer').insertAfter(jQuery('#wpfooter'));
jQuery('#w3tc-footer').css(
'bottom',
Math.floor(0 - jQuery('#w3tc-footer').outerHeight())
);
}
function debounce(func){
var timer;
return function(event){
if(timer){
clearTimeout(timer);
}
timer = setTimeout(func,100,event);
};
}
/**
* Get the S3 bucket region from the selected location to be used for the hostname.
*
* The default location (us-east-1) returns an empty string. All other regions return the region with a trailing dot.
*
* @since 2.7.4
*
* @param {string} location Bucket location.
* @returns string
*/
function get_bucket_region( location ) {
let region = '';
switch ( location ) {
case 'us-east-1':
break;
case 'us-east-1-e':
region = 'us-east-1.';
break;
default:
region = location + '.';
break;
}
return region;
}
/**
* Event callback for changing CDN Cloudfront (push) S3 bucket location.
*
* @since 2.7.2
*
* @see get_bucket_region()
*/
function cdn_cf_bucket_location() {
const id = jQuery( '#cdn_cf_bucket' ).val();
jQuery( '#cdn-cf-bucket-hostname' )
.text( id + '.s3.' + get_bucket_region( jQuery( '#cdn_cf_bucket_location' ).val() ) + 'amazonaws.com' );
}
/**
* Toggle the disk notice for dbcache.
*
* @since 2.8.0
*/
function toggle_dbcache_notice() {
if ( jQuery('#dbcache__engine').val() === 'file' && jQuery('#dbcache__enabled').is(':checked') ) {
jQuery('.dbcache_disk_notice').show();
} else {
jQuery('.dbcache_disk_notice').hide();
}
}
/**
* Toggle the disk notice for objectcache.
*
* @since 2.8.0
*/
function toggle_objectcache_notice() {
if ( jQuery('#objectcache__engine').val() === 'file' && jQuery('#objectcache__enabled').is(':checked') ) {
jQuery('.objectcache_disk_notice').show();
} else {
jQuery('.objectcache_disk_notice').hide();
}
}
// On document ready.
jQuery(function() {
// Global vars.
var $cdn_enabled = jQuery('#cdn__enabled'),
$cdn_engine = jQuery('#cdn__engine');
// Database cache disk usage warning.
toggle_dbcache_notice();
jQuery('#dbcache__enabled').change(toggle_dbcache_notice);
jQuery('#dbcache__engine').change(toggle_dbcache_notice);
// Object cache disk usage warning.
toggle_objectcache_notice();
jQuery('#objectcache__enabled').change(toggle_objectcache_notice);
jQuery('#objectcache__engine').change(toggle_objectcache_notice);
// General page.
jQuery('.w3tc_read_technical_info').on('click', function() {
jQuery('.w3tc_technical_info').toggle();
});
jQuery('#plugin_license_key_verify').on('click', function() {
jQuery('.w3tc_license_verification').html("Checking...");
var license_key = jQuery('#plugin_license_key').val();
if (!license_key) {
jQuery('.w3tc_license_verification').html('Please enter an license key and try again.');
return;
}
var params = {
action: 'w3tc_verify_plugin_license_key',
license_key: license_key
};
jQuery.get(ajaxurl, params, function(data) {
if (w3tc_starts_with(data + '.', 'inactive.expired.')) {
jQuery('.w3tc_license_verification').html('The license key has expired. Please renew it.');
} else if (w3tc_starts_with(data + '.', 'active.')) {
jQuery('.w3tc_license_verification').html('License key is correct.');
} else if (w3tc_starts_with(data + '.', 'inactive.by_rooturi.activations_limit_not_reached.')) {
jQuery('.w3tc_license_verification').html('License key is correct and can be activated now.');
} else if (w3tc_starts_with(data + '.', 'inactive.by_rooturi.')) {
jQuery('.w3tc_license_verification').html('License key is correct but already in use on another site. See the FAQ for how to enable Pro version in development mode.');
} else {
jQuery('.w3tc_license_verification').html('The license key is not valid. Please check it and try again.');
}
}).fail(function() {
jQuery('.w3tc_license_verification').html('Check failed');
});
});
// General Settings Tab actions.
jQuery( document ).on( 'click', '.performance_page_w3tc_general .nav-tab', function(){
const $tab = jQuery( this ),
$nav_tab_wrapper = $tab.closest( ".nav-tab-wrapper" )
tab_type = $tab.attr( "data-tab-type" ),
$inside = $tab.closest( ".postbox-tabs" ).find( ".inside" );
// Highlight the selected tab.
$nav_tab_wrapper.find( "a" ).removeClass( "nav-tab-active" );
$tab.addClass( "nav-tab-active" );
// If the tab is a link, don't do anything.
if ( $tab.is('[href]') ) {
return;
}
// Start off by hiding everything.
$inside.children().hide();
if (! tab_type) {
// Show children without a data-tab-type attribute.
$inside.children(':not([data-tab-type])').show(); // Show those without data-tab-type
} else {
// Show children with the matching data-tab-type attribute.
$inside.children('[data-tab-type="' + tab_type + '"]').show();
}
} );
// Tutorial page forum links via API.
jQuery(document).on( 'click', '[data-tab-type="help"]', function() {
const $helpTab = jQuery( this ),
$inside = $helpTab.closest( ".postbox-tabs" ).find( ".inside" );
$forumTopicsContainer = $inside.find( '.help-forum-topics' );
isLoaded = $forumTopicsContainer.attr( 'data-loaded' ) === "1";
tabId = $forumTopicsContainer.attr( 'data-tab-id' );
// Check if topics are already loaded
if ( isLoaded ) return;
// Construct the API URL with the tab ID
const apiUrl = `https://boldgrid.com/support/wp-json/w3tc/v1/help_topics?tag=${tabId}`;
// Fetch topics from the API
jQuery.ajax({
url: apiUrl,
method: 'GET',
dataType: 'json',
success: function( data ) {
// Check for errors or empty results
if ( Array.isArray( data ) && data.length === 0 ) {
$forumTopicsContainer.html( "
No forum topics found.
" );
} else {
// Create a list of topics
const $ul = jQuery( '