W3 Total Cache - Version 0.14.4

Version Description

  • Fix: Cleanup widget and postbox display for WordPress 5.5
  • Fix: Update to PageSpeed API v5, show webvitals metrics
  • Fix: Console error when adminbar is hidden and PageSpeed module is active
  • Fix: Stats view JS issue
  • Fix: Deprecated jQuery warnings
  • Fix: Require files for request_filesystem_credentials() call
  • Added option to disable jquery-migrate on the front-end. Fixed #172 master (#240)
Download this release

Release Info

Developer joemoto
Plugin Icon 128x128 W3 Total Cache
Version 0.14.4
Comparing to
See all releases

Code changes from version 0.14.3 to 0.14.4

ConfigKeys.php CHANGED
@@ -2417,7 +2417,10 @@ $keys = array(
2417
  'default' => '',
2418
  'master_only' => true
2419
  ),
2420
-
 
 
 
2421
 
2422
  // extensions keys:
2423
  //
2417
  'default' => '',
2418
  'master_only' => true
2419
  ),
2420
+ 'jquerymigrate.disabled' => array(
2421
+ 'type' => 'boolean',
2422
+ 'default' => false,
2423
+ ),
2424
 
2425
  // extensions keys:
2426
  //
Extension_CloudFlare_Page_View.js CHANGED
@@ -33,10 +33,10 @@ jQuery(function($) {
33
 
34
 
35
  .on('click', '.w3tc_cloudflare_zone_page', function() {
36
- var page = jQuery(this).attr('data-page');
37
  jQuery('input[name="w3tc_action"]').val('extension_cloudflare_intro_done');
38
  jQuery('input[name="page"]').val(page);
39
-
40
  var url = ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce;
41
 
42
  W3tc_Lightbox.load_form(url, '.w3tc_extension_cloudflare_form',
33
 
34
 
35
  .on('click', '.w3tc_cloudflare_zone_page', function() {
36
+ var page = jQuery(this).data('page');
37
  jQuery('input[name="w3tc_action"]').val('extension_cloudflare_intro_done');
38
  jQuery('input[name="page"]').val(page);
39
+
40
  var url = ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce;
41
 
42
  W3tc_Lightbox.load_form(url, '.w3tc_extension_cloudflare_form',
Generic_Plugin_Admin.php CHANGED
@@ -203,8 +203,8 @@ class Generic_Plugin_Admin {
203
  $score = apply_filters( 'w3tc_monitoring_score', $score );
204
 
205
  header( "Content-Type: application/x-javascript; charset=UTF-8" );
206
- echo 'document.getElementById("w3tc_monitoring_score").innerHTML = "' .
207
- strtr( $score, '"', '.' ) . '";';
208
 
209
  exit();
210
  }
203
  $score = apply_filters( 'w3tc_monitoring_score', $score );
204
 
205
  header( "Content-Type: application/x-javascript; charset=UTF-8" );
206
+ echo 'document.getElementById("w3tc_monitoring_score") && ( document.getElementById("w3tc_monitoring_score").innerHTML = "' .
207
+ strtr( $score, '"', '.' ) . '" );';
208
 
209
  exit();
210
  }
Generic_WidgetBoldGrid_View.js CHANGED
@@ -8,10 +8,12 @@ jQuery( document ).ready( function( $ ) {
8
  return;
9
  }
10
 
11
- try {
12
- message = $.parseJSON( originalEvent.data );
13
- } catch ( e ) {
14
- return;
 
 
15
  }
16
 
17
  if ( ! message || 'undefined' === typeof message.action ) {
@@ -19,7 +21,7 @@ jQuery( document ).ready( function( $ ) {
19
  }
20
 
21
  if (message.action == 'install-plugin') {
22
- window.location = $('#w3tc-boldgrid-install').attr('href');
23
  }
24
  });
25
  });
8
  return;
9
  }
10
 
11
+ if ( originalEvent.data ) {
12
+ try {
13
+ message = $.parseJSON( originalEvent.data );
14
+ } catch ( e ) {
15
+ return;
16
+ }
17
  }
18
 
19
  if ( ! message || 'undefined' === typeof message.action ) {
21
  }
22
 
23
  if (message.action == 'install-plugin') {
24
+ window.location = $('#w3tc-boldgrid-install').prop('href');
25
  }
26
  });
27
  });
PageSpeed_Api.php CHANGED
@@ -4,7 +4,7 @@ namespace W3TC;
4
  /**
5
  * Google Page Speed API
6
  */
7
- define( 'W3TC_PAGESPEED_API_URL', 'https://www.googleapis.com/pagespeedonline/v1/runPagespeed' );
8
 
9
  /**
10
  * class PageSpeed_Api
@@ -14,269 +14,115 @@ class PageSpeed_Api {
14
  * API Key
15
  */
16
  private $key = '';
17
-
18
  /**
19
  * Referrer for key restricting
20
  */
21
  private $key_restrict_referrer = '';
22
 
23
- /**
24
- * PHP5-style constructor
25
- */
26
  function __construct( $api_key, $api_ref ) {
27
  $this->key = $api_key;
28
  $this->key_restrict_referrer = $api_ref;
29
  }
30
 
31
- /**
32
- * Analyze URL
33
- */
34
- function analyze( $url ) {
35
- $json = $this->_request( $url );
36
- if ( !$json )
37
- return null;
38
 
39
- $results = $this->_parse( $json );
40
- if ( $results )
41
- $this->_sort( $results );
42
 
43
- return $results;
 
 
 
 
 
 
 
44
  }
45
 
46
- /**
47
- * Make API request
48
- *
49
- * @param string $url
50
- * @return string
51
- */
52
- function _request( $url ) {
53
- $request_url = Util_Environment::url_format( W3TC_PAGESPEED_API_URL, array(
54
- 'url' => $url,
55
- 'key' => $this->key,
56
- ) );
57
 
58
- $response = Util_Http::get( $request_url, array(
59
- 'timeout' => 120,
60
- 'headers' => array( 'Referer' => $this->key_restrict_referrer )
 
 
 
61
  ) );
62
 
63
- if ( !is_wp_error( $response ) && $response['response']['code'] == 200 ) {
64
- return $response['body'];
65
  }
66
 
67
- return false;
68
- }
69
-
70
- /**
71
- * Parse response
72
- *
73
- * @param string $json
74
- * @return array|bool
75
- */
76
- function _parse( $json ) {
77
- $data = json_decode( $json );
78
- $results = false;
79
-
80
- if ( isset( $data->formattedResults ) ) {
81
- $results = array(
82
- 'url' => $data->id,
83
- 'code' => $data->responseCode,
84
- 'title' => $data->title,
85
- 'score' => $data->score,
86
- 'rules' => array()
87
- );
88
-
89
- foreach ( (array) $data->formattedResults->ruleResults as $i => $rule_result ) {
90
- $results['rules'][$i] = array(
91
- 'name' => $rule_result->localizedRuleName,
92
- 'impact' => $rule_result->ruleImpact,
93
- 'priority' => $this->_get_priority( $rule_result->ruleImpact ),
94
- 'resolution' => $this->_get_resolution( $rule_result->localizedRuleName ),
95
- 'blocks' => array()
96
- );
97
-
98
- if ( isset( $rule_result->urlBlocks ) ) {
99
- foreach ( (array) $rule_result->urlBlocks as $j => $url_block ) {
100
- $args = isset( $url_block->header->args ) ? $url_block->header->args : array();
101
- $results['rules'][$i]['blocks'][$j] = array(
102
- 'header' => $this->_format_string( $url_block->header->format, $args ),
103
- 'urls' => array()
104
- );
105
-
106
- if ( isset( $url_block->urls ) ) {
107
- foreach ( (array) $url_block->urls as $k => $url ) {
108
- $args = isset( $url->result->args ) ? $url->result->args : array();
109
- $results['rules'][$i]['blocks'][$j]['urls'][$k] = array(
110
- 'result' => $this->_format_string( $url->result->format, $args )
111
- );
112
- }
113
- }
114
- }
115
- }
116
- }
117
  }
118
 
119
- return $results;
 
 
 
120
  }
121
 
122
- /**
123
- * Returns rule priority by impact
124
- *
125
- * @param float $impact
126
- * @return string
127
- */
128
- function _get_priority( $impact ) {
129
- if ( $impact < 3 ) {
130
- $priority = 'low';
131
- } elseif ( $impact >= 3 && $impact <= 10 ) {
132
- $priority = 'medium';
133
- } else {
134
- $priority = 'high';
135
- }
136
 
137
- return $priority;
138
- }
139
 
140
- /**
141
- * Returns resolution
142
- *
143
- * @param string $code
144
- * @return array
145
- */
146
- function _get_resolution( $code ) {
147
- switch ( $code ) {
148
- case 'MinifyHTML':
149
- return array(
150
- 'header' => 'Enable HTML Minify',
151
- 'tab' => 'minify'
152
- );
153
-
154
- case 'MinifyJavaScript':
155
- case 'DeferParsingJavaScript':
156
- return array(
157
- 'header' => 'Enable JavaScript Minify',
158
- 'tab' => 'minify'
159
- );
160
-
161
- case 'MinifyCss':
162
- case 'PutCssInTheDocumentHead':
163
- return array(
164
- 'header' => 'Enable CSS Minify',
165
- 'tab' => 'minify'
166
- );
167
-
168
- case 'AvoidCssImport':
169
- return array(
170
- 'header' => 'Enable CSS Minify and @import processing',
171
- 'tab' => 'minify'
172
- );
173
-
174
- case 'OptimizeTheOrderOfStylesAndScripts':
175
- return array(
176
- 'header' => 'Enable JavaScript and CSS Minify',
177
- 'tab' => 'minify'
178
- );
179
-
180
- case 'PreferAsyncResources':
181
- return array(
182
- 'header' => 'Switch to non-blocking JavaScript embedding',
183
- 'tab' => 'minify'
184
- );
185
-
186
- case 'RemoveQueryStringsFromStaticResources':
187
- return array(
188
- 'header' => 'Disable the "Prevent caching of objects after settings change" feature',
189
- 'tab' => 'browsercache'
190
- );
191
 
192
- case 'LeverageBrowserCaching':
193
- return array(
194
- 'header' => 'Enable the expires header on the Browser Cache Settings tab',
195
- 'tab' => 'browsercache'
196
- );
197
 
198
- case 'SpecifyACacheValidator':
199
- return array(
200
- 'header' => 'Enable the ETag header on the Browser Cache Settings tab',
201
- 'tab' => 'browsercache'
202
- );
203
  }
204
 
205
- return array();
206
  }
207
 
208
- private $_format_string_args = array();
209
-
210
- /**
211
- * Formats string
212
- *
213
- * @param string $format
214
- * @param array $args
215
- * @return mixed
216
- */
217
- function _format_string( $format, $args ) {
218
- $result = $format;
219
- if ( !empty( $args ) ) {
220
- $this->_format_string_args = $args;
221
-
222
- $result = preg_replace_callback( '~\$([0-9]+)~', array(
223
- $this,
224
- '_format_string_callback'
225
- ), $format );
226
- }
227
 
228
- return $result;
229
- }
230
 
231
  /**
232
- * Format string callback
233
  *
234
- * @param array $matches
235
  * @return string
236
  */
237
- function _format_string_callback( $matches ) {
238
- $index = (int) $matches[1] - 1;
 
 
 
239
 
240
- if ( isset( $this->_format_string_args[$index]->value ) ) {
241
- switch ( $this->_format_string_args[$index]->type ) {
242
- case 'URL':
243
- return sprintf( '<a href="%s">%s</a>', $this->_format_string_args[$index]->value, $this->_format_string_args[$index]->value );
244
 
245
- default:
246
- return $this->_format_string_args[$index]->value;
247
- }
248
  }
249
 
250
- return $matches[0];
251
  }
252
 
253
- /**
254
- * Sort results
255
- *
256
- * @param array $results
257
- * @return void
258
- */
259
- function _sort( &$results ) {
260
- if ( isset( $results['rules'] ) ) {
261
- usort( $results['rules'], array(
262
- $this,
263
- '_sort_cmp'
264
- ) );
265
  }
266
- }
267
 
268
- /**
269
- * Compare function
270
- *
271
- * @param array $rule_result1
272
- * @param array $rule_result2
273
- * @return int
274
- */
275
- function _sort_cmp( &$rule_result1, &$rule_result2 ) {
276
- if ( $rule_result1['impact'] == $rule_result2['impact'] ) {
277
- return 0;
278
  }
279
 
280
- return ( $rule_result1['impact'] > $rule_result2['impact'] ) ? -1 : 1;
281
  }
282
  }
4
  /**
5
  * Google Page Speed API
6
  */
7
+ define( 'W3TC_PAGESPEED_API_URL', 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed' );
8
 
9
  /**
10
  * class PageSpeed_Api
14
  * API Key
15
  */
16
  private $key = '';
 
17
  /**
18
  * Referrer for key restricting
19
  */
20
  private $key_restrict_referrer = '';
21
 
22
+
23
+
 
24
  function __construct( $api_key, $api_ref ) {
25
  $this->key = $api_key;
26
  $this->key_restrict_referrer = $api_ref;
27
  }
28
 
 
 
 
 
 
 
 
29
 
 
 
 
30
 
31
+ public function analyze( $url ) {
32
+ return array(
33
+ 'mobile' => $this->analyze_strategy( $url, 'mobile' ),
34
+ 'desktop' => $this->analyze_strategy( $url, 'desktop' ),
35
+ 'test_url' => Util_Environment::url_format(
36
+ 'https://developers.google.com/speed/pagespeed/insights/',
37
+ array( 'url' => $url ) )
38
+ );
39
  }
40
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+
43
+ public function analyze_strategy( $url, $strategy ) {
44
+ $json = $this->_request( array(
45
+ 'url' => $url,
46
+ 'category' => 'performance',
47
+ 'strategy' => $strategy
48
  ) );
49
 
50
+ if ( !$json ) {
51
+ return null;
52
  }
53
 
54
+ $data = array();
55
+ try {
56
+ $data = json_decode( $json, true );
57
+ } catch ( \Exception $e ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  }
59
 
60
+ return array(
61
+ 'score' => $this->v( $data, array( 'lighthouseResult', 'categories', 'performance', 'score' ) ) * 100,
62
+ 'metrics' => $this->v( $data, array( 'loadingExperience', 'metrics' ) )
63
+ );
64
  }
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
 
 
67
 
68
+ public function get_page_score( $url ) {
69
+ $json = $this->_request( array(
70
+ 'url' => $url,
71
+ 'category' => 'performance',
72
+ 'strategy' => 'desktop'
73
+ ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
+ if ( !$json ) {
76
+ return null;
77
+ }
 
 
78
 
79
+ $data = array();
80
+ try {
81
+ $data = json_decode( $json, true );
82
+ } catch ( \Exception $e ) {
 
83
  }
84
 
85
+ return $this->v( $data, array( 'lighthouseResult', 'categories', 'performance', 'score' ) );
86
  }
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
 
 
89
 
90
  /**
91
+ * Make API request
92
  *
93
+ * @param string $url
94
  * @return string
95
  */
96
+ function _request( $query ) {
97
+ $request_url = Util_Environment::url_format( W3TC_PAGESPEED_API_URL,
98
+ array_merge( $query, array(
99
+ 'key' => $this->key
100
+ ) ) );
101
 
102
+ $response = Util_Http::get( $request_url, array(
103
+ 'timeout' => 120,
104
+ 'headers' => array( 'Referer' => $this->key_restrict_referrer )
105
+ ) );
106
 
107
+ if ( !is_wp_error( $response ) && $response['response']['code'] == 200 ) {
108
+ return $response['body'];
 
109
  }
110
 
111
+ return false;
112
  }
113
 
114
+
115
+
116
+ function v( $data, $elements ) {
117
+ if ( empty( $elements ) ) {
118
+ return $data;
 
 
 
 
 
 
 
119
  }
 
120
 
121
+ $key = array_shift( $elements );
122
+ if ( !isset( $data[$key] ) ) {
123
+ return null;
 
 
 
 
 
 
 
124
  }
125
 
126
+ return $this->v( $data[$key], $elements );
127
  }
128
  }
PageSpeed_Plugin_Widget.php CHANGED
@@ -79,51 +79,39 @@ class PageSpeed_Plugin_Widget {
79
 
80
 
81
  public function w3tc_ajax_pagespeed_widgetdata() {
 
82
  if ( Util_Request::get( 'cache' ) != 'no' ) {
83
- $response = get_transient( 'w3tc_pagespeed_widgetdata' );
84
- $response = @json_decode( $response, true );
85
- if ( is_array( $response ) && isset( $response['time'] ) &&
86
- $response['time'] >= time() - 60 ) {
87
- echo json_encode( $response );
88
- return;
89
  }
90
  }
91
 
92
- $config = Dispatcher::config();
93
- $key = $config->get_string( 'widget.pagespeed.key' );
94
- $ref = $config->get_string( 'widget.pagespeed.key.restrict.referrer' );
 
95
 
96
- $w3_pagespeed = new PageSpeed_Api( $key, $ref );
97
- $r = $w3_pagespeed->analyze( get_home_url() );
98
 
99
- if ( !$r ) {
100
- echo json_encode( array( 'error' => 'API call failed' ) );
101
- return;
102
- }
103
 
104
- $details = '<ul class="w3tc-widget-ps-rules">';
105
- foreach ( $r['rules'] as $index => $rule ) {
106
- if ( $index >= 5 )
107
- break;
108
-
109
- $details .=
110
- '<li class="w3tc-widget-ps-rule w3tc-widget-ps-priority-' .
111
- $rule['priority'] . '">' .
112
- '<div class="w3tc-widget-ps-icon"><div></div></div>' .
113
- '<p>' . $rule['name'] . '</p>' .
114
- '</li>';
115
  }
116
 
117
- $details .= '</ul>';
118
-
119
- $response = array(
120
- 'score' => $r['score'] . ' / 100',
121
- 'details' => $details,
122
- 'time' => time()
123
- );
124
 
125
- set_transient( 'w3tc_pagespeed_widgetdata', json_encode( $response ), 60 );
126
- echo json_encode( $response );
127
  }
128
 
129
 
@@ -132,7 +120,7 @@ class PageSpeed_Plugin_Widget {
132
  if ( empty( $_SERVER['HTTP_REFERER'] ) ) {
133
  return 'n/a';
134
  }
135
-
136
  $url = $_SERVER['HTTP_REFERER'];
137
 
138
  $config = Dispatcher::config();
@@ -140,10 +128,11 @@ class PageSpeed_Plugin_Widget {
140
  $ref = $config->get_string( 'widget.pagespeed.key.restrict.referrer' );
141
  $w3_pagespeed = new PageSpeed_Api( $key, $ref );
142
 
143
- $r = $w3_pagespeed->analyze( $url );
144
 
145
- if ( $r )
146
- $score .= $r['score'] . ' / 100';
 
147
 
148
  return $score;
149
  }
79
 
80
 
81
  public function w3tc_ajax_pagespeed_widgetdata() {
82
+ $api_response = null;
83
  if ( Util_Request::get( 'cache' ) != 'no' ) {
84
+ $r = get_transient( 'w3tc_pagespeed_widgetdata' );
85
+ $r = @json_decode( $r, true );
86
+ if ( is_array( $r ) && isset( $r['time'] ) &&
87
+ $r['time'] >= time() - 3600 ) {
88
+ $api_response = $r;
 
89
  }
90
  }
91
 
92
+ if ( is_null( $api_response ) ) {
93
+ $config = Dispatcher::config();
94
+ $key = $config->get_string( 'widget.pagespeed.key' );
95
+ $ref = $config->get_string( 'widget.pagespeed.key.restrict.referrer' );
96
 
97
+ $w3_pagespeed = new PageSpeed_Api( $key, $ref );
98
+ $api_response = $w3_pagespeed->analyze( get_home_url() );
99
 
100
+ if ( !$api_response ) {
101
+ echo json_encode( array( 'error' => 'API call failed' ) );
102
+ return;
103
+ }
104
 
105
+ $api_response['time'] = time();
106
+ set_transient( 'w3tc_pagespeed_widgetdata', json_encode( $api_response ), 3600 );
 
 
 
 
 
 
 
 
 
107
  }
108
 
109
+ ob_start();
110
+ include W3TC_DIR . '/PageSpeed_Widget_View_FromApi.php';
111
+ $content = ob_get_contents();
112
+ ob_end_clean();
 
 
 
113
 
114
+ echo json_encode( array( '.w3tcps_content' => $content ) );
 
115
  }
116
 
117
 
120
  if ( empty( $_SERVER['HTTP_REFERER'] ) ) {
121
  return 'n/a';
122
  }
123
+
124
  $url = $_SERVER['HTTP_REFERER'];
125
 
126
  $config = Dispatcher::config();
128
  $ref = $config->get_string( 'widget.pagespeed.key.restrict.referrer' );
129
  $w3_pagespeed = new PageSpeed_Api( $key, $ref );
130
 
131
+ $r = $w3_pagespeed->get_page_score( $url );
132
 
133
+ if ( !is_null( $r ) ) {
134
+ $score .= (int)((float)$r * 100) . ' / 100';
135
+ }
136
 
137
  return $score;
138
  }
PageSpeed_Widget_View.css CHANGED
@@ -2,69 +2,59 @@
2
  position: absolute;
3
  }
4
 
5
- .w3tc-widget-ps-rules {
6
- margin: 1em 0;
7
- background: #fff url(pub/img/ps_bar.gif) repeat-y;
 
8
  }
9
 
10
- .w3tc-widget-ps-rules a {
11
- color: #00f;
12
- text-decoration: none;
13
  }
14
 
15
- .w3tc-widget-ps-rules li,
16
- .w3tc-widget-ps-rules p {
17
- margin: 0;
18
  }
19
 
20
- .w3tc-widget-ps-rule {
21
- line-height: 20px;
22
- clear: left;
23
  }
24
 
25
- .w3tc-widget-ps-rule p {
26
- margin-left: 40px;
27
- line-height: 20px;
28
- height: 20px;
29
- overflow: hidden;
30
  }
31
 
32
- .w3tc-widget-ps-icon {
33
- width: 31px;
34
- height: 20px;
35
- position: relative;
36
- float: left;
37
  }
38
 
39
- .w3tc-widget-ps-icon div {
40
- display: block;
41
- background: url(pub/img/ps_scores.png);
42
- width: 14px;
43
- height: 14px;
44
- position: relative;
45
- top: 3px;
46
- left: 8px;
47
  }
48
 
49
- .w3tc-widget-ps-priority-high .w3tc-widget-ps-icon div {
50
- background-position: 0;
 
51
  }
52
 
53
- .w3tc-widget-ps-priority-medium .w3tc-widget-ps-icon div {
54
- background-position: -14px;
 
55
  }
56
 
57
- .w3tc-widget-ps-priority-low .w3tc-widget-ps-icon div {
58
- background-position: -28px;
 
59
  }
60
 
61
- .w3tc-widget-ps-expand {
62
- float: left;
63
- width: 30px;
64
- height: 20px;
65
- text-align: center;
66
- }
67
-
68
- .w3tc-widget-ps-expand a {
69
- color: #66d;
70
  }
2
  position: absolute;
3
  }
4
 
5
+ .w3tcps_scores {
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: center;
9
  }
10
 
11
+ .w3tcps_scores p {
12
+ padding: 0 10px;
 
13
  }
14
 
15
+ .w3tcps_scores section {
16
+ font-size: 30px;
17
+ font-weight: bold;
18
  }
19
 
20
+ .w3tcps_metric {
21
+ margin-top: 10px;
22
+ margin-bottom: 5px;
23
  }
24
 
25
+ .w3tcps_barline {
26
+ display: flex;
27
+ font-size: 14px;
28
+ margin-bottom: 2px;
 
29
  }
30
 
31
+ .w3tcps_barline div {
32
+ text-align: left;
33
+ padding-left: 10px;
34
+ min-width: 38px;
35
+ position: relative;
36
  }
37
 
38
+ .w3tcps_barfast {
39
+ background-color: #0cc66b;
40
+ color: #fff;
 
 
 
 
 
41
  }
42
 
43
+ .w3tcps_baraverage {
44
+ background-color: #ffa400;
45
+ color: #000;
46
  }
47
 
48
+ .w3tcps_barslow {
49
+ background-color: #ff4e42;
50
+ color: #fff;
51
  }
52
 
53
+ .w3tcps_buttons {
54
+ display: flex;
55
+ justify-content: center;
56
  }
57
 
58
+ .w3tcps_buttons .button {
59
+ margin: 5px;
 
 
 
 
 
 
 
60
  }
PageSpeed_Widget_View.js CHANGED
@@ -1,43 +1,36 @@
1
  jQuery(document).ready(function($) {
2
- function w3tcps_load(nocache) {
3
- $('.w3tcps_loading').removeClass('w3tc_hidden');
4
- $('.w3tcps_content').addClass('w3tc_hidden');
5
- $('.w3tcps_error').addClass('w3tc_none');
6
 
7
- $.getJSON(ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce +
8
- '&w3tc_action=pagespeed_widgetdata' + (nocache ? '&cache=no' : ''),
9
- function(data) {
10
- $('.w3tcps_loading').addClass('w3tc_hidden');
11
 
12
- if (data.error) {
13
- $('.w3tcps_error').removeClass('w3tc_none');
14
- return;
15
- }
16
 
17
- jQuery('.w3tcps_score').html(data.score);
18
- jQuery('.w3tcps_list').html(data.details);
19
-
20
- $('.w3tcps_content').removeClass('w3tc_hidden');
21
- }
22
- ).fail(function() {
23
- $('.w3tcps_error').removeClass('w3tc_none');
24
- $('.w3tcps_content').addClass('w3tc_hidden');
25
- $('.w3tcps_loading').addClass('w3tc_hidden');
26
- });
27
- }
28
 
29
 
30
 
31
- jQuery('.w3tc-widget-ps-view-all').click(function() {
32
- window.open('admin.php?page=w3tc_dashboard&w3tc_test_pagespeed_results&_wpnonce=' + jQuery(this).metadata().nonce, 'pagespeed_results', 'width=800,height=600,status=no,toolbar=no,menubar=no,scrollbars=yes');
33
- return false;
34
- });
35
 
36
- jQuery('.w3tc-widget-ps-refresh').click(function() {
37
- w3tcps_load(true);
38
- });
39
 
40
 
41
-
42
- w3tcps_load();
43
  });
1
  jQuery(document).ready(function($) {
2
+ function w3tcps_load(nocache) {
3
+ $('.w3tcps_loading').removeClass('w3tc_hidden');
4
+ $('.w3tcps_content').addClass('w3tc_hidden');
5
+ $('.w3tcps_error').addClass('w3tc_none');
6
 
7
+ $.getJSON(ajaxurl + '?action=w3tc_ajax&_wpnonce=' + w3tc_nonce +
8
+ '&w3tc_action=pagespeed_widgetdata' + (nocache ? '&cache=no' : ''),
9
+ function(data) {
10
+ $('.w3tcps_loading').addClass('w3tc_hidden');
11
 
12
+ if (data.error) {
13
+ $('.w3tcps_error').removeClass('w3tc_none');
14
+ return;
15
+ }
16
 
17
+ jQuery('.w3tcps_content').html(data['.w3tcps_content']);
18
+ $('.w3tcps_content').removeClass('w3tc_hidden');
19
+ }
20
+ ).fail(function() {
21
+ $('.w3tcps_error').removeClass('w3tc_none');
22
+ $('.w3tcps_content').addClass('w3tc_hidden');
23
+ $('.w3tcps_loading').addClass('w3tc_hidden');
24
+ });
25
+ }
 
 
26
 
27
 
28
 
29
+ jQuery('.w3tcps_content').on('click', '.w3tcps_refresh', function() {
30
+ w3tcps_load(true);
31
+ });
 
32
 
 
 
 
33
 
34
 
35
+ w3tcps_load();
 
36
  });
PageSpeed_Widget_View.php CHANGED
@@ -7,42 +7,52 @@ if ( !defined( 'W3TC' ) )
7
  ?>
8
  <div class="w3tcps_loading w3tc_loading w3tc_hidden">Loading...</div>
9
  <div class="w3tcps_error w3tc_none">
10
- <p>Unable to fetch Page Speed results.</p>
11
- <p>
12
- <input class="button w3tc-widget-ps-refresh" type="button" value="Refresh Analysis" />
13
- </p>
14
  </div>
15
 
16
  <div class="w3tcps_content w3tc_hidden">
17
- <h4>Page Speed Score: <span class="w3tcps_score"></span></h4>
 
 
 
 
18
 
19
- <div class="w3tcps_list">
20
- <ul class="w3tc-widget-ps-rules">
21
- <li>
22
- <div class="w3tc-widget-ps-icon"><div></div></div>
23
- <p>.</p>
24
- </li>
25
- <li>
26
- <div class="w3tc-widget-ps-icon"><div></div></div>
27
- <p>.</p>
28
- </li>
29
- <li>
30
- <div class="w3tc-widget-ps-icon"><div></div></div>
31
- <p>.</p>
32
- </li>
33
- <li>
34
- <div class="w3tc-widget-ps-icon"><div></div></div>
35
- <p>.</p>
36
- </li>
37
- <li>
38
- <div class="w3tc-widget-ps-icon"><div></div></div>
39
- <p>.</p>
40
- </li>
41
- </ul>
42
- </div>
 
 
 
 
 
 
43
 
44
- <p>
45
- <input class="button w3tc-widget-ps-refresh" type="button" value="Refresh analysis" />
46
- <input class="button w3tc-widget-ps-view-all {nonce: '<?php echo wp_create_nonce( 'w3tc' ); ?>'}" type="button" value="View all results" />
47
- </p>
48
  </div>
7
  ?>
8
  <div class="w3tcps_loading w3tc_loading w3tc_hidden">Loading...</div>
9
  <div class="w3tcps_error w3tc_none">
10
+ <p>Unable to fetch Page Speed results.</p>
11
+ <p>
12
+ <input class="button w3tc-widget-ps-refresh" type="button" value="Refresh Analysis" />
13
+ </p>
14
  </div>
15
 
16
  <div class="w3tcps_content w3tc_hidden">
17
+ <div class="w3tcps_scores">
18
+ <section title="Mobile">0</section>
19
+ <p>|</p>
20
+ <section title="Desktop">4</section>
21
+ </div>
22
 
23
+ <div>
24
+ <div class="w3tcps_metric">V</div>
25
+ <div class="w3tcps_barline">
26
+ <div class="w3tcps_barfast">0%</div>
27
+ </div>
28
+ <div class="w3tcps_barline">
29
+ <div class="w3tcps_barfast">0%</div>
30
+ </div>
31
+ <div class="w3tcps_metric">V</div>
32
+ <div class="w3tcps_barline">
33
+ <div class="w3tcps_barfast">0%</div>
34
+ </div>
35
+ <div class="w3tcps_barline">
36
+ <div class="w3tcps_barfast">0%</div>
37
+ </div>
38
+ <div class="w3tcps_metric">V</div>
39
+ <div class="w3tcps_barline">
40
+ <div class="w3tcps_barfast">0%</div>
41
+ </div>
42
+ <div class="w3tcps_barline">
43
+ <div class="w3tcps_barfast">0%</div>
44
+ </div>
45
+ <div class="w3tcps_metric">V</div>
46
+ <div class="w3tcps_barline">
47
+ <div class="w3tcps_barfast">0%</div>
48
+ </div>
49
+ <div class="w3tcps_barline">
50
+ <div class="w3tcps_barfast">0%</div>
51
+ </div>
52
+ </div>
53
 
54
+ <div class="w3tcps_buttons">
55
+ <input class="button w3tcps_refresh" type="button" value="Refresh analysis" />
56
+ <a href="#" class="button">View all results</a>
57
+ </div>
58
  </div>
PageSpeed_Widget_View_FromApi.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace W3TC;
3
+
4
+ if ( !defined( 'W3TC' ) )
5
+ die();
6
+
7
+ $r = $api_response;
8
+ $rm = $api_response['mobile'];
9
+ $rd = $api_response['desktop'];
10
+
11
+
12
+
13
+ function w3tcps_barline($metric) {
14
+ if ( !is_array( $metric['distributions'] ) ||
15
+ count( $metric['distributions'] ) < 3 ) {
16
+ return;
17
+ }
18
+
19
+ $v1 = round((float)$metric['distributions'][0]['proportion'] * 100);
20
+ $v2 = round((float)$metric['distributions'][1]['proportion'] * 100);
21
+ $v3 = round((float)$metric['distributions'][2]['proportion'] * 100);
22
+
23
+ ?>
24
+ <div class="w3tcps_barline">
25
+ <div class="w3tcps_barfast" style="flex-grow: <?php echo esc_html($v1) ?>"><?php echo esc_html($v1) ?>%</div>
26
+ <div class="w3tcps_baraverage" style="flex-grow: <?php echo esc_html($v2) ?>"><?php echo esc_html($v2) ?>%</div>
27
+ <div class="w3tcps_barslow" style="flex-grow: <?php echo esc_html($v3) ?>;"><?php echo esc_html($v3) ?>%</div>
28
+ </div>
29
+ <?php
30
+ }
31
+
32
+
33
+
34
+ function w3tcps_bar($r, $metric, $name) {
35
+ if ( !isset( $r['desktop']['metrics'][$metric] ) ) {
36
+ return;
37
+ }
38
+
39
+ echo '<div class="w3tcps_metric">' . esc_html( $name ) . '</div>';
40
+ w3tcps_barline( $r['mobile']['metrics'][$metric]);
41
+ w3tcps_barline( $r['desktop']['metrics'][$metric]);
42
+ }
43
+
44
+
45
+
46
+ ?>
47
+ <div class="w3tcps_scores">
48
+ <section title="Mobile"><?php echo esc_html( $rm['score'] ) ?></section>
49
+ <p>|</p>
50
+ <section title="Desktop"><?php echo esc_html( $rd['score'] ) ?></section>
51
+ </div>
52
+
53
+ <div>
54
+ <?php w3tcps_bar($r, 'LARGEST_CONTENTFUL_PAINT_MS', 'Largest Contentful Paint') ?>
55
+ <?php w3tcps_bar($r, 'FIRST_CONTENTFUL_PAINT_MS', 'First Contentful Paint') ?>
56
+ <?php w3tcps_bar($r, 'FIRST_INPUT_DELAY_MS', 'First Input Delay') ?>
57
+ <?php w3tcps_bar($r, 'CUMULATIVE_LAYOUT_SHIFT_SCORE', 'Cumulative Layout Shift') ?>
58
+ </div>
59
+ <div class="w3tcps_buttons">
60
+ <input class="button w3tcps_refresh" type="button" value="Refresh analysis" />
61
+ <a href="<?php echo esc_html( $r['test_url'] ) ?>" target="_blank" class="button">View all results</a>
62
+ </div>
PgCache_Page_CookieGroups_View.js CHANGED
@@ -2,7 +2,7 @@ jQuery(function() {
2
 
3
 
4
  function w3tc_cookiegroups_clear() {
5
- if (!jQuery('#cookiegroups li').size()) {
6
  jQuery('#cookiegroups_empty').show();
7
  } else {
8
  jQuery('#cookiegroups_empty').hide();
@@ -36,7 +36,7 @@ jQuery('#w3tc_cookiegroup_add').click(function() {
36
  '<table class="form-table">' +
37
  '<tr>' +
38
  '<th>Group name:</th>' +
39
- '<td><span class="cookiegroup_number">' + (jQuery('#cookiegroups li').size() + 1) + '.</span> ' +
40
  '<span class="cookiegroup_name">' + group + '</span> ' +
41
  '<input type="button" class="button cookiegroup_delete" value="Delete group" /></td>' +
42
  '</tr>' +
2
 
3
 
4
  function w3tc_cookiegroups_clear() {
5
+ if (!jQuery('#cookiegroups li').length) {
6
  jQuery('#cookiegroups_empty').show();
7
  } else {
8
  jQuery('#cookiegroups_empty').hide();
36
  '<table class="form-table">' +
37
  '<tr>' +
38
  '<th>Group name:</th>' +
39
+ '<td><span class="cookiegroup_number">' + (jQuery('#cookiegroups li').length + 1) + '.</span> ' +
40
  '<span class="cookiegroup_name">' + group + '</span> ' +
41
  '<input type="button" class="button cookiegroup_delete" value="Delete group" /></td>' +
42
  '</tr>' +
Root_Loader.php CHANGED
@@ -75,6 +75,10 @@ class Root_Loader {
75
  $plugins[] = new Extensions_Plugin_Admin();
76
  $plugins[] = new Generic_Plugin_AdminNotifications();
77
  $plugins[] = new UsageStatistics_Plugin_Admin();
 
 
 
 
78
  }
79
 
80
  $this->_loaded_plugins = $plugins;
75
  $plugins[] = new Extensions_Plugin_Admin();
76
  $plugins[] = new Generic_Plugin_AdminNotifications();
77
  $plugins[] = new UsageStatistics_Plugin_Admin();
78
+ } else {
79
+ if ( $c->get_boolean( 'jquerymigrate.disabled' ) ) {
80
+ $plugins[] = new UserExperience_Plugin_Jquery();
81
+ }
82
  }
83
 
84
  $this->_loaded_plugins = $plugins;
UsageStatistics_Page_View.js CHANGED
@@ -333,15 +333,15 @@ jQuery(document).ready(function($) {
333
  var phpRequestsDatasets = [];
334
  $('.w3tcus_chart_check').each(function() {
335
  if ($(this).is(':checked')) {
336
- var dataColumn = $(this).attr('data-column');
337
- var backgroundColor = $(this).attr('data-background');
338
  if (!backgroundColor) {
339
  backgroundColor = '#0073aa';
340
  }
341
 
342
  if (startsWith(dataColumn, 'php_php_requests')) {
343
  phpRequestsDatasets.push({
344
- label: $(this).attr('data-name'),
345
  dataColumn: dataColumn.substr(4),
346
  backgroundColor: backgroundColor
347
  });
@@ -731,7 +731,7 @@ jQuery(document).ready(function($) {
731
  // Utils
732
  //
733
  function startsWith(s, prefix) {
734
- return s.substr(0, prefix.length) == prefix;
735
  }
736
 
737
 
333
  var phpRequestsDatasets = [];
334
  $('.w3tcus_chart_check').each(function() {
335
  if ($(this).is(':checked')) {
336
+ var dataColumn = $(this).data('column');
337
+ var backgroundColor = $(this).data('background');
338
  if (!backgroundColor) {
339
  backgroundColor = '#0073aa';
340
  }
341
 
342
  if (startsWith(dataColumn, 'php_php_requests')) {
343
  phpRequestsDatasets.push({
344
+ label: $(this).data('name'),
345
  dataColumn: dataColumn.substr(4),
346
  backgroundColor: backgroundColor
347
  });
731
  // Utils
732
  //
733
  function startsWith(s, prefix) {
734
+ return s && s.substr(0, prefix.length) == prefix;
735
  }
736
 
737
 
UserExperience_GeneralPage_View.php CHANGED
@@ -59,6 +59,15 @@ Util_Ui::config_overloading_button( array(
59
  'description' => __( 'Remove wp-embed.js script from your website. oEmbed functionality still works but you will not be able to embed other WordPress posts on your pages.',
60
  'w3-total-cache' )
61
  ) );
 
 
 
 
 
 
 
 
 
62
  ?>
63
  </table>
64
 
59
  'description' => __( 'Remove wp-embed.js script from your website. oEmbed functionality still works but you will not be able to embed other WordPress posts on your pages.',
60
  'w3-total-cache' )
61
  ) );
62
+
63
+ Util_Ui::config_item(
64
+ array(
65
+ 'key' => 'jquerymigrate.disabled',
66
+ 'control' => 'checkbox',
67
+ 'checkbox_label' => __( 'Disable jquery-migrate on the front-end', 'w3-total-cache' ),
68
+ 'description' => __( 'Remove jquery-migrate support from your website front-end.', 'w3-total-cache' ),
69
+ )
70
+ );
71
  ?>
72
  </table>
73
 
UserExperience_Plugin_Jquery.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: UserExperience_Plugin_Jquery.php
4
+ *
5
+ * @since 0.14.4
6
+ *
7
+ * @package W3TC
8
+ */
9
+
10
+ namespace W3TC;
11
+
12
+ /**
13
+ * Class: UserExperience_Plugin_Jquery
14
+ *
15
+ * @since 0.14.4
16
+ */
17
+ class UserExperience_Plugin_Jquery {
18
+ /**
19
+ * Config class object.
20
+ *
21
+ * @since 0.14.4
22
+ *
23
+ * @var Config
24
+ */
25
+ private $_config = null;
26
+
27
+ /**
28
+ * Constructor.
29
+ *
30
+ * @since 0.14.4
31
+ */
32
+ public function __construct() {
33
+ $this->_config = Dispatcher::config();
34
+ }
35
+
36
+ /**
37
+ * Run.
38
+ *
39
+ * @since 0.14.4
40
+ */
41
+ public function run() {
42
+ // Disable jquery-migrate on the front-end, if configured.
43
+ if ( ! is_admin() && $this->_config->get_boolean( 'jquerymigrate.disabled' ) ) {
44
+ add_action( 'wp_default_scripts', array( $this, 'disable_jquery_migrate' ) );
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Disable jquery-migrate.
50
+ *
51
+ * @since 0.14.4
52
+ *
53
+ * @link https://developer.wordpress.org/reference/hooks/wp_default_scripts/
54
+ * @link https://core.trac.wordpress.org/browser/tags/5.4/src/wp-includes/class.wp-dependencies.php
55
+ *
56
+ * @param WP_Scripts $scripts WP_Scripts instance.
57
+ */
58
+ public function disable_jquery_migrate( $scripts ) {
59
+ if ( isset( $scripts->registered['jquery'] ) ) {
60
+ $script = $scripts->registered['jquery'];
61
+
62
+ if ( $script->deps ) {
63
+ $script->deps = array_diff( $script->deps, array( 'jquery-migrate' ) );
64
+ }
65
+ }
66
+
67
+ unset( $scripts->registered['jquery-migrate'] );
68
+ }
69
+ }
Util_Ui.php CHANGED
@@ -155,6 +155,13 @@ class Util_Ui {
155
  /**
156
  * Returns postbox header
157
  *
 
 
 
 
 
 
 
158
  * @param string $title
159
  * @param string $class
160
  * @param string $id
155
  /**
156
  * Returns postbox header
157
  *
158
+ * WordPress 5.5 introduced .postbox-header, which broke the styles of our postboxes. This was
159
+ * resolved by adding additional css to /pub/css/options.css and pub/css/widget.css tagged with
160
+ * a "WP 5.5" comment.
161
+ *
162
+ * @todo Add .postbox-header to our postboxes and cleanup css.
163
+ * @link https://github.com/W3EDGE/w3-total-cache/issues/237
164
+ *
165
  * @param string $title
166
  * @param string $class
167
  * @param string $id
Util_Widget.php CHANGED
@@ -90,7 +90,7 @@ class Util_Widget {
90
  $header_text = __( 'Configure' );
91
  }
92
 
93
- $widget_name .= ' <div class="w3tc-widget-configure postbox-title-action">' .
94
  '<a href="' . esc_url( $control_callback ) .
95
  '" class="edit-box open-box ' . esc_attr($header_class) . '">' . $header_text .
96
  '</a></span>';
90
  $header_text = __( 'Configure' );
91
  }
92
 
93
+ $widget_name .= ' <span class="w3tc-widget-configure postbox-title-action">' .
94
  '<a href="' . esc_url( $control_callback ) .
95
  '" class="edit-box open-box ' . esc_attr($header_class) . '">' . $header_text .
96
  '</a></span>';
Util_WpFile.php CHANGED
@@ -240,6 +240,9 @@ class Util_WpFile {
240
  $url = $_SERVER['REQUEST_URI'];
241
  $url = preg_replace( "/&w3tc_note=([^&]+)/", '', $url );
242
 
 
 
 
243
 
244
  $success = true;
245
  ob_start();
@@ -281,6 +284,10 @@ class Util_WpFile {
281
  */
282
  static private function get_filesystem_credentials_form( $method = '', $url = '',
283
  $context = false ) {
 
 
 
 
284
  ob_start();
285
  // If first check failed try again and show error message
286
  request_filesystem_credentials( $url, $method, true, false, array() );
240
  $url = $_SERVER['REQUEST_URI'];
241
  $url = preg_replace( "/&w3tc_note=([^&]+)/", '', $url );
242
 
243
+ // Ensure request_filesystem_credentials() is available.
244
+ require_once ABSPATH . 'wp-admin/includes/file.php';
245
+ require_once ABSPATH . 'wp-admin/includes/template.php';
246
 
247
  $success = true;
248
  ob_start();
284
  */
285
  static private function get_filesystem_credentials_form( $method = '', $url = '',
286
  $context = false ) {
287
+ // Ensure request_filesystem_credentials() is available.
288
+ require_once ABSPATH . 'wp-admin/includes/file.php';
289
+ require_once ABSPATH . 'wp-admin/includes/template.php';
290
+
291
  ob_start();
292
  // If first check failed try again and show error message
293
  request_filesystem_credentials( $url, $method, true, false, array() );
pub/css/options.css CHANGED
@@ -285,6 +285,15 @@ input.w3tc-error, textarea.w3tc-error {
285
 
286
  #w3tc .postbox .hndle {
287
  cursor: auto;
 
 
 
 
 
 
 
 
 
288
  }
289
 
290
  #pgcache_reject_roles label, #newrelic_accept_roles label, #cdn_reject_roles label {
@@ -630,7 +639,7 @@ table:not(.w3tc-pro-feature) .w3tc-gopro:after {
630
  padding-top: 1em;
631
  }
632
 
633
- #w3tc_dashboard_banner .hndle {
634
  background: #eee;
635
  border-bottom: 3px solid #65bbbd;
636
  }
285
 
286
  #w3tc .postbox .hndle {
287
  cursor: auto;
288
+ border-bottom: 1px solid #ccd0d4; /* WP 5.5 */
289
+ }
290
+
291
+ #w3tc .postbox-header {
292
+ border-bottom: 0; /* WP 5.5 */
293
+ }
294
+
295
+ #w3tc .postbox .handlediv {
296
+ float: right; /* WP 5.5 */
297
  }
298
 
299
  #pgcache_reject_roles label, #newrelic_accept_roles label, #cdn_reject_roles label {
639
  padding-top: 1em;
640
  }
641
 
642
+ #w3tc_dashboard_banner .postbox .hndle {
643
  background: #eee;
644
  border-bottom: 3px solid #65bbbd;
645
  }
pub/css/widget.css CHANGED
@@ -64,6 +64,14 @@
64
  border-radius: 0;
65
  }
66
 
 
 
 
 
 
 
 
 
67
  #postbox-container-right {
68
  width: 196px;
69
  white-space: nowrap;
64
  border-radius: 0;
65
  }
66
 
67
+ #w3tc-dashboard-widgets .handle-actions {
68
+ display: none; /* WP 5.5 - Dashboard widget reordering not working, so disable. */
69
+ }
70
+
71
+ #w3tc-dashboard-widgets .hndle {
72
+ display: block; /* WP 5.5 */
73
+ }
74
+
75
  #postbox-container-right {
76
  width: 196px;
77
  white-space: nowrap;
pub/js/lightbox.js CHANGED
@@ -311,7 +311,7 @@ function w3tc_lightbox_minify_recommendations(nonce) {
311
  });
312
 
313
  jQuery('#recom_js_check').click(function() {
314
- if (jQuery('#recom_js_files :checkbox:checked').size()) {
315
  jQuery('#recom_js_files :checkbox').removeAttr('checked');
316
  } else {
317
  jQuery('#recom_js_files :checkbox').attr('checked', 'checked');
@@ -321,7 +321,7 @@ function w3tc_lightbox_minify_recommendations(nonce) {
321
  });
322
 
323
  jQuery('#recom_css_check').click(function() {
324
- if (jQuery('#recom_css_files :checkbox:checked').size()) {
325
  jQuery('#recom_css_files :checkbox').removeAttr('checked');
326
  } else {
327
  jQuery('#recom_css_files :checkbox').attr('checked', 'checked');
@@ -346,13 +346,13 @@ function w3tc_lightbox_minify_recommendations(nonce) {
346
  });
347
 
348
  jQuery('#recom_js_files li').each(function() {
349
- if (jQuery(this).find(':checkbox:checked').size()) {
350
  w3tc_minify_js_file_add(theme, jQuery(this).find('[name=recom_js_template]').val(), jQuery(this).find('[name=recom_js_location]').val(), jQuery(this).find('[name=recom_js_file]').val());
351
  }
352
  });
353
 
354
  jQuery('#recom_css_files li').each(function() {
355
- if (jQuery(this).find(':checkbox:checked').size()) {
356
  w3tc_minify_css_file_add(theme, jQuery(this).find('[name=recom_css_template]').val(), jQuery(this).find('[name=recom_css_file]').val());
357
  }
358
  });
@@ -360,8 +360,8 @@ function w3tc_lightbox_minify_recommendations(nonce) {
360
  w3tc_minify_js_theme(theme);
361
  w3tc_minify_css_theme(theme);
362
 
363
- w3tc_input_enable('.js_enabled', jQuery('#minify_js_enable:checked').size());
364
- w3tc_input_enable('.css_enabled', jQuery('#minify_css_enable:checked').size());
365
 
366
  lightbox.close();
367
  });
@@ -503,12 +503,12 @@ jQuery(function() {
503
  });
504
 
505
  jQuery('.button-buy-plugin').click(function() {
506
- var data_src = jQuery(this).attr('data-src');
507
- var nonce = jQuery(this).attr('data-nonce');
508
  if (!nonce) {
509
  nonce = w3tc_nonce;
510
  }
511
- var renew_key = jQuery(this).attr('data-renew-key');
512
 
513
  w3tc_lightbox_upgrade(nonce, data_src, renew_key);
514
  jQuery('#w3tc-license-instruction').show();
311
  });
312
 
313
  jQuery('#recom_js_check').click(function() {
314
+ if (jQuery('#recom_js_files :checkbox:checked').length) {
315
  jQuery('#recom_js_files :checkbox').removeAttr('checked');
316
  } else {
317
  jQuery('#recom_js_files :checkbox').attr('checked', 'checked');
321
  });
322
 
323
  jQuery('#recom_css_check').click(function() {
324
+ if (jQuery('#recom_css_files :checkbox:checked').length) {
325
  jQuery('#recom_css_files :checkbox').removeAttr('checked');
326
  } else {
327
  jQuery('#recom_css_files :checkbox').attr('checked', 'checked');
346
  });
347
 
348
  jQuery('#recom_js_files li').each(function() {
349
+ if (jQuery(this).find(':checkbox:checked').length) {
350
  w3tc_minify_js_file_add(theme, jQuery(this).find('[name=recom_js_template]').val(), jQuery(this).find('[name=recom_js_location]').val(), jQuery(this).find('[name=recom_js_file]').val());
351
  }
352
  });
353
 
354
  jQuery('#recom_css_files li').each(function() {
355
+ if (jQuery(this).find(':checkbox:checked').length) {
356
  w3tc_minify_css_file_add(theme, jQuery(this).find('[name=recom_css_template]').val(), jQuery(this).find('[name=recom_css_file]').val());
357
  }
358
  });
360
  w3tc_minify_js_theme(theme);
361
  w3tc_minify_css_theme(theme);
362
 
363
+ w3tc_input_enable('.js_enabled', jQuery('#minify_js_enable:checked').length);
364
+ w3tc_input_enable('.css_enabled', jQuery('#minify_css_enable:checked').length);
365
 
366
  lightbox.close();
367
  });
503
  });
504
 
505
  jQuery('.button-buy-plugin').click(function() {
506
+ var data_src = jQuery(this).data('src');
507
+ var nonce = jQuery(this).data('nonce');
508
  if (!nonce) {
509
  nonce = w3tc_nonce;
510
  }
511
+ var renew_key = jQuery(this).data('renew-key');
512
 
513
  w3tc_lightbox_upgrade(nonce, data_src, renew_key);
514
  jQuery('#w3tc-license-instruction').show();
pub/js/options.js CHANGED
@@ -33,7 +33,7 @@ function w3tc_input_enable(input, enabled) {
33
  }
34
 
35
  function w3tc_minify_js_file_clear() {
36
- if (!jQuery('#js_files :visible').size()) {
37
  jQuery('#js_files_empty').show();
38
  } else {
39
  jQuery('#js_files_empty').hide();
@@ -41,7 +41,7 @@ function w3tc_minify_js_file_clear() {
41
  }
42
 
43
  function w3tc_minify_css_file_clear() {
44
- if (!jQuery('#css_files :visible').size()) {
45
  jQuery('#css_files_empty').show();
46
  } else {
47
  jQuery('#css_files_empty').hide();
@@ -49,7 +49,7 @@ function w3tc_minify_css_file_clear() {
49
  }
50
 
51
  function w3tc_mobile_groups_clear() {
52
- if (!jQuery('#mobile_groups li').size()) {
53
  jQuery('#mobile_groups_empty').show();
54
  } else {
55
  jQuery('#mobile_groups_empty').hide();
@@ -57,7 +57,7 @@ function w3tc_mobile_groups_clear() {
57
  }
58
 
59
  function w3tc_referrer_groups_clear() {
60
- if (!jQuery('#referrer_groups li').size()) {
61
  jQuery('#referrer_groups_empty').show();
62
  } else {
63
  jQuery('#referrer_groups_empty').hide();
@@ -65,7 +65,7 @@ function w3tc_referrer_groups_clear() {
65
  }
66
 
67
  function w3tc_minify_js_file_add(theme, template, location, file) {
68
- var append = jQuery('<li><table><tr><th>&nbsp;</th><th>File URI:</th><th>Template:</th><th colspan="3">Embed Location:</th></tr><tr><td>' + (jQuery('#js_files li').size() + 1) + '.</td><td><input class="js_enabled" type="text" name="js_files[' + theme + '][' + template + '][' + location + '][]" value="" size="70" \/></td><td><select class="js_file_template js_enabled"></select></td><td><select class="js_file_location js_enabled"><option value="include">Embed in &lt;head&gt;</option><option value="include-body">Embed after &lt;body&gt;</option><option value="include-footer">Embed before &lt;/body&gt;</option></select></td><td><input class="js_file_delete js_enabled button" type="button" value="Delete" /> <input class="js_file_verify js_enabled button" type="button" value="Verify URI" /></td></tr></table><\/li>');
69
  append.find('input:text').val(file);
70
  var select = append.find('.js_file_template');
71
  for (var i in minify_templates[theme]) {
@@ -78,7 +78,7 @@ function w3tc_minify_js_file_add(theme, template, location, file) {
78
  }
79
 
80
  function w3tc_minify_css_file_add(theme, template, file) {
81
- var append = jQuery('<li><table><tr><th>&nbsp;</th><th>File URI:</th><th colspan="2">Template:</th></tr><tr><td>' + (jQuery('#css_files li').size() + 1) + '.</td><td><input class="css_enabled" type="text" name="css_files[' + theme + '][' + template + '][include][]" value="" size="70" \/></td><td><select class="css_file_template css_enabled"></select></td><td><input class="css_file_delete css_enabled button" type="button" value="Delete" /></td><td><input class="css_file_verify css_enabled button" type="button" value="Verify URI" /></td></tr></table><\/li>');
82
  append.find('input:text').val(file);
83
  var select = append.find('.css_file_template');
84
  for (var i in minify_templates[theme]) {
@@ -140,7 +140,7 @@ function w3tc_cdn_get_cnames() {
140
  }
141
 
142
  function w3tc_cdn_cnames_assign() {
143
- var li = jQuery('#cdn_cnames li'), size = li.size();
144
 
145
  if (size > 1) {
146
  li.eq(0).find('.cdn_cname_delete').show();
@@ -374,9 +374,9 @@ jQuery(function() {
374
  });
375
 
376
  // pagecache page
377
- w3tc_input_enable('#pgcache_reject_roles input[type=checkbox]', jQuery('#pgcache__reject__logged_roles:checked').size());
378
  jQuery('#pgcache__reject__logged_roles').on('click', function () {
379
- w3tc_input_enable('#pgcache_reject_roles input[type=checkbox]', jQuery('#pgcache__reject__logged_roles:checked').size());
380
  });
381
 
382
  if(jQuery('#pgcache__cache__nginx_handle_xml').is('*'))
@@ -419,9 +419,9 @@ jQuery(function() {
419
  w3tc_security_headers();
420
 
421
  // minify page
422
- w3tc_input_enable('.html_enabled', jQuery('#minify__html__enable:checked').size());
423
- w3tc_input_enable('.js_enabled', jQuery('#minify__js__enable:checked').size());
424
- w3tc_input_enable('.css_enabled', jQuery('#minify__css__enable:checked').size());
425
 
426
  w3tc_minify_js_theme(jQuery('#js_themes').val());
427
  w3tc_minify_css_theme(jQuery('#css_themes').val());
@@ -562,7 +562,7 @@ jQuery(function() {
562
  }
563
  });
564
 
565
- if (jQuery('#js_enabled:checked').size()) {
566
  if (invalid_js.length && !confirm('The following files have invalid JS file extension:\r\n\r\n' + invalid_js.join('\r\n') + '\r\n\r\nAre you confident these files contain valid JS code?')) {
567
  return false;
568
  }
@@ -573,7 +573,7 @@ jQuery(function() {
573
  }
574
  }
575
 
576
- if (jQuery('#css_enabled:checked').size()) {
577
  if (invalid_css.length && !confirm('The following files have invalid CSS file extension:\r\n\r\n' + invalid_css.join('\r\n') + '\r\n\r\nAre you confident these files contain valid CSS code?')) {
578
  return false;
579
  }
@@ -598,9 +598,9 @@ jQuery(function() {
598
  jQuery(this.rel).show();
599
  });
600
 
601
- w3tc_input_enable('#cdn_reject_roles input[type=checkbox]', jQuery('#cdn__reject__logged_roles:checked').size());
602
  jQuery('#cdn__reject__logged_roles').on('click', function () {
603
- w3tc_input_enable('#cdn_reject_roles input[type=checkbox]', jQuery('#cdn__reject__logged_roles:checked').size());
604
  });
605
 
606
  jQuery('#cdn_export_library').click(function() {
@@ -658,8 +658,8 @@ jQuery(function() {
658
  'config[user]': jQuery('#cdn_ftp_user').val(),
659
  'config[path]': jQuery('#cdn_ftp_path').val(),
660
  'config[pass]': jQuery('#cdn_ftp_pass').val(),
661
- 'config[pasv]': jQuery('#cdn_ftp_pasv:checked').size(),
662
- 'config[default_keys]': jQuery('#cdn__ftp__default_keys:checked').size(),
663
  'config[pubkey]': jQuery('#cdn_ftp_pubkey').val(),
664
  'config[privkey]': jQuery('#cdn_ftp_privkey').val()
665
  });
@@ -947,7 +947,7 @@ jQuery(function() {
947
  status.addClass(data.result ? 'w3tc-success' : 'w3tc-error');
948
  status.html(data.error);
949
 
950
- if (container_id && container_id.size() && data.container_id) {
951
  container_id.val(data.container_id);
952
  }
953
  }, 'json').fail(function() {
@@ -1091,14 +1091,14 @@ jQuery(function() {
1091
  var error = false;
1092
 
1093
  jQuery('#mobile_groups li').each(function() {
1094
- if (jQuery(this).find(':checked').size()) {
1095
  var group = jQuery(this).find('.mobile_group').text();
1096
  var theme = jQuery(this).find(':selected').val();
1097
  var redirect = jQuery(this).find('input[type=text]').val();
1098
  var agents = jQuery.trim(jQuery(this).find('textarea').val()).split("\n");
1099
 
1100
  jQuery('#mobile_groups li').each(function() {
1101
- if (jQuery(this).find(':checked').size()) {
1102
  var compare_group = jQuery(this).find('.mobile_group').text();
1103
  if (compare_group != group) {
1104
  var compare_theme = jQuery(this).find(':selected').val();
@@ -1160,7 +1160,7 @@ jQuery(function() {
1160
  });
1161
 
1162
  if (!exists) {
1163
- var li = jQuery('<li id="mobile_group_' + group + '"><table class="form-table"><tr><th>Group name:</th><td><span class="mobile_group_number">' + (jQuery('#mobile_groups li').size() + 1) + '.</span> <span class="mobile_group">' + group + '</span> <input type="button" class="button mobile_delete" value="Delete group" /></td></tr><tr><th><label for="mobile_groups_' + group + '_enabled">Enabled:</label></th><td><input type="hidden" name="mobile_groups[' + group + '][enabled]" value="0" /><input id="mobile_groups_' + group + '_enabled" type="checkbox" name="mobile_groups[' + group + '][enabled]" value="1" checked="checked" /></td></tr><tr><th><label for="mobile_groups_' + group + '_theme">Theme:</label></th><td><select id="mobile_groups_' + group + '_theme" name="mobile_groups[' + group + '][theme]"><option value="">-- Pass-through --</option></select><p class="description">Assign this group of user agents to a specific them. Leaving this option "Active Theme" allows any plugins you have (e.g. mobile plugins) to properly handle requests for these user agents. If the "redirect users to" field is not empty, this setting is ignored.</p></td></tr><tr><th><label for="mobile_groups_' + group + '_redirect">Redirect users to:</label></th><td><input id="mobile_groups_' + group + '_redirect" type="text" name="mobile_groups[' + group + '][redirect]" value="" size="60" /><p class="description">A 302 redirect is used to send this group of users to another hostname (domain); recommended if a 3rd party service provides a mobile version of your site.</p></td></tr><tr><th><label for="mobile_groups_' + group + '_agents">User agents:</label></th><td><textarea id="mobile_groups_' + group + '_agents" name="mobile_groups[' + group + '][agents]" rows="10" cols="50"></textarea><p class="description">Specify the user agents for this group.</p></td></tr></table></li>');
1164
  var select = li.find('select');
1165
 
1166
  jQuery.each(mobile_themes, function(index, value) {
@@ -1193,14 +1193,14 @@ jQuery(function() {
1193
  var error = false;
1194
 
1195
  jQuery('#referrer_groups li').each(function() {
1196
- if (jQuery(this).find(':checked').size()) {
1197
  var group = jQuery(this).find('.referrer_group').text();
1198
  var theme = jQuery(this).find(':selected').val();
1199
  var redirect = jQuery(this).find('input[type=text]').val();
1200
  var agents = jQuery.trim(jQuery(this).find('textarea').val()).split("\n");
1201
 
1202
  jQuery('#referrer_groups li').each(function() {
1203
- if (jQuery(this).find(':checked').size()) {
1204
  var compare_group = jQuery(this).find('.referrer_group').text();
1205
  if (compare_group != group) {
1206
  var compare_theme = jQuery(this).find(':selected').val();
@@ -1262,7 +1262,7 @@ jQuery(function() {
1262
  });
1263
 
1264
  if (!exists) {
1265
- var li = jQuery('<li id="referrer_group_' + group + '"><table class="form-table"><tr><th>Group name:</th><td><span class="referrer_group_number">' + (jQuery('#referrer_groups li').size() + 1) + '.</span> <span class="referrer_group">' + group + '</span> <input type="button" class="button referrer_delete" value="Delete group" /></td></tr><tr><th><label for="referrer_groups_' + group + '_enabled">Enabled:</label></th><td><input type="hidden" name="referrer_groups[' + group + '][enabled]" value="0" /><input id="referrer_groups_' + group + '_enabled" type="checkbox" name="referrer_groups[' + group + '][enabled]" value="1" checked="checked" /></td></tr><tr><th><label for="referrer_groups_' + group + '_theme">Theme:</label></th><td><select id="referrer_groups_' + group + '_theme" name="referrer_groups[' + group + '][theme]"><option value="">-- Pass-through --</option></select><p class="description">Assign this group of referrers to a specific them. Leaving this option "Active Theme" allows any plugins you have (e.g. referrer plugins) to properly handle requests for these referrers. If the "redirect users to" field is not empty, this setting is ignored.</p></td></tr><tr><th><label for="referrer_groups_' + group + '_redirect">Redirect users to:</label></th><td><input id="referrer_groups_' + group + '_redirect" type="text" name="referrer_groups[' + group + '][redirect]" value="" size="60" /><p class="description">A 302 redirect is used to send this group of users to another hostname (domain); recommended if a 3rd party service provides a referrer version of your site.</p></td></tr><tr><th><label for="referrer_groups_' + group + '_referrers">Referrers:</label></th><td><textarea id="referrer_groups_' + group + '_referrers" name="referrer_groups[' + group + '][referrers]" rows="10" cols="50"></textarea><p class="description">Specify the referrers for this group.</p></td></tr></table></li>');
1266
  var select = li.find('select');
1267
 
1268
  jQuery.each(referrer_themes, function(index, value) {
@@ -1392,7 +1392,7 @@ jQuery(function() {
1392
  // check for unsaved changes
1393
  jQuery('#w3tc input,#w3tc select,#w3tc textarea').on('change', function () {
1394
  var ignore = false;
1395
- jQuery(this).parents().andSelf().each(function() {
1396
  if (jQuery(this).hasClass('w3tc-ignore-change') || jQuery(this).hasClass('lightbox')) {
1397
  ignore = true;
1398
  return false;
@@ -1420,7 +1420,7 @@ jQuery(function() {
1420
 
1421
  var w3tchelp_loaded = {};
1422
  function w3tc_load_faq_section(i) {
1423
- var section = i.attr('data-section');
1424
 
1425
  if (w3tchelp_loaded[section])
1426
  return;
@@ -1456,19 +1456,19 @@ jQuery(function() {
1456
  // gopro block
1457
  jQuery('.w3tc-gopro-more').click(function(e) {
1458
  e.preventDefault();
1459
- if (!jQuery(this).attr('data-expanded')) {
1460
- jQuery(this).attr('data-expanded', '1');
1461
  jQuery(this).html('Show Less <span class="dashicons dashicons-arrow-up-alt2"></span>');
1462
  jQuery(this).parent().find('.w3tc-gopro-description').css('max-height', '300px');
1463
  } else {
1464
- jQuery(this).attr('data-expanded', '');
1465
  jQuery(this).html('Show More <span class="dashicons dashicons-arrow-down-alt2"></span>');
1466
  jQuery(this).parent().find('.w3tc-gopro-description').css('max-height', '');
1467
  }
1468
 
1469
  if (window.w3tc_ga) {
1470
  w3tc_ga('send', 'event', 'anchor', 'click',
1471
- jQuery(this).attr('data-href'));
1472
  }
1473
 
1474
  });
33
  }
34
 
35
  function w3tc_minify_js_file_clear() {
36
+ if (!jQuery('#js_files :visible').length) {
37
  jQuery('#js_files_empty').show();
38
  } else {
39
  jQuery('#js_files_empty').hide();
41
  }
42
 
43
  function w3tc_minify_css_file_clear() {
44
+ if (!jQuery('#css_files :visible').length) {
45
  jQuery('#css_files_empty').show();
46
  } else {
47
  jQuery('#css_files_empty').hide();
49
  }
50
 
51
  function w3tc_mobile_groups_clear() {
52
+ if (!jQuery('#mobile_groups li').length) {
53
  jQuery('#mobile_groups_empty').show();
54
  } else {
55
  jQuery('#mobile_groups_empty').hide();
57
  }
58
 
59
  function w3tc_referrer_groups_clear() {
60
+ if (!jQuery('#referrer_groups li').length) {
61
  jQuery('#referrer_groups_empty').show();
62
  } else {
63
  jQuery('#referrer_groups_empty').hide();
65
  }
66
 
67
  function w3tc_minify_js_file_add(theme, template, location, file) {
68
+ var append = jQuery('<li><table><tr><th>&nbsp;</th><th>File URI:</th><th>Template:</th><th colspan="3">Embed Location:</th></tr><tr><td>' + (jQuery('#js_files li').length + 1) + '.</td><td><input class="js_enabled" type="text" name="js_files[' + theme + '][' + template + '][' + location + '][]" value="" size="70" \/></td><td><select class="js_file_template js_enabled"></select></td><td><select class="js_file_location js_enabled"><option value="include">Embed in &lt;head&gt;</option><option value="include-body">Embed after &lt;body&gt;</option><option value="include-footer">Embed before &lt;/body&gt;</option></select></td><td><input class="js_file_delete js_enabled button" type="button" value="Delete" /> <input class="js_file_verify js_enabled button" type="button" value="Verify URI" /></td></tr></table><\/li>');
69
  append.find('input:text').val(file);
70
  var select = append.find('.js_file_template');
71
  for (var i in minify_templates[theme]) {
78
  }
79
 
80
  function w3tc_minify_css_file_add(theme, template, file) {
81
+ var append = jQuery('<li><table><tr><th>&nbsp;</th><th>File URI:</th><th colspan="2">Template:</th></tr><tr><td>' + (jQuery('#css_files li').length + 1) + '.</td><td><input class="css_enabled" type="text" name="css_files[' + theme + '][' + template + '][include][]" value="" size="70" \/></td><td><select class="css_file_template css_enabled"></select></td><td><input class="css_file_delete css_enabled button" type="button" value="Delete" /></td><td><input class="css_file_verify css_enabled button" type="button" value="Verify URI" /></td></tr></table><\/li>');
82
  append.find('input:text').val(file);
83
  var select = append.find('.css_file_template');
84
  for (var i in minify_templates[theme]) {
140
  }
141
 
142
  function w3tc_cdn_cnames_assign() {
143
+ var li = jQuery('#cdn_cnames li'), size = li.length;
144
 
145
  if (size > 1) {
146
  li.eq(0).find('.cdn_cname_delete').show();
374
  });
375
 
376
  // pagecache page
377
+ w3tc_input_enable('#pgcache_reject_roles input[type=checkbox]', jQuery('#pgcache__reject__logged_roles:checked').length);
378
  jQuery('#pgcache__reject__logged_roles').on('click', function () {
379
+ w3tc_input_enable('#pgcache_reject_roles input[type=checkbox]', jQuery('#pgcache__reject__logged_roles:checked').length);
380
  });
381
 
382
  if(jQuery('#pgcache__cache__nginx_handle_xml').is('*'))
419
  w3tc_security_headers();
420
 
421
  // minify page
422
+ w3tc_input_enable('.html_enabled', jQuery('#minify__html__enable:checked').length);
423
+ w3tc_input_enable('.js_enabled', jQuery('#minify__js__enable:checked').length);
424
+ w3tc_input_enable('.css_enabled', jQuery('#minify__css__enable:checked').length);
425
 
426
  w3tc_minify_js_theme(jQuery('#js_themes').val());
427
  w3tc_minify_css_theme(jQuery('#css_themes').val());
562
  }
563
  });
564
 
565
+ if (jQuery('#js_enabled:checked').length) {
566
  if (invalid_js.length && !confirm('The following files have invalid JS file extension:\r\n\r\n' + invalid_js.join('\r\n') + '\r\n\r\nAre you confident these files contain valid JS code?')) {
567
  return false;
568
  }
573
  }
574
  }
575
 
576
+ if (jQuery('#css_enabled:checked').length) {
577
  if (invalid_css.length && !confirm('The following files have invalid CSS file extension:\r\n\r\n' + invalid_css.join('\r\n') + '\r\n\r\nAre you confident these files contain valid CSS code?')) {
578
  return false;
579
  }
598
  jQuery(this.rel).show();
599
  });
600
 
601
+ w3tc_input_enable('#cdn_reject_roles input[type=checkbox]', jQuery('#cdn__reject__logged_roles:checked').length);
602
  jQuery('#cdn__reject__logged_roles').on('click', function () {
603
+ w3tc_input_enable('#cdn_reject_roles input[type=checkbox]', jQuery('#cdn__reject__logged_roles:checked').length);
604
  });
605
 
606
  jQuery('#cdn_export_library').click(function() {
658
  'config[user]': jQuery('#cdn_ftp_user').val(),
659
  'config[path]': jQuery('#cdn_ftp_path').val(),
660
  'config[pass]': jQuery('#cdn_ftp_pass').val(),
661
+ 'config[pasv]': jQuery('#cdn_ftp_pasv:checked').length,
662
+ 'config[default_keys]': jQuery('#cdn__ftp__default_keys:checked').length,
663
  'config[pubkey]': jQuery('#cdn_ftp_pubkey').val(),
664
  'config[privkey]': jQuery('#cdn_ftp_privkey').val()
665
  });
947
  status.addClass(data.result ? 'w3tc-success' : 'w3tc-error');
948
  status.html(data.error);
949
 
950
+ if (container_id && container_id.length && data.container_id) {
951
  container_id.val(data.container_id);
952
  }
953
  }, 'json').fail(function() {
1091
  var error = false;
1092
 
1093
  jQuery('#mobile_groups li').each(function() {
1094
+ if (jQuery(this).find(':checked').length) {
1095
  var group = jQuery(this).find('.mobile_group').text();
1096
  var theme = jQuery(this).find(':selected').val();
1097
  var redirect = jQuery(this).find('input[type=text]').val();
1098
  var agents = jQuery.trim(jQuery(this).find('textarea').val()).split("\n");
1099
 
1100
  jQuery('#mobile_groups li').each(function() {
1101
+ if (jQuery(this).find(':checked').length) {
1102
  var compare_group = jQuery(this).find('.mobile_group').text();
1103
  if (compare_group != group) {
1104
  var compare_theme = jQuery(this).find(':selected').val();
1160
  });
1161
 
1162
  if (!exists) {
1163
+ var li = jQuery('<li id="mobile_group_' + group + '"><table class="form-table"><tr><th>Group name:</th><td><span class="mobile_group_number">' + (jQuery('#mobile_groups li').length + 1) + '.</span> <span class="mobile_group">' + group + '</span> <input type="button" class="button mobile_delete" value="Delete group" /></td></tr><tr><th><label for="mobile_groups_' + group + '_enabled">Enabled:</label></th><td><input type="hidden" name="mobile_groups[' + group + '][enabled]" value="0" /><input id="mobile_groups_' + group + '_enabled" type="checkbox" name="mobile_groups[' + group + '][enabled]" value="1" checked="checked" /></td></tr><tr><th><label for="mobile_groups_' + group + '_theme">Theme:</label></th><td><select id="mobile_groups_' + group + '_theme" name="mobile_groups[' + group + '][theme]"><option value="">-- Pass-through --</option></select><p class="description">Assign this group of user agents to a specific them. Leaving this option "Active Theme" allows any plugins you have (e.g. mobile plugins) to properly handle requests for these user agents. If the "redirect users to" field is not empty, this setting is ignored.</p></td></tr><tr><th><label for="mobile_groups_' + group + '_redirect">Redirect users to:</label></th><td><input id="mobile_groups_' + group + '_redirect" type="text" name="mobile_groups[' + group + '][redirect]" value="" size="60" /><p class="description">A 302 redirect is used to send this group of users to another hostname (domain); recommended if a 3rd party service provides a mobile version of your site.</p></td></tr><tr><th><label for="mobile_groups_' + group + '_agents">User agents:</label></th><td><textarea id="mobile_groups_' + group + '_agents" name="mobile_groups[' + group + '][agents]" rows="10" cols="50"></textarea><p class="description">Specify the user agents for this group.</p></td></tr></table></li>');
1164
  var select = li.find('select');
1165
 
1166
  jQuery.each(mobile_themes, function(index, value) {
1193
  var error = false;
1194
 
1195
  jQuery('#referrer_groups li').each(function() {
1196
+ if (jQuery(this).find(':checked').length) {
1197
  var group = jQuery(this).find('.referrer_group').text();
1198
  var theme = jQuery(this).find(':selected').val();
1199
  var redirect = jQuery(this).find('input[type=text]').val();
1200
  var agents = jQuery.trim(jQuery(this).find('textarea').val()).split("\n");
1201
 
1202
  jQuery('#referrer_groups li').each(function() {
1203
+ if (jQuery(this).find(':checked').length) {
1204
  var compare_group = jQuery(this).find('.referrer_group').text();
1205
  if (compare_group != group) {
1206
  var compare_theme = jQuery(this).find(':selected').val();
1262
  });
1263
 
1264
  if (!exists) {
1265
+ var li = jQuery('<li id="referrer_group_' + group + '"><table class="form-table"><tr><th>Group name:</th><td><span class="referrer_group_number">' + (jQuery('#referrer_groups li').length + 1) + '.</span> <span class="referrer_group">' + group + '</span> <input type="button" class="button referrer_delete" value="Delete group" /></td></tr><tr><th><label for="referrer_groups_' + group + '_enabled">Enabled:</label></th><td><input type="hidden" name="referrer_groups[' + group + '][enabled]" value="0" /><input id="referrer_groups_' + group + '_enabled" type="checkbox" name="referrer_groups[' + group + '][enabled]" value="1" checked="checked" /></td></tr><tr><th><label for="referrer_groups_' + group + '_theme">Theme:</label></th><td><select id="referrer_groups_' + group + '_theme" name="referrer_groups[' + group + '][theme]"><option value="">-- Pass-through --</option></select><p class="description">Assign this group of referrers to a specific them. Leaving this option "Active Theme" allows any plugins you have (e.g. referrer plugins) to properly handle requests for these referrers. If the "redirect users to" field is not empty, this setting is ignored.</p></td></tr><tr><th><label for="referrer_groups_' + group + '_redirect">Redirect users to:</label></th><td><input id="referrer_groups_' + group + '_redirect" type="text" name="referrer_groups[' + group + '][redirect]" value="" size="60" /><p class="description">A 302 redirect is used to send this group of users to another hostname (domain); recommended if a 3rd party service provides a referrer version of your site.</p></td></tr><tr><th><label for="referrer_groups_' + group + '_referrers">Referrers:</label></th><td><textarea id="referrer_groups_' + group + '_referrers" name="referrer_groups[' + group + '][referrers]" rows="10" cols="50"></textarea><p class="description">Specify the referrers for this group.</p></td></tr></table></li>');
1266
  var select = li.find('select');
1267
 
1268
  jQuery.each(referrer_themes, function(index, value) {
1392
  // check for unsaved changes
1393
  jQuery('#w3tc input,#w3tc select,#w3tc textarea').on('change', function () {
1394
  var ignore = false;
1395
+ jQuery(this).parents().addBack().each(function() {
1396
  if (jQuery(this).hasClass('w3tc-ignore-change') || jQuery(this).hasClass('lightbox')) {
1397
  ignore = true;
1398
  return false;
1420
 
1421
  var w3tchelp_loaded = {};
1422
  function w3tc_load_faq_section(i) {
1423
+ var section = i.data('section');
1424
 
1425
  if (w3tchelp_loaded[section])
1426
  return;
1456
  // gopro block
1457
  jQuery('.w3tc-gopro-more').click(function(e) {
1458
  e.preventDefault();
1459
+ if (!jQuery(this).data('expanded')) {
1460
+ jQuery(this).data('expanded', '1');
1461
  jQuery(this).html('Show Less <span class="dashicons dashicons-arrow-up-alt2"></span>');
1462
  jQuery(this).parent().find('.w3tc-gopro-description').css('max-height', '300px');
1463
  } else {
1464
+ jQuery(this).data('expanded', '');
1465
  jQuery(this).html('Show More <span class="dashicons dashicons-arrow-down-alt2"></span>');
1466
  jQuery(this).parent().find('.w3tc-gopro-description').css('max-height', '');
1467
  }
1468
 
1469
  if (window.w3tc_ga) {
1470
  w3tc_ga('send', 'event', 'anchor', 'click',
1471
+ jQuery(this).data('href'));
1472
  }
1473
 
1474
  });
pub/js/popup.js CHANGED
@@ -391,11 +391,11 @@ var W3tc_Popup_Cdn_Import_Library = {
391
  },
392
 
393
  is_redirect_permanent: function() {
394
- return (jQuery('#cdn_import_library_redirect_permanent:checked').size() > 0);
395
  },
396
 
397
  is_redirect_cdn: function() {
398
- return (jQuery('#cdn_import_library_redirect_cdn:checked').size() > 0);
399
  },
400
 
401
  add_log: function(path, result, error) {
391
  },
392
 
393
  is_redirect_permanent: function() {
394
+ return (jQuery('#cdn_import_library_redirect_permanent:checked').length > 0);
395
  },
396
 
397
  is_redirect_cdn: function() {
398
+ return (jQuery('#cdn_import_library_redirect_cdn:checked').length > 0);
399
  },
400
 
401
  add_log: function(path, result, error) {
pub/js/widget.js CHANGED
@@ -36,9 +36,9 @@ jQuery(function() {
36
  jQuery('.w3tc_generic_widgetservice_radio').click(function () {
37
  var o = jQuery(this);
38
 
39
- jQuery('#w3tc_generic_widgetservices_name').val(o.attr('data-name'));
40
- jQuery('#w3tc_generic_widgetservices_value').val(o.attr('data-value'));
41
- jQuery('#w3tc_generic_widgetservices_form_hash').val(o.attr('data-form_hash'));
42
  });
43
 
44
  jQuery('#buy-w3-service-cancel').on('click', function () {
36
  jQuery('.w3tc_generic_widgetservice_radio').click(function () {
37
  var o = jQuery(this);
38
 
39
+ jQuery('#w3tc_generic_widgetservices_name').val(o.data('name'));
40
+ jQuery('#w3tc_generic_widgetservices_value').val(o.data('value'));
41
+ jQuery('#w3tc_generic_widgetservices_form_hash').val(o.data('form_hash'));
42
  });
43
 
44
  jQuery('#buy-w3-service-cancel').on('click', function () {
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: boldgrid, fredericktownes, maxicusc, gidomanders, bwmarkle, harryjackson1221, joemoto
3
  Tags: seo, cache, optimize, pagespeed, performance, caching, compression, maxcdn, nginx, varnish, redis, new relic, aws, amazon web services, s3, cloudfront, rackspace, cloudflare, azure, apache
4
  Requires at least: 3.2
5
- Tested up to: 5.4
6
- Stable tag: 0.14.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -275,9 +275,18 @@ Please reach out to all of these people and support their projects if you're so
275
 
276
  == Changelog ==
277
 
 
 
 
 
 
 
 
 
 
278
  = 0.14.3 =
279
  * Fix: Take "Accepted Query Strings" into account when "Cache query strings" enabled
280
- * Fix: Fix typo in variable for lazy loading
281
  * Update: Add lazy load Google Maps reference to the general settings page
282
  * Update: Support background-image: together with background: for lazy loading
283
 
2
  Contributors: boldgrid, fredericktownes, maxicusc, gidomanders, bwmarkle, harryjackson1221, joemoto
3
  Tags: seo, cache, optimize, pagespeed, performance, caching, compression, maxcdn, nginx, varnish, redis, new relic, aws, amazon web services, s3, cloudfront, rackspace, cloudflare, azure, apache
4
  Requires at least: 3.2
5
+ Tested up to: 5.5
6
+ Stable tag: 0.14.4
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
275
 
276
  == Changelog ==
277
 
278
+ = 0.14.4 =
279
+ * Fix: Cleanup widget and postbox display for WordPress 5.5
280
+ * Fix: Update to PageSpeed API v5, show webvitals metrics
281
+ * Fix: Console error when adminbar is hidden and PageSpeed module is active
282
+ * Fix: Stats view JS issue
283
+ * Fix: Deprecated jQuery warnings
284
+ * Fix: Require files for request_filesystem_credentials() call
285
+ * Added option to disable jquery-migrate on the front-end. Fixed #172 master (#240)
286
+
287
  = 0.14.3 =
288
  * Fix: Take "Accepted Query Strings" into account when "Cache query strings" enabled
289
+ * Fixed typo in variable for lazy loading
290
  * Update: Add lazy load Google Maps reference to the general settings page
291
  * Update: Support background-image: together with background: for lazy loading
292
 
w3-total-cache-api.php CHANGED
@@ -5,7 +5,7 @@ if ( !defined( 'ABSPATH' ) ) {
5
  }
6
 
7
  define( 'W3TC', true );
8
- define( 'W3TC_VERSION', '0.14.3' );
9
  define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
10
  define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
11
  define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
5
  }
6
 
7
  define( 'W3TC', true );
8
+ define( 'W3TC_VERSION', '0.14.4' );
9
  define( 'W3TC_POWERED_BY', 'W3 Total Cache' );
10
  define( 'W3TC_EMAIL', 'w3tc@w3-edge.com' );
11
  define( 'W3TC_TEXT_DOMAIN', 'w3-total-cache' );
w3-total-cache.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: W3 Total Cache
4
  Description: The highest rated and most complete WordPress performance plugin. Dramatically improve the speed and user experience of your site. Add browser, page, object and database caching as well as minify and content delivery network (CDN) to WordPress.
5
- Version: 0.14.3
6
  Plugin URI: https://www.boldgrid.com/totalcache/
7
  Author: BoldGrid
8
  Author URI: https://www.boldgrid.com/
2
  /*
3
  Plugin Name: W3 Total Cache
4
  Description: The highest rated and most complete WordPress performance plugin. Dramatically improve the speed and user experience of your site. Add browser, page, object and database caching as well as minify and content delivery network (CDN) to WordPress.
5
+ Version: 0.14.4
6
  Plugin URI: https://www.boldgrid.com/totalcache/
7
  Author: BoldGrid
8
  Author URI: https://www.boldgrid.com/