Breeze – WordPress Cache Plugin - Version 1.2.0

Version Description

  • Add: noreferrer noopener attributes tag on external links when process HTML for caching.
    • Add: Preload fonts allow to text remain visible during webfont load.
    • Add: Preload key request of fonts OR CSS file which load fonts from local resource.
    • Add: Preload links allow to enable preload next page of application.
    • Add: lazy load display images on a page only when they are visible to the user.
    • Add: Minimize the impact of third-party code.
Download this release

Release Info

Developer adeelkhan
Plugin Icon 128x128 Breeze – WordPress Cache Plugin
Version 1.2.0
Comparing to
See all releases

Code changes from version 1.1.11 to 1.2.0

Files changed (39) hide show
  1. assets/js/breeze-backend.js +35 -0
  2. assets/js/breeze-configuration.js +4 -1
  3. assets/js/breeze-lazy-load.js +763 -0
  4. assets/js/breeze-lazy-load.min.js +1 -0
  5. assets/js/breeze-prefetch-links.js +81 -0
  6. breeze.php +61 -7
  7. composer.lock +150 -0
  8. inc/breeze-admin.php +157 -12
  9. inc/breeze-configuration.php +24 -1
  10. inc/cache/config-cache.php +4 -0
  11. inc/cache/execute-cache.php +59 -0
  12. inc/class-breeze-lazy-load.php +242 -0
  13. inc/class-breeze-prefetch.php +79 -0
  14. inc/class-breeze-preload-fonts.php +61 -0
  15. inc/compatibility/class-breeze-shortpixel-compatibility.php +50 -0
  16. inc/minification/breeze-js-deferred-loading.php +134 -2
  17. inc/minification/breeze-minification-scripts.php +154 -2
  18. inc/minification/breeze-minification-styles.php +38 -0
  19. inc/minification/breeze-minify-main.php +12 -3
  20. readme.txt +10 -1
  21. vendor/composer/ClassLoader.php +37 -3
  22. vendor/composer/InstalledVersions.php +301 -0
  23. vendor/composer/autoload_classmap.php +1 -0
  24. vendor/composer/autoload_real.php +7 -2
  25. vendor/composer/autoload_static.php +5 -0
  26. vendor/composer/installed.json +138 -114
  27. vendor/composer/installed.php +42 -0
  28. vendor/composer/platform_check.php +26 -0
  29. vendor/matthiasmullie/minify/.github/FUNDING.yml +12 -0
  30. vendor/matthiasmullie/minify/Dockerfile +1 -1
  31. vendor/matthiasmullie/minify/composer.json +2 -2
  32. vendor/matthiasmullie/minify/docker-compose.yml +15 -0
  33. vendor/matthiasmullie/minify/src/CSS.php +47 -13
  34. vendor/matthiasmullie/minify/src/JS.php +1 -1
  35. vendor/matthiasmullie/minify/src/Minify.php +7 -3
  36. views/tabs/advanced.php +170 -1
  37. views/tabs/basic.php +118 -98
  38. views/tabs/cdn.php +47 -35
  39. views/tabs/varnish.php +27 -23
assets/js/breeze-backend.js CHANGED
@@ -138,4 +138,39 @@ jQuery(document).ready(function ($) {
138
 
139
  current_url_clean();
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  });
138
 
139
  current_url_clean();
140
 
141
+
142
+ $( '#advanced-options-tab' ).on( 'change', '#bz-lazy-load', function () {
143
+
144
+ var native_lazy = $( '#native-lazy-option' );
145
+ if ( true === $( this ).is( ':checked' ) ) {
146
+ native_lazy.show();
147
+ }else{
148
+ native_lazy.hide();
149
+ $('#bz-lazy-load-nat').attr('checked', false);
150
+ }
151
+ } );
152
+
153
+ var font_display_swap = $( '#font-display-swap' );
154
+ var font_display = $( '#font-display' );
155
+ var css_minification = $( '#minification-css' );
156
+
157
+ if ( css_minification.is( ':checked' ) ) {
158
+ font_display_swap.show();
159
+ } else {
160
+ font_display_swap.hide();
161
+ font_display.attr( 'checked', false );
162
+ }
163
+ $( '#basic-panel' ).on(
164
+ 'change',
165
+ '#minification-css',
166
+ function () {
167
+ console.log( $( this ).is( ':checked' ) );
168
+ if ( $( this ).is( ':checked' ) ) {
169
+ font_display_swap.show();
170
+ } else {
171
+ font_display_swap.hide();
172
+ font_display.attr( 'checked', false );
173
+ }
174
+ }
175
+ );
176
  });
assets/js/breeze-configuration.js CHANGED
@@ -63,6 +63,7 @@ jQuery(document).ready(function ($) {
63
 
64
  $('button.add-url').unbind('click').click(function () {
65
  var defer = $(this).attr('id').indexOf('defer') > -1;
 
66
  var listURL = $(this).closest('td').find('.breeze-list-url');
67
  var html = '';
68
  var listInput = listURL.find('.breeze-input-group');
@@ -86,7 +87,9 @@ jQuery(document).ready(function ($) {
86
  html += ' </span>';
87
  html += ' <input type="text" size="98"';
88
  html += 'class="breeze-input-url"';
89
- if (!defer) {
 
 
90
  html += 'name="move-to-footer-js[]"';
91
  } else {
92
  html += 'name="defer-js[]"';
63
 
64
  $('button.add-url').unbind('click').click(function () {
65
  var defer = $(this).attr('id').indexOf('defer') > -1;
66
+ var preload = $(this).attr('id').indexOf('preload-fonts') > -1;
67
  var listURL = $(this).closest('td').find('.breeze-list-url');
68
  var html = '';
69
  var listInput = listURL.find('.breeze-input-group');
87
  html += ' </span>';
88
  html += ' <input type="text" size="98"';
89
  html += 'class="breeze-input-url"';
90
+ if(preload){
91
+ html += 'name="breeze-preload-font[]"';
92
+ } else if (!defer) {
93
  html += 'name="move-to-footer-js[]"';
94
  } else {
95
  html += 'name="defer-js[]"';
assets/js/breeze-lazy-load.js ADDED
@@ -0,0 +1,763 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! lazysizes - v5.3.0 */
2
+
3
+ (function(window, factory) {
4
+ var lazySizes = factory(window, window.document, Date);
5
+ if(typeof module == 'object' && module.exports){
6
+ module.exports = lazySizes;
7
+ } else if (typeof define == 'function' && define.amd) {
8
+ define(lazySizes);
9
+ } else {
10
+ window.lazySizes = lazySizes;
11
+ }
12
+ }(window, function l(window, document, Date) { // Pass in the windoe Date function also for SSR because the Date class can be lost
13
+ 'use strict';
14
+ /*jshint eqnull:true */
15
+
16
+ var lazysizes, lazySizesCfg;
17
+
18
+ (function(){
19
+ var prop;
20
+
21
+ var lazySizesDefaults = {
22
+ lazyClass: 'br-lazy',
23
+ loadedClass: 'br-loaded',
24
+ loadingClass: 'br-loading',
25
+ preloadClass: 'br-preload',
26
+ errorClass: 'br-error',
27
+ //strictClass: 'lazystrict',
28
+ autosizesClass: 'br-autosizes',
29
+ fastLoadedClass: 'ls-is-cached',
30
+ iframeLoadMode: 0,
31
+ srcAttr: 'data-breeze',
32
+ srcsetAttr: 'data-brsrcset',
33
+ sizesAttr: 'data-brsizes',
34
+ //preloadAfterLoad: false,
35
+ minSize: 40,
36
+ customMedia: {},
37
+ init: true,
38
+ expFactor: 1.5,
39
+ hFac: 0.8,
40
+ loadMode: 2,
41
+ loadHidden: true,
42
+ ricTimeout: 0,
43
+ throttleDelay: 125,
44
+ };
45
+
46
+ lazySizesCfg = window.lazySizesConfig || window.lazysizesConfig || {};
47
+
48
+ for(prop in lazySizesDefaults){
49
+ if(!(prop in lazySizesCfg)){
50
+ lazySizesCfg[prop] = lazySizesDefaults[prop];
51
+ }
52
+ }
53
+ })();
54
+
55
+ if (!document || !document.getElementsByClassName) {
56
+ return {
57
+ init: function () {},
58
+ cfg: lazySizesCfg,
59
+ noSupport: true,
60
+ };
61
+ }
62
+
63
+ var docElem = document.documentElement;
64
+
65
+ var supportPicture = window.HTMLPictureElement;
66
+
67
+ var _addEventListener = 'addEventListener';
68
+
69
+ var _getAttribute = 'getAttribute';
70
+
71
+ /**
72
+ * Update to bind to window because 'this' becomes null during SSR
73
+ * builds.
74
+ */
75
+ var addEventListener = window[_addEventListener].bind(window);
76
+
77
+ var setTimeout = window.setTimeout;
78
+
79
+ var requestAnimationFrame = window.requestAnimationFrame || setTimeout;
80
+
81
+ var requestIdleCallback = window.requestIdleCallback;
82
+
83
+ var regPicture = /^picture$/i;
84
+
85
+ var loadEvents = ['load', 'error', 'lazyincluded', '_lazyloaded'];
86
+
87
+ var regClassCache = {};
88
+
89
+ var forEach = Array.prototype.forEach;
90
+
91
+ var hasClass = function(ele, cls) {
92
+ if(!regClassCache[cls]){
93
+ regClassCache[cls] = new RegExp('(\\s|^)'+cls+'(\\s|$)');
94
+ }
95
+ return regClassCache[cls].test(ele[_getAttribute]('class') || '') && regClassCache[cls];
96
+ };
97
+
98
+ var addClass = function(ele, cls) {
99
+ if (!hasClass(ele, cls)){
100
+ ele.setAttribute('class', (ele[_getAttribute]('class') || '').trim() + ' ' + cls);
101
+ }
102
+ };
103
+
104
+ var removeClass = function(ele, cls) {
105
+ var reg;
106
+ if ((reg = hasClass(ele,cls))) {
107
+ ele.setAttribute('class', (ele[_getAttribute]('class') || '').replace(reg, ' '));
108
+ }
109
+ };
110
+
111
+ var addRemoveLoadEvents = function(dom, fn, add){
112
+ var action = add ? _addEventListener : 'removeEventListener';
113
+ if(add){
114
+ addRemoveLoadEvents(dom, fn);
115
+ }
116
+ loadEvents.forEach(function(evt){
117
+ dom[action](evt, fn);
118
+ });
119
+ };
120
+
121
+ var triggerEvent = function(elem, name, detail, noBubbles, noCancelable){
122
+ var event = document.createEvent('Event');
123
+
124
+ if(!detail){
125
+ detail = {};
126
+ }
127
+
128
+ detail.instance = lazysizes;
129
+
130
+ event.initEvent(name, !noBubbles, !noCancelable);
131
+
132
+ event.detail = detail;
133
+
134
+ elem.dispatchEvent(event);
135
+ return event;
136
+ };
137
+
138
+ var updatePolyfill = function (el, full){
139
+ var polyfill;
140
+ if( !supportPicture && ( polyfill = (window.picturefill || lazySizesCfg.pf) ) ){
141
+ if(full && full.src && !el[_getAttribute]('srcset')){
142
+ el.setAttribute('srcset', full.src);
143
+ }
144
+ polyfill({reevaluate: true, elements: [el]});
145
+ } else if(full && full.src){
146
+ el.src = full.src;
147
+ }
148
+ };
149
+
150
+ var getCSS = function (elem, style){
151
+ return (getComputedStyle(elem, null) || {})[style];
152
+ };
153
+
154
+ var getWidth = function(elem, parent, width){
155
+ width = width || elem.offsetWidth;
156
+
157
+ while(width < lazySizesCfg.minSize && parent && !elem._lazysizesWidth){
158
+ width = parent.offsetWidth;
159
+ parent = parent.parentNode;
160
+ }
161
+
162
+ return width;
163
+ };
164
+
165
+ var rAF = (function(){
166
+ var running, waiting;
167
+ var firstFns = [];
168
+ var secondFns = [];
169
+ var fns = firstFns;
170
+
171
+ var run = function(){
172
+ var runFns = fns;
173
+
174
+ fns = firstFns.length ? secondFns : firstFns;
175
+
176
+ running = true;
177
+ waiting = false;
178
+
179
+ while(runFns.length){
180
+ runFns.shift()();
181
+ }
182
+
183
+ running = false;
184
+ };
185
+
186
+ var rafBatch = function(fn, queue){
187
+ if(running && !queue){
188
+ fn.apply(this, arguments);
189
+ } else {
190
+ fns.push(fn);
191
+
192
+ if(!waiting){
193
+ waiting = true;
194
+ (document.hidden ? setTimeout : requestAnimationFrame)(run);
195
+ }
196
+ }
197
+ };
198
+
199
+ rafBatch._lsFlush = run;
200
+
201
+ return rafBatch;
202
+ })();
203
+
204
+ var rAFIt = function(fn, simple){
205
+ return simple ?
206
+ function() {
207
+ rAF(fn);
208
+ } :
209
+ function(){
210
+ var that = this;
211
+ var args = arguments;
212
+ rAF(function(){
213
+ fn.apply(that, args);
214
+ });
215
+ }
216
+ ;
217
+ };
218
+
219
+ var throttle = function(fn){
220
+ var running;
221
+ var lastTime = 0;
222
+ var gDelay = lazySizesCfg.throttleDelay;
223
+ var rICTimeout = lazySizesCfg.ricTimeout;
224
+ var run = function(){
225
+ running = false;
226
+ lastTime = Date.now();
227
+ fn();
228
+ };
229
+ var idleCallback = requestIdleCallback && rICTimeout > 49 ?
230
+ function(){
231
+ requestIdleCallback(run, {timeout: rICTimeout});
232
+
233
+ if(rICTimeout !== lazySizesCfg.ricTimeout){
234
+ rICTimeout = lazySizesCfg.ricTimeout;
235
+ }
236
+ } :
237
+ rAFIt(function(){
238
+ setTimeout(run);
239
+ }, true)
240
+ ;
241
+
242
+ return function(isPriority){
243
+ var delay;
244
+
245
+ if((isPriority = isPriority === true)){
246
+ rICTimeout = 33;
247
+ }
248
+
249
+ if(running){
250
+ return;
251
+ }
252
+
253
+ running = true;
254
+
255
+ delay = gDelay - (Date.now() - lastTime);
256
+
257
+ if(delay < 0){
258
+ delay = 0;
259
+ }
260
+
261
+ if(isPriority || delay < 9){
262
+ idleCallback();
263
+ } else {
264
+ setTimeout(idleCallback, delay);
265
+ }
266
+ };
267
+ };
268
+
269
+ //based on http://modernjavascript.blogspot.de/2013/08/building-better-debounce.html
270
+ var debounce = function(func) {
271
+ var timeout, timestamp;
272
+ var wait = 99;
273
+ var run = function(){
274
+ timeout = null;
275
+ func();
276
+ };
277
+ var later = function() {
278
+ var last = Date.now() - timestamp;
279
+
280
+ if (last < wait) {
281
+ setTimeout(later, wait - last);
282
+ } else {
283
+ (requestIdleCallback || run)(run);
284
+ }
285
+ };
286
+
287
+ return function() {
288
+ timestamp = Date.now();
289
+
290
+ if (!timeout) {
291
+ timeout = setTimeout(later, wait);
292
+ }
293
+ };
294
+ };
295
+
296
+ var loader = (function(){
297
+ var preloadElems, isCompleted, resetPreloadingTimer, loadMode, started;
298
+
299
+ var eLvW, elvH, eLtop, eLleft, eLright, eLbottom, isBodyHidden;
300
+
301
+ var regImg = /^img$/i;
302
+ var regIframe = /^iframe$/i;
303
+
304
+ var supportScroll = ('onscroll' in window) && !(/(gle|ing)bot/.test(navigator.userAgent));
305
+
306
+ var shrinkExpand = 0;
307
+ var currentExpand = 0;
308
+
309
+ var isLoading = 0;
310
+ var lowRuns = -1;
311
+
312
+ var resetPreloading = function(e){
313
+ isLoading--;
314
+ if(!e || isLoading < 0 || !e.target){
315
+ isLoading = 0;
316
+ }
317
+ };
318
+
319
+ var isVisible = function (elem) {
320
+ if (isBodyHidden == null) {
321
+ isBodyHidden = getCSS(document.body, 'visibility') == 'hidden';
322
+ }
323
+
324
+ return isBodyHidden || !(getCSS(elem.parentNode, 'visibility') == 'hidden' && getCSS(elem, 'visibility') == 'hidden');
325
+ };
326
+
327
+ var isNestedVisible = function(elem, elemExpand){
328
+ var outerRect;
329
+ var parent = elem;
330
+ var visible = isVisible(elem);
331
+
332
+ eLtop -= elemExpand;
333
+ eLbottom += elemExpand;
334
+ eLleft -= elemExpand;
335
+ eLright += elemExpand;
336
+
337
+ while(visible && (parent = parent.offsetParent) && parent != document.body && parent != docElem){
338
+ visible = ((getCSS(parent, 'opacity') || 1) > 0);
339
+
340
+ if(visible && getCSS(parent, 'overflow') != 'visible'){
341
+ outerRect = parent.getBoundingClientRect();
342
+ visible = eLright > outerRect.left &&
343
+ eLleft < outerRect.right &&
344
+ eLbottom > outerRect.top - 1 &&
345
+ eLtop < outerRect.bottom + 1
346
+ ;
347
+ }
348
+ }
349
+
350
+ return visible;
351
+ };
352
+
353
+ var checkElements = function() {
354
+ var eLlen, i, rect, autoLoadElem, loadedSomething, elemExpand, elemNegativeExpand, elemExpandVal,
355
+ beforeExpandVal, defaultExpand, preloadExpand, hFac;
356
+ var lazyloadElems = lazysizes.elements;
357
+
358
+ if((loadMode = lazySizesCfg.loadMode) && isLoading < 8 && (eLlen = lazyloadElems.length)){
359
+
360
+ i = 0;
361
+
362
+ lowRuns++;
363
+
364
+ for(; i < eLlen; i++){
365
+
366
+ if(!lazyloadElems[i] || lazyloadElems[i]._lazyRace){continue;}
367
+
368
+ if(!supportScroll || (lazysizes.prematureUnveil && lazysizes.prematureUnveil(lazyloadElems[i]))){unveilElement(lazyloadElems[i]);continue;}
369
+
370
+ if(!(elemExpandVal = lazyloadElems[i][_getAttribute]('data-expand')) || !(elemExpand = elemExpandVal * 1)){
371
+ elemExpand = currentExpand;
372
+ }
373
+
374
+ if (!defaultExpand) {
375
+ defaultExpand = (!lazySizesCfg.expand || lazySizesCfg.expand < 1) ?
376
+ docElem.clientHeight > 500 && docElem.clientWidth > 500 ? 500 : 370 :
377
+ lazySizesCfg.expand;
378
+
379
+ lazysizes._defEx = defaultExpand;
380
+
381
+ preloadExpand = defaultExpand * lazySizesCfg.expFactor;
382
+ hFac = lazySizesCfg.hFac;
383
+ isBodyHidden = null;
384
+
385
+ if(currentExpand < preloadExpand && isLoading < 1 && lowRuns > 2 && loadMode > 2 && !document.hidden){
386
+ currentExpand = preloadExpand;
387
+ lowRuns = 0;
388
+ } else if(loadMode > 1 && lowRuns > 1 && isLoading < 6){
389
+ currentExpand = defaultExpand;
390
+ } else {
391
+ currentExpand = shrinkExpand;
392
+ }
393
+ }
394
+
395
+ if(beforeExpandVal !== elemExpand){
396
+ eLvW = innerWidth + (elemExpand * hFac);
397
+ elvH = innerHeight + elemExpand;
398
+ elemNegativeExpand = elemExpand * -1;
399
+ beforeExpandVal = elemExpand;
400
+ }
401
+
402
+ rect = lazyloadElems[i].getBoundingClientRect();
403
+
404
+ if ((eLbottom = rect.bottom) >= elemNegativeExpand &&
405
+ (eLtop = rect.top) <= elvH &&
406
+ (eLright = rect.right) >= elemNegativeExpand * hFac &&
407
+ (eLleft = rect.left) <= eLvW &&
408
+ (eLbottom || eLright || eLleft || eLtop) &&
409
+ (lazySizesCfg.loadHidden || isVisible(lazyloadElems[i])) &&
410
+ ((isCompleted && isLoading < 3 && !elemExpandVal && (loadMode < 3 || lowRuns < 4)) || isNestedVisible(lazyloadElems[i], elemExpand))){
411
+ unveilElement(lazyloadElems[i]);
412
+ loadedSomething = true;
413
+ if(isLoading > 9){break;}
414
+ } else if(!loadedSomething && isCompleted && !autoLoadElem &&
415
+ isLoading < 4 && lowRuns < 4 && loadMode > 2 &&
416
+ (preloadElems[0] || lazySizesCfg.preloadAfterLoad) &&
417
+ (preloadElems[0] || (!elemExpandVal && ((eLbottom || eLright || eLleft || eLtop) || lazyloadElems[i][_getAttribute](lazySizesCfg.sizesAttr) != 'auto')))){
418
+ autoLoadElem = preloadElems[0] || lazyloadElems[i];
419
+ }
420
+ }
421
+
422
+ if(autoLoadElem && !loadedSomething){
423
+ unveilElement(autoLoadElem);
424
+ }
425
+ }
426
+ };
427
+
428
+ var throttledCheckElements = throttle(checkElements);
429
+
430
+ var switchLoadingClass = function(e){
431
+ var elem = e.target;
432
+
433
+ if (elem._lazyCache) {
434
+ delete elem._lazyCache;
435
+ return;
436
+ }
437
+
438
+ resetPreloading(e);
439
+ addClass(elem, lazySizesCfg.loadedClass);
440
+ removeClass(elem, lazySizesCfg.loadingClass);
441
+ addRemoveLoadEvents(elem, rafSwitchLoadingClass);
442
+ triggerEvent(elem, 'lazyloaded');
443
+ };
444
+ var rafedSwitchLoadingClass = rAFIt(switchLoadingClass);
445
+ var rafSwitchLoadingClass = function(e){
446
+ rafedSwitchLoadingClass({target: e.target});
447
+ };
448
+
449
+ var changeIframeSrc = function(elem, src){
450
+ var loadMode = elem.getAttribute('data-load-mode') || lazySizesCfg.iframeLoadMode;
451
+
452
+ // loadMode can be also a string!
453
+ if (loadMode == 0) {
454
+ elem.contentWindow.location.replace(src);
455
+ } else if (loadMode == 1) {
456
+ elem.src = src;
457
+ }
458
+ };
459
+
460
+ var handleSources = function(source){
461
+ var customMedia;
462
+
463
+ var sourceSrcset = source[_getAttribute](lazySizesCfg.srcsetAttr);
464
+
465
+ if( (customMedia = lazySizesCfg.customMedia[source[_getAttribute]('data-media') || source[_getAttribute]('media')]) ){
466
+ source.setAttribute('media', customMedia);
467
+ }
468
+
469
+ if(sourceSrcset){
470
+ source.setAttribute('srcset', sourceSrcset);
471
+ }
472
+ };
473
+
474
+ var lazyUnveil = rAFIt(function (elem, detail, isAuto, sizes, isImg){
475
+ var src, srcset, parent, isPicture, event, firesLoad;
476
+
477
+ if(!(event = triggerEvent(elem, 'lazybeforeunveil', detail)).defaultPrevented){
478
+
479
+ if(sizes){
480
+ if(isAuto){
481
+ addClass(elem, lazySizesCfg.autosizesClass);
482
+ } else {
483
+ elem.setAttribute('sizes', sizes);
484
+ }
485
+ }
486
+
487
+ srcset = elem[_getAttribute](lazySizesCfg.srcsetAttr);
488
+ src = elem[_getAttribute](lazySizesCfg.srcAttr);
489
+
490
+ if(isImg) {
491
+ parent = elem.parentNode;
492
+ isPicture = parent && regPicture.test(parent.nodeName || '');
493
+ }
494
+
495
+ firesLoad = detail.firesLoad || (('src' in elem) && (srcset || src || isPicture));
496
+
497
+ event = {target: elem};
498
+
499
+ addClass(elem, lazySizesCfg.loadingClass);
500
+
501
+ if(firesLoad){
502
+ clearTimeout(resetPreloadingTimer);
503
+ resetPreloadingTimer = setTimeout(resetPreloading, 2500);
504
+ addRemoveLoadEvents(elem, rafSwitchLoadingClass, true);
505
+ }
506
+
507
+ if(isPicture){
508
+ forEach.call(parent.getElementsByTagName('source'), handleSources);
509
+ }
510
+
511
+ if(srcset){
512
+ elem.setAttribute('srcset', srcset);
513
+ } else if(src && !isPicture){
514
+ if(regIframe.test(elem.nodeName)){
515
+ changeIframeSrc(elem, src);
516
+ } else {
517
+ elem.src = src;
518
+ }
519
+ }
520
+
521
+ if(isImg && (srcset || isPicture)){
522
+ updatePolyfill(elem, {src: src});
523
+ }
524
+ }
525
+
526
+ if(elem._lazyRace){
527
+ delete elem._lazyRace;
528
+ }
529
+ removeClass(elem, lazySizesCfg.lazyClass);
530
+
531
+ rAF(function(){
532
+ // Part of this can be removed as soon as this fix is older: https://bugs.chromium.org/p/chromium/issues/detail?id=7731 (2015)
533
+ var isLoaded = elem.complete && elem.naturalWidth > 1;
534
+
535
+ if( !firesLoad || isLoaded){
536
+ if (isLoaded) {
537
+ addClass(elem, lazySizesCfg.fastLoadedClass);
538
+ }
539
+ switchLoadingClass(event);
540
+ elem._lazyCache = true;
541
+ setTimeout(function(){
542
+ if ('_lazyCache' in elem) {
543
+ delete elem._lazyCache;
544
+ }
545
+ }, 9);
546
+ }
547
+ if (elem.loading == 'lazy') {
548
+ isLoading--;
549
+ }
550
+ }, true);
551
+ });
552
+
553
+ var unveilElement = function (elem){
554
+ if (elem._lazyRace) {return;}
555
+ var detail;
556
+
557
+ var isImg = regImg.test(elem.nodeName);
558
+
559
+ //allow using sizes="auto", but don't use. it's invalid. Use data-sizes="auto" or a valid value for sizes instead (i.e.: sizes="80vw")
560
+ var sizes = isImg && (elem[_getAttribute](lazySizesCfg.sizesAttr) || elem[_getAttribute]('sizes'));
561
+ var isAuto = sizes == 'auto';
562
+
563
+ if( (isAuto || !isCompleted) && isImg && (elem[_getAttribute]('src') || elem.srcset) && !elem.complete && !hasClass(elem, lazySizesCfg.errorClass) && hasClass(elem, lazySizesCfg.lazyClass)){return;}
564
+
565
+ detail = triggerEvent(elem, 'lazyunveilread').detail;
566
+
567
+ if(isAuto){
568
+ autoSizer.updateElem(elem, true, elem.offsetWidth);
569
+ }
570
+
571
+ elem._lazyRace = true;
572
+ isLoading++;
573
+
574
+ lazyUnveil(elem, detail, isAuto, sizes, isImg);
575
+ };
576
+
577
+ var afterScroll = debounce(function(){
578
+ lazySizesCfg.loadMode = 3;
579
+ throttledCheckElements();
580
+ });
581
+
582
+ var altLoadmodeScrollListner = function(){
583
+ if(lazySizesCfg.loadMode == 3){
584
+ lazySizesCfg.loadMode = 2;
585
+ }
586
+ afterScroll();
587
+ };
588
+
589
+ var onload = function(){
590
+ if(isCompleted){return;}
591
+ if(Date.now() - started < 999){
592
+ setTimeout(onload, 999);
593
+ return;
594
+ }
595
+
596
+
597
+ isCompleted = true;
598
+
599
+ lazySizesCfg.loadMode = 3;
600
+
601
+ throttledCheckElements();
602
+
603
+ addEventListener('scroll', altLoadmodeScrollListner, true);
604
+ };
605
+
606
+ return {
607
+ _: function(){
608
+ started = Date.now();
609
+
610
+ lazysizes.elements = document.getElementsByClassName(lazySizesCfg.lazyClass);
611
+ preloadElems = document.getElementsByClassName(lazySizesCfg.lazyClass + ' ' + lazySizesCfg.preloadClass);
612
+
613
+ addEventListener('scroll', throttledCheckElements, true);
614
+
615
+ addEventListener('resize', throttledCheckElements, true);
616
+
617
+ addEventListener('pageshow', function (e) {
618
+ if (e.persisted) {
619
+ var loadingElements = document.querySelectorAll('.' + lazySizesCfg.loadingClass);
620
+
621
+ if (loadingElements.length && loadingElements.forEach) {
622
+ requestAnimationFrame(function () {
623
+ loadingElements.forEach( function (img) {
624
+ if (img.complete) {
625
+ unveilElement(img);
626
+ }
627
+ });
628
+ });
629
+ }
630
+ }
631
+ });
632
+
633
+ if(window.MutationObserver){
634
+ new MutationObserver( throttledCheckElements ).observe( docElem, {childList: true, subtree: true, attributes: true} );
635
+ } else {
636
+ docElem[_addEventListener]('DOMNodeInserted', throttledCheckElements, true);
637
+ docElem[_addEventListener]('DOMAttrModified', throttledCheckElements, true);
638
+ setInterval(throttledCheckElements, 999);
639
+ }
640
+
641
+ addEventListener('hashchange', throttledCheckElements, true);
642
+
643
+ //, 'fullscreenchange'
644
+ ['focus', 'mouseover', 'click', 'load', 'transitionend', 'animationend'].forEach(function(name){
645
+ document[_addEventListener](name, throttledCheckElements, true);
646
+ });
647
+
648
+ if((/d$|^c/.test(document.readyState))){
649
+ onload();
650
+ } else {
651
+ addEventListener('load', onload);
652
+ document[_addEventListener]('DOMContentLoaded', throttledCheckElements);
653
+ setTimeout(onload, 20000);
654
+ }
655
+
656
+ if(lazysizes.elements.length){
657
+ checkElements();
658
+ rAF._lsFlush();
659
+ } else {
660
+ throttledCheckElements();
661
+ }
662
+ },
663
+ checkElems: throttledCheckElements,
664
+ unveil: unveilElement,
665
+ _aLSL: altLoadmodeScrollListner,
666
+ };
667
+ })();
668
+
669
+
670
+ var autoSizer = (function(){
671
+ var autosizesElems;
672
+
673
+ var sizeElement = rAFIt(function(elem, parent, event, width){
674
+ var sources, i, len;
675
+ elem._lazysizesWidth = width;
676
+ width += 'px';
677
+
678
+ elem.setAttribute('sizes', width);
679
+
680
+ if(regPicture.test(parent.nodeName || '')){
681
+ sources = parent.getElementsByTagName('source');
682
+ for(i = 0, len = sources.length; i < len; i++){
683
+ sources[i].setAttribute('sizes', width);
684
+ }
685
+ }
686
+
687
+ if(!event.detail.dataAttr){
688
+ updatePolyfill(elem, event.detail);
689
+ }
690
+ });
691
+ var getSizeElement = function (elem, dataAttr, width){
692
+ var event;
693
+ var parent = elem.parentNode;
694
+
695
+ if(parent){
696
+ width = getWidth(elem, parent, width);
697
+ event = triggerEvent(elem, 'lazybeforesizes', {width: width, dataAttr: !!dataAttr});
698
+
699
+ if(!event.defaultPrevented){
700
+ width = event.detail.width;
701
+
702
+ if(width && width !== elem._lazysizesWidth){
703
+ sizeElement(elem, parent, event, width);
704
+ }
705
+ }
706
+ }
707
+ };
708
+
709
+ var updateElementsSizes = function(){
710
+ var i;
711
+ var len = autosizesElems.length;
712
+ if(len){
713
+ i = 0;
714
+
715
+ for(; i < len; i++){
716
+ getSizeElement(autosizesElems[i]);
717
+ }
718
+ }
719
+ };
720
+
721
+ var debouncedUpdateElementsSizes = debounce(updateElementsSizes);
722
+
723
+ return {
724
+ _: function(){
725
+ autosizesElems = document.getElementsByClassName(lazySizesCfg.autosizesClass);
726
+ addEventListener('resize', debouncedUpdateElementsSizes);
727
+ },
728
+ checkElems: debouncedUpdateElementsSizes,
729
+ updateElem: getSizeElement
730
+ };
731
+ })();
732
+
733
+ var init = function(){
734
+ if(!init.i && document.getElementsByClassName){
735
+ init.i = true;
736
+ autoSizer._();
737
+ loader._();
738
+ }
739
+ };
740
+
741
+ setTimeout(function(){
742
+ if(lazySizesCfg.init){
743
+ init();
744
+ }
745
+ });
746
+
747
+ lazysizes = {
748
+ cfg: lazySizesCfg,
749
+ autoSizer: autoSizer,
750
+ loader: loader,
751
+ init: init,
752
+ uP: updatePolyfill,
753
+ aC: addClass,
754
+ rC: removeClass,
755
+ hC: hasClass,
756
+ fire: triggerEvent,
757
+ gW: getWidth,
758
+ rAF: rAF,
759
+ };
760
+
761
+ return lazysizes;
762
+ }
763
+ ));
assets/js/breeze-lazy-load.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e,t){t=t(e,e.document,Date),"object"==typeof module&&module.exports?module.exports=t:"function"==typeof define&&define.amd?define(t):e.lazySizes=t}(window,function(n,f,s){"use strict";var m,h;if(!function(){var e,t={lazyClass:"br-lazy",loadedClass:"br-loaded",loadingClass:"br-loading",preloadClass:"br-preload",errorClass:"br-error",autosizesClass:"br-autosizes",fastLoadedClass:"ls-is-cached",iframeLoadMode:0,srcAttr:"data-breeze",srcsetAttr:"data-brsrcset",sizesAttr:"data-brsizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:!0,ricTimeout:0,throttleDelay:125};for(e in h=n.lazySizesConfig||n.lazysizesConfig||{},t)e in h||(h[e]=t[e])}(),!f||!f.getElementsByClassName)return{init:function(){},cfg:h,noSupport:!0};function r(e,t){return w[t]||(w[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),w[t].test(e[C]("class")||"")&&w[t]}function c(e,t){r(e,t)||e.setAttribute("class",(e[C]("class")||"").trim()+" "+t)}function u(e,t){(t=r(e,t))&&e.setAttribute("class",(e[C]("class")||"").replace(t," "))}function z(e,t,a,n,i){var s=f.createEvent("Event");return(a=a||{}).instance=m,s.initEvent(t,!n,!i),s.detail=a,e.dispatchEvent(s),s}function y(e,t){var a;!p&&(a=n.picturefill||h.pf)?(t&&t.src&&!e[C]("srcset")&&e.setAttribute("srcset",t.src),a({reevaluate:!0,elements:[e]})):t&&t.src&&(e.src=t.src)}function g(e,t){return(getComputedStyle(e,null)||{})[t]}function i(e,t,a){for(a=a||e.offsetWidth;a<h.minSize&&t&&!e._lazysizesWidth;)a=t.offsetWidth,t=t.parentNode;return a}var a,o,t,l,d,v=f.documentElement,p=n.HTMLPictureElement,b="addEventListener",C="getAttribute",e=n[b].bind(n),A=n.setTimeout,E=n.requestAnimationFrame||A,_=n.requestIdleCallback,M=/^picture$/i,N=["load","error","lazyincluded","_lazyloaded"],w={},L=Array.prototype.forEach,x=function(t,a,e){var n=e?b:"removeEventListener";e&&x(t,a),N.forEach(function(e){t[n](e,a)})},W=(l=[],d=t=[],B._lsFlush=S,B);function S(){var e=d;for(d=t.length?l:t,o=!(a=!0);e.length;)e.shift()();a=!1}function B(e,t){a&&!t?e.apply(this,arguments):(d.push(e),o||(o=!0,(f.hidden?A:E)(S)))}function T(a,e){return e?function(){W(a)}:function(){var e=this,t=arguments;W(function(){a.apply(e,t)})}}function F(e){function t(){a=null,e()}var a,n,i=function(){var e=s.now()-n;e<99?A(i,99-e):(_||t)(t)};return function(){n=s.now(),a=a||A(i,99)}}var R,D,k,H,O,P,$,q,I,U,j,G,J,K,Q,V,X,Y,Z,ee,te,ae,ne,ie,se,re,oe,le,de,ce,ue,fe=(Z=/^img$/i,ee=/^iframe$/i,te="onscroll"in n&&!/(gle|ing)bot/.test(navigator.userAgent),ie=-1,J=ze,Q=ne=ae=0,V=h.throttleDelay,X=h.ricTimeout,Y=_&&49<X?function(){_(ye,{timeout:X}),X!==h.ricTimeout&&(X=h.ricTimeout)}:T(function(){A(ye)},!0),re=T(ge),oe=function(e){re({target:e.target})},le=T(function(t,e,a,n,i){var s,r,o,l,d;(o=z(t,"lazybeforeunveil",e)).defaultPrevented||(n&&(a?c(t,h.autosizesClass):t.setAttribute("sizes",n)),s=t[C](h.srcsetAttr),a=t[C](h.srcAttr),i&&(r=(d=t.parentNode)&&M.test(d.nodeName||"")),l=e.firesLoad||"src"in t&&(s||a||r),o={target:t},c(t,h.loadingClass),l&&(clearTimeout(k),k=A(me,2500),x(t,oe,!0)),r&&L.call(d.getElementsByTagName("source"),ve),s?t.setAttribute("srcset",s):a&&!r&&(ee.test(t.nodeName)?(n=a,0==(d=(e=t).getAttribute("data-load-mode")||h.iframeLoadMode)?e.contentWindow.location.replace(n):1==d&&(e.src=n)):t.src=a),i&&(s||r)&&y(t,{src:a})),t._lazyRace&&delete t._lazyRace,u(t,h.lazyClass),W(function(){var e=t.complete&&1<t.naturalWidth;l&&!e||(e&&c(t,h.fastLoadedClass),ge(o),t._lazyCache=!0,A(function(){"_lazyCache"in t&&delete t._lazyCache},9)),"lazy"==t.loading&&ne--},!0)}),ce=F(function(){h.loadMode=3,se()}),ue=function(){D||(s.now()-O<999?A(ue,999):(D=!0,h.loadMode=3,se(),e("scroll",pe,!0)))},{_:function(){O=s.now(),m.elements=f.getElementsByClassName(h.lazyClass),R=f.getElementsByClassName(h.lazyClass+" "+h.preloadClass),e("scroll",se,!0),e("resize",se,!0),e("pageshow",function(e){var t;!e.persisted||(t=f.querySelectorAll("."+h.loadingClass)).length&&t.forEach&&E(function(){t.forEach(function(e){e.complete&&de(e)})})}),n.MutationObserver?new MutationObserver(se).observe(v,{childList:!0,subtree:!0,attributes:!0}):(v[b]("DOMNodeInserted",se,!0),v[b]("DOMAttrModified",se,!0),setInterval(se,999)),e("hashchange",se,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){f[b](e,se,!0)}),/d$|^c/.test(f.readyState)?ue():(e("load",ue),f[b]("DOMContentLoaded",se),A(ue,2e4)),m.elements.length?(ze(),W._lsFlush()):se()},checkElems:se=function(e){var t;(e=!0===e)&&(X=33),K||(K=!0,(t=V-(s.now()-Q))<0&&(t=0),e||t<9?Y():A(Y,t))},unveil:de=function(e){var t,a,n,i;e._lazyRace||(!(i="auto"==(n=(a=Z.test(e.nodeName))&&(e[C](h.sizesAttr)||e[C]("sizes"))))&&D||!a||!e[C]("src")&&!e.srcset||e.complete||r(e,h.errorClass)||!r(e,h.lazyClass))&&(t=z(e,"lazyunveilread").detail,i&&Ee.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,ne++,le(e,t,i,n,a))},_aLSL:pe});function me(e){ne--,e&&!(ne<0)&&e.target||(ne=0)}function he(e){return null==G&&(G="hidden"==g(f.body,"visibility")),G||!("hidden"==g(e.parentNode,"visibility")&&"hidden"==g(e,"visibility"))}function ze(){var e,t,a,n,i,s,r,o,l,d,c,u=m.elements;if((H=h.loadMode)&&ne<8&&(e=u.length)){for(t=0,ie++;t<e;t++)if(u[t]&&!u[t]._lazyRace)if(!te||m.prematureUnveil&&m.prematureUnveil(u[t]))de(u[t]);else if((r=u[t][C]("data-expand"))&&(i=+r)||(i=ae),l||(l=!h.expand||h.expand<1?500<v.clientHeight&&500<v.clientWidth?500:370:h.expand,d=(m._defEx=l)*h.expFactor,c=h.hFac,G=null,ae<d&&ne<1&&2<ie&&2<H&&!f.hidden?(ae=d,ie=0):ae=1<H&&1<ie&&ne<6?l:0),o!==i&&(P=innerWidth+i*c,$=innerHeight+i,s=-1*i,o=i),d=u[t].getBoundingClientRect(),(j=d.bottom)>=s&&(q=d.top)<=$&&(U=d.right)>=s*c&&(I=d.left)<=P&&(j||U||I||q)&&(h.loadHidden||he(u[t]))&&(D&&ne<3&&!r&&(H<3||ie<4)||function(e,t){var a,n=e,i=he(e);for(q-=t,j+=t,I-=t,U+=t;i&&(n=n.offsetParent)&&n!=f.body&&n!=v;)(i=0<(g(n,"opacity")||1))&&"visible"!=g(n,"overflow")&&(a=n.getBoundingClientRect(),i=U>a.left&&I<a.right&&j>a.top-1&&q<a.bottom+1);return i}(u[t],i))){if(de(u[t]),n=!0,9<ne)break}else!n&&D&&!a&&ne<4&&ie<4&&2<H&&(R[0]||h.preloadAfterLoad)&&(R[0]||!r&&(j||U||I||q||"auto"!=u[t][C](h.sizesAttr)))&&(a=R[0]||u[t]);a&&!n&&de(a)}}function ye(){K=!1,Q=s.now(),J()}function ge(e){var t=e.target;t._lazyCache?delete t._lazyCache:(me(e),c(t,h.loadedClass),u(t,h.loadingClass),x(t,oe),z(t,"lazyloaded"))}function ve(e){var t,a=e[C](h.srcsetAttr);(t=h.customMedia[e[C]("data-media")||e[C]("media")])&&e.setAttribute("media",t),a&&e.setAttribute("srcset",a)}function pe(){3==h.loadMode&&(h.loadMode=2),ce()}var be,Ce,Ae,Ee=(Ce=T(function(e,t,a,n){var i,s,r;if(e._lazysizesWidth=n,n+="px",e.setAttribute("sizes",n),M.test(t.nodeName||""))for(s=0,r=(i=t.getElementsByTagName("source")).length;s<r;s++)i[s].setAttribute("sizes",n);a.detail.dataAttr||y(e,a.detail)}),{_:function(){be=f.getElementsByClassName(h.autosizesClass),e("resize",Ae)},checkElems:Ae=F(function(){var e,t=be.length;if(t)for(e=0;e<t;e++)_e(be[e])}),updateElem:_e});function _e(e,t,a){var n=e.parentNode;n&&(a=i(e,n,a),(t=z(e,"lazybeforesizes",{width:a,dataAttr:!!t})).defaultPrevented||(a=t.detail.width)&&a!==e._lazysizesWidth&&Ce(e,n,t,a))}var Me=function(){!Me.i&&f.getElementsByClassName&&(Me.i=!0,Ee._(),fe._())};return A(function(){h.init&&Me()}),m={cfg:h,autoSizer:Ee,loader:fe,init:Me,uP:y,aC:c,rC:u,hC:r,fire:z,gW:i,rAF:W}});
assets/js/breeze-prefetch-links.js ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Document ready
2
+ var ready = ( callback ) => {
3
+ if ( document.readyState != 'loading' ) {
4
+ callback();
5
+ } else {
6
+ document.addEventListener( 'DOMContentLoaded', callback );
7
+ }
8
+ }
9
+
10
+ // Timer used to whether prefetch a link or not.
11
+ var timer;
12
+
13
+ // Document ready callback.
14
+ ready(
15
+ () => {
16
+ // List of URLs to prefetch.
17
+ var prefetched_urls = [];
18
+ addEventListener(
19
+ 'mouseover',
20
+ function ( e ) {
21
+ // Take in consideration only A tags.
22
+ if ( e.target instanceof HTMLAnchorElement ) {
23
+ var the_href = e.target.attributes.href.value;
24
+
25
+ timer = setTimeout(
26
+ function () {
27
+
28
+ var test_link = the_href.replace( breeze_prefetch.local_url, '' );
29
+ // Local host domain.
30
+ var local_host = new URL( breeze_prefetch.local_url ).host;
31
+ // Hovered link host domain.
32
+ var hover_host = new URL( the_href ).host;
33
+
34
+ if (
35
+ '' !== the_href.trim() &&
36
+ false === prefetched_urls.includes( the_href ) &&
37
+ local_host === hover_host &&
38
+ false === search_for_banned_links( breeze_prefetch.ignore_list, test_link )
39
+ ) {
40
+ // Add to the array links that have been prefetched already.
41
+ prefetched_urls.push( the_href.trim() );
42
+ // Activate the prefetch link by adding it to the header.
43
+ var link_tag = document.createElement( 'link' );
44
+ link_tag.href = the_href;
45
+ link_tag.rel = 'prefetch';
46
+ document.head.appendChild( link_tag );
47
+ }
48
+ },
49
+ 150
50
+ );
51
+
52
+ }
53
+ }
54
+ );
55
+ addEventListener(
56
+ 'mouseout',
57
+ function ( e ) {
58
+ clearTimeout( timer );
59
+ }
60
+ );
61
+ } // End ready callback
62
+ );
63
+
64
+ /**
65
+ * Finding if a link is excluded from prefetch.
66
+ *
67
+ * @param ignore_list
68
+ * @param item
69
+ * @returns {boolean}
70
+ */
71
+ function search_for_banned_links( ignore_list, item ) {
72
+ var found = false;
73
+ if ( ignore_list.length ) {
74
+ for ( i = 0; i < ignore_list.length; i++ ) {
75
+ if ( -1 !== item.indexOf( ignore_list[ i ] ) || -1 !== ignore_list[ i ].indexOf( item ) ) {
76
+ found = true;
77
+ }
78
+ }
79
+ }
80
+ return found;
81
+ }
breeze.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Plugin Name: Breeze
4
  * Description: Breeze is a WordPress cache plugin with extensive options to speed up your website. All the options including Varnish Cache are compatible with Cloudways hosting.
5
- * Version: 1.1.11
6
  * Text Domain: breeze
7
  * Domain Path: /languages
8
  * Author: Cloudways
@@ -37,7 +37,7 @@ if ( ! defined( 'BREEZE_PLUGIN_DIR' ) ) {
37
  define( 'BREEZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
38
  }
39
  if ( ! defined( 'BREEZE_VERSION' ) ) {
40
- define( 'BREEZE_VERSION', '1.1.11' );
41
  }
42
  if ( ! defined( 'BREEZE_SITEURL' ) ) {
43
  define( 'BREEZE_SITEURL', get_site_url() );
@@ -58,6 +58,11 @@ if ( ! defined( 'BREEZE_BASENAME' ) ) {
58
  define( 'BREEZE_BASENAME', plugin_basename( __FILE__ ) );
59
  }
60
 
 
 
 
 
 
61
  define( 'BREEZE_CACHE_DELAY', true );
62
  define( 'BREEZE_CACHE_NOGZIP', true );
63
  define( 'BREEZE_ROOT_DIR', str_replace( BREEZE_WP_CONTENT_NAME, '', WP_CONTENT_DIR ) );
@@ -82,6 +87,8 @@ register_activation_hook( __FILE__, array( 'Breeze_Admin', 'plugin_active_hook'
82
  register_deactivation_hook( __FILE__, array( 'Breeze_Admin', 'plugin_deactive_hook' ) );
83
 
84
  require_once( BREEZE_PLUGIN_DIR . 'inc/breeze-admin.php' );
 
 
85
 
86
  if ( is_admin() || 'cli' === php_sapi_name() ) {
87
 
@@ -105,16 +112,20 @@ if ( is_admin() || 'cli' === php_sapi_name() ) {
105
  $config_advanced = breeze_get_option( 'advanced_settings' );
106
 
107
  if ( ! empty( $cdn_conf['cdn-active'] )
108
- || ! empty( $basic_conf['breeze-minify-js'] )
109
- || ! empty( $basic_conf['breeze-minify-css'] )
110
- || ! empty( $basic_conf['breeze-minify-html'] )
111
- || ! empty( $config_advanced['breeze-defer-js'] )
112
- || ! empty( $config_advanced['breeze-move-to-footer-js'] )
 
113
  ) {
114
  // Call back ob start
115
  ob_start( 'breeze_ob_start_callback' );
116
  }
117
  }
 
 
 
118
 
119
  // Call back ob start - stack
120
  function breeze_ob_start_callback( $buffer ) {
@@ -285,6 +296,49 @@ function breeze_check_for_new_version() {
285
  require_once( BREEZE_PLUGIN_DIR . 'inc/cache/config-cache.php' );
286
  }
287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  // If the WP install is multi-site
289
  if ( is_multisite() ) {
290
  // For multi-site we need to also reset the root config-file.
2
  /**
3
  * Plugin Name: Breeze
4
  * Description: Breeze is a WordPress cache plugin with extensive options to speed up your website. All the options including Varnish Cache are compatible with Cloudways hosting.
5
+ * Version: 1.2.0
6
  * Text Domain: breeze
7
  * Domain Path: /languages
8
  * Author: Cloudways
37
  define( 'BREEZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
38
  }
39
  if ( ! defined( 'BREEZE_VERSION' ) ) {
40
+ define( 'BREEZE_VERSION', '1.2.0' );
41
  }
42
  if ( ! defined( 'BREEZE_SITEURL' ) ) {
43
  define( 'BREEZE_SITEURL', get_site_url() );
58
  define( 'BREEZE_BASENAME', plugin_basename( __FILE__ ) );
59
  }
60
 
61
+ if ( ! defined( 'BREEZE_PLUGIN_URL' ) ) {
62
+ // Usage BREEZE_PLUGIN_URL . "some_image.png" from plugin folder
63
+ define( 'BREEZE_PLUGIN_URL', plugins_url() . '/' . dirname( plugin_basename( __FILE__ ) ) . '/' );
64
+ }
65
+
66
  define( 'BREEZE_CACHE_DELAY', true );
67
  define( 'BREEZE_CACHE_NOGZIP', true );
68
  define( 'BREEZE_ROOT_DIR', str_replace( BREEZE_WP_CONTENT_NAME, '', WP_CONTENT_DIR ) );
87
  register_deactivation_hook( __FILE__, array( 'Breeze_Admin', 'plugin_deactive_hook' ) );
88
 
89
  require_once( BREEZE_PLUGIN_DIR . 'inc/breeze-admin.php' );
90
+ require_once( BREEZE_PLUGIN_DIR . 'inc/class-breeze-prefetch.php' );
91
+ require_once( BREEZE_PLUGIN_DIR . 'inc/class-breeze-preload-fonts.php' );
92
 
93
  if ( is_admin() || 'cli' === php_sapi_name() ) {
94
 
112
  $config_advanced = breeze_get_option( 'advanced_settings' );
113
 
114
  if ( ! empty( $cdn_conf['cdn-active'] )
115
+ || ! empty( $basic_conf['breeze-minify-js'] )
116
+ || ! empty( $basic_conf['breeze-minify-css'] )
117
+ || ! empty( $basic_conf['breeze-minify-html'] )
118
+ || ! empty( $config_advanced['breeze-defer-js'] )
119
+ || ! empty( $config_advanced['breeze-move-to-footer-js'] )
120
+ || ! empty( $config_advanced['breeze-delay-js-scripts'] )
121
  ) {
122
  // Call back ob start
123
  ob_start( 'breeze_ob_start_callback' );
124
  }
125
  }
126
+ // Compatibility with ShortPixel.
127
+ require_once( BREEZE_PLUGIN_DIR . 'inc/compatibility/class-breeze-shortpixel-compatibility.php' );
128
+
129
 
130
  // Call back ob start - stack
131
  function breeze_ob_start_callback( $buffer ) {
296
  require_once( BREEZE_PLUGIN_DIR . 'inc/cache/config-cache.php' );
297
  }
298
 
299
+ $advanced = breeze_get_option( 'advanced_settings' );
300
+ $is_advanced = get_option( 'breeze_advanced_settings_120' );
301
+ if ( empty( $is_advanced ) ) {
302
+ $advanced['breeze-delay-js-scripts'] = array(
303
+ 'gtag',
304
+ 'document.write',
305
+ 'html5.js',
306
+ 'show_ads.js',
307
+ 'google_ad',
308
+ 'blogcatalog.com/w',
309
+ 'tweetmeme.com/i',
310
+ 'mybloglog.com/',
311
+ 'histats.com/js',
312
+ 'ads.smowtion.com/ad.js',
313
+ 'statcounter.com/counter/counter.js',
314
+ 'widgets.amung.us',
315
+ 'ws.amazon.com/widgets',
316
+ 'media.fastclick.net',
317
+ '/ads/',
318
+ 'comment-form-quicktags/quicktags.php',
319
+ 'edToolbar',
320
+ 'intensedebate.com',
321
+ 'scripts.chitika.net/',
322
+ '_gaq.push',
323
+ 'jotform.com/',
324
+ 'admin-bar.min.js',
325
+ 'GoogleAnalyticsObject',
326
+ 'plupload.full.min.js',
327
+ 'syntaxhighlighter',
328
+ 'adsbygoogle',
329
+ 'gist.github.com',
330
+ '_stq',
331
+ 'nonce',
332
+ 'post_id',
333
+ 'data-noptimize',
334
+ 'googletagmanager',
335
+ );
336
+
337
+ breeze_update_option( 'advanced_settings', $advanced, true );
338
+ breeze_update_option( 'advanced_settings_120', 'yes', true );
339
+ }
340
+
341
+
342
  // If the WP install is multi-site
343
  if ( is_multisite() ) {
344
  // For multi-site we need to also reset the root config-file.
composer.lock ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "content-hash": "e7806260d775937d439159cde5165225",
8
+ "packages": [
9
+ {
10
+ "name": "matthiasmullie/minify",
11
+ "version": "1.3.66",
12
+ "source": {
13
+ "type": "git",
14
+ "url": "https://github.com/matthiasmullie/minify.git",
15
+ "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6"
16
+ },
17
+ "dist": {
18
+ "type": "zip",
19
+ "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/45fd3b0f1dfa2c965857c6d4a470bea52adc31a6",
20
+ "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6",
21
+ "shasum": ""
22
+ },
23
+ "require": {
24
+ "ext-pcre": "*",
25
+ "matthiasmullie/path-converter": "~1.1",
26
+ "php": ">=5.3.0"
27
+ },
28
+ "require-dev": {
29
+ "friendsofphp/php-cs-fixer": "~2.0",
30
+ "matthiasmullie/scrapbook": "dev-master",
31
+ "phpunit/phpunit": ">=4.8"
32
+ },
33
+ "suggest": {
34
+ "psr/cache-implementation": "Cache implementation to use with Minify::cache"
35
+ },
36
+ "bin": [
37
+ "bin/minifycss",
38
+ "bin/minifyjs"
39
+ ],
40
+ "type": "library",
41
+ "autoload": {
42
+ "psr-4": {
43
+ "MatthiasMullie\\Minify\\": "src/"
44
+ }
45
+ },
46
+ "notification-url": "https://packagist.org/downloads/",
47
+ "license": [
48
+ "MIT"
49
+ ],
50
+ "authors": [
51
+ {
52
+ "name": "Matthias Mullie",
53
+ "email": "minify@mullie.eu",
54
+ "homepage": "http://www.mullie.eu",
55
+ "role": "Developer"
56
+ }
57
+ ],
58
+ "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.",
59
+ "homepage": "http://www.minifier.org",
60
+ "keywords": [
61
+ "JS",
62
+ "css",
63
+ "javascript",
64
+ "minifier",
65
+ "minify"
66
+ ],
67
+ "support": {
68
+ "issues": "https://github.com/matthiasmullie/minify/issues",
69
+ "source": "https://github.com/matthiasmullie/minify/tree/1.3.66"
70
+ },
71
+ "funding": [
72
+ {
73
+ "url": "https://github.com/[user1",
74
+ "type": "github"
75
+ },
76
+ {
77
+ "url": "https://github.com/matthiasmullie] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g.",
78
+ "type": "github"
79
+ },
80
+ {
81
+ "url": "https://github.com/user2",
82
+ "type": "github"
83
+ }
84
+ ],
85
+ "time": "2021-01-06T15:18:10+00:00"
86
+ },
87
+ {
88
+ "name": "matthiasmullie/path-converter",
89
+ "version": "1.1.3",
90
+ "source": {
91
+ "type": "git",
92
+ "url": "https://github.com/matthiasmullie/path-converter.git",
93
+ "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9"
94
+ },
95
+ "dist": {
96
+ "type": "zip",
97
+ "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9",
98
+ "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9",
99
+ "shasum": ""
100
+ },
101
+ "require": {
102
+ "ext-pcre": "*",
103
+ "php": ">=5.3.0"
104
+ },
105
+ "require-dev": {
106
+ "phpunit/phpunit": "~4.8"
107
+ },
108
+ "type": "library",
109
+ "autoload": {
110
+ "psr-4": {
111
+ "MatthiasMullie\\PathConverter\\": "src/"
112
+ }
113
+ },
114
+ "notification-url": "https://packagist.org/downloads/",
115
+ "license": [
116
+ "MIT"
117
+ ],
118
+ "authors": [
119
+ {
120
+ "name": "Matthias Mullie",
121
+ "email": "pathconverter@mullie.eu",
122
+ "homepage": "http://www.mullie.eu",
123
+ "role": "Developer"
124
+ }
125
+ ],
126
+ "description": "Relative path converter",
127
+ "homepage": "http://github.com/matthiasmullie/path-converter",
128
+ "keywords": [
129
+ "converter",
130
+ "path",
131
+ "paths",
132
+ "relative"
133
+ ],
134
+ "support": {
135
+ "issues": "https://github.com/matthiasmullie/path-converter/issues",
136
+ "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3"
137
+ },
138
+ "time": "2019-02-05T23:41:09+00:00"
139
+ }
140
+ ],
141
+ "packages-dev": [],
142
+ "aliases": [],
143
+ "minimum-stability": "stable",
144
+ "stability-flags": [],
145
+ "prefer-stable": false,
146
+ "prefer-lowest": false,
147
+ "platform": [],
148
+ "platform-dev": [],
149
+ "plugin-api-version": "2.0.0"
150
+ }
inc/breeze-admin.php CHANGED
@@ -34,6 +34,9 @@ class Breeze_Admin {
34
  }
35
  );
36
 
 
 
 
37
  // Add our custom action to clear cache
38
  add_action( 'breeze_clear_all_cache', array( $this, 'breeze_clear_all_cache' ) );
39
  add_action( 'breeze_clear_varnish', array( $this, 'breeze_clear_varnish' ) );
@@ -73,6 +76,28 @@ class Breeze_Admin {
73
 
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  /**
77
  * Admin Init.
78
  *
@@ -121,12 +146,12 @@ class Breeze_Admin {
121
  wp_enqueue_script( 'jquery' );
122
  }
123
  wp_enqueue_script( 'breeze-backend', plugins_url( 'assets/js/breeze-backend.js', dirname( __FILE__ ) ), array( 'jquery' ), BREEZE_VERSION, true );
124
- wp_enqueue_style( 'breeze-topbar', plugins_url( 'assets/css/topbar.css', dirname( __FILE__ ) ) );
125
- wp_enqueue_style( 'breeze-notice', plugins_url( 'assets/css/notice.css', dirname( __FILE__ ) ) );
126
  $current_screen = get_current_screen();
127
  if ( $current_screen->base == 'settings_page_breeze' || $current_screen->base == 'settings_page_breeze-network' ) {
128
  //add css
129
- wp_enqueue_style( 'breeze-style', plugins_url( 'assets/css/style.css', dirname( __FILE__ ) ) );
130
  //js
131
  wp_enqueue_script( 'breeze-configuration', plugins_url( 'assets/js/breeze-configuration.js', dirname( __FILE__ ) ), array( 'jquery' ), BREEZE_VERSION, true );
132
 
@@ -194,7 +219,7 @@ class Breeze_Admin {
194
  $current_params = $_SERVER['QUERY_STRING'];
195
 
196
  if ( is_multisite() && ! is_subdomain_install() ) {
197
- $blog_details = get_blog_details();
198
  $current_host .= rtrim( $blog_details->path, '/' );
199
  }
200
 
@@ -293,7 +318,7 @@ class Breeze_Admin {
293
  /*
294
  * Register active plugin hook.
295
  */
296
- public static function plugin_active_hook() {
297
  WP_Filesystem();
298
  // Default basic
299
  $basic = breeze_get_option( 'basic_settings' );
@@ -305,6 +330,7 @@ class Breeze_Admin {
305
  'breeze-ttl' => '',
306
  'breeze-minify-html' => '0',
307
  'breeze-minify-css' => '0',
 
308
  'breeze-minify-js' => '0',
309
  'breeze-gzip-compression' => '1',
310
  'breeze-desktop-cache' => '1',
@@ -326,12 +352,56 @@ class Breeze_Admin {
326
  'breeze-exclude-urls' => array(),
327
  'breeze-group-css' => '0',
328
  'breeze-group-js' => '0',
 
 
 
329
  'breeze-exclude-css' => array(),
330
  'breeze-exclude-js' => array(),
331
  'breeze-move-to-footer-js' => array(),
332
  'breeze-defer-js' => array(),
333
  );
334
- $advanced = array_merge( $default_advanced, $advanced );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
 
336
  //CDN default
337
  $cdn = breeze_get_option( 'cdn_integration' );
@@ -359,6 +429,10 @@ class Breeze_Admin {
359
  $varnish = array_merge( $default_varnish, $varnish );
360
 
361
  if ( is_multisite() ) {
 
 
 
 
362
  $blogs = get_sites();
363
  foreach ( $blogs as $blog ) {
364
  $blog_basic = get_blog_option( (int) $blog->blog_id, 'breeze_basic_settings', '' );
@@ -367,8 +441,19 @@ class Breeze_Admin {
367
  }
368
 
369
  $blog_advanced = get_blog_option( (int) $blog->blog_id, 'breeze_advanced_settings', '' );
370
- if ( empty( $blog_advanced ) ) {
371
- update_blog_option( (int) $blog->blog_id, 'breeze_advanced_settings', $advanced );
 
 
 
 
 
 
 
 
 
 
 
372
  }
373
 
374
  $blog_cdn = get_blog_option( (int) $blog->blog_id, 'breeze_cdn_integration', '' );
@@ -381,11 +466,71 @@ class Breeze_Admin {
381
  update_blog_option( (int) $blog->blog_id, 'breeze_varnish_cache', $varnish );
382
  }
383
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  } else {
385
- update_option( 'breeze_basic_settings', $basic );
386
- update_option( 'breeze_advanced_settings', $advanced );
387
- update_option( 'breeze_cdn_integration', $cdn );
388
- update_option( 'breeze_varnish_cache', $varnish );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  }
390
 
391
  //add header to htaccess if setting is enabled or by default if first installed
34
  }
35
  );
36
 
37
+ // Load the Javascript for Lazy load.
38
+ add_action( 'wp_enqueue_scripts', array( $this, 'breeze_lazy_load' ) );
39
+
40
  // Add our custom action to clear cache
41
  add_action( 'breeze_clear_all_cache', array( $this, 'breeze_clear_all_cache' ) );
42
  add_action( 'breeze_clear_varnish', array( $this, 'breeze_clear_varnish' ) );
76
 
77
  }
78
 
79
+ /**
80
+ * Load Lazy Load library
81
+ * @since 1.2.0
82
+ * @access public
83
+ */
84
+ public function breeze_lazy_load() {
85
+ $advanced = breeze_get_option( 'advanced_settings' );
86
+ $is_lazy_load_enabled = filter_var( $advanced['breeze-lazy-load'], FILTER_VALIDATE_BOOLEAN );
87
+ $is_lazy_load_native = filter_var( $advanced['breeze-lazy-load-native'], FILTER_VALIDATE_BOOLEAN );
88
+ if ( true === $is_lazy_load_enabled && false === $is_lazy_load_native ) {
89
+ if ( ! wp_script_is( 'jquery', 'enqueued' ) ) {
90
+ wp_enqueue_script( 'jquery' );
91
+ }
92
+
93
+ $script_load = '.min';
94
+ if ( defined( 'SCRIPT_DEBUG' ) && true === SCRIPT_DEBUG ) {
95
+ $script_load = '';
96
+ }
97
+ wp_enqueue_script( 'breeze-lazy', plugins_url( 'assets/js/breeze-lazy-load' . $script_load . '.js', dirname( __FILE__ ) ), array(), BREEZE_VERSION, true );
98
+ }
99
+ }
100
+
101
  /**
102
  * Admin Init.
103
  *
146
  wp_enqueue_script( 'jquery' );
147
  }
148
  wp_enqueue_script( 'breeze-backend', plugins_url( 'assets/js/breeze-backend.js', dirname( __FILE__ ) ), array( 'jquery' ), BREEZE_VERSION, true );
149
+ wp_enqueue_style( 'breeze-topbar', plugins_url( 'assets/css/topbar.css', dirname( __FILE__ ) ), array(), BREEZE_VERSION );
150
+ wp_enqueue_style( 'breeze-notice', plugins_url( 'assets/css/notice.css', dirname( __FILE__ ) ), array(), BREEZE_VERSION );
151
  $current_screen = get_current_screen();
152
  if ( $current_screen->base == 'settings_page_breeze' || $current_screen->base == 'settings_page_breeze-network' ) {
153
  //add css
154
+ wp_enqueue_style( 'breeze-style', plugins_url( 'assets/css/style.css', dirname( __FILE__ ) ), array(), BREEZE_VERSION );
155
  //js
156
  wp_enqueue_script( 'breeze-configuration', plugins_url( 'assets/js/breeze-configuration.js', dirname( __FILE__ ) ), array( 'jquery' ), BREEZE_VERSION, true );
157
 
219
  $current_params = $_SERVER['QUERY_STRING'];
220
 
221
  if ( is_multisite() && ! is_subdomain_install() ) {
222
+ $blog_details = get_blog_details();
223
  $current_host .= rtrim( $blog_details->path, '/' );
224
  }
225
 
318
  /*
319
  * Register active plugin hook.
320
  */
321
+ public static function plugin_active_hook( $network_wide ) {
322
  WP_Filesystem();
323
  // Default basic
324
  $basic = breeze_get_option( 'basic_settings' );
330
  'breeze-ttl' => '',
331
  'breeze-minify-html' => '0',
332
  'breeze-minify-css' => '0',
333
+ 'breeze-font-display-swap' => '0',
334
  'breeze-minify-js' => '0',
335
  'breeze-gzip-compression' => '1',
336
  'breeze-desktop-cache' => '1',
352
  'breeze-exclude-urls' => array(),
353
  'breeze-group-css' => '0',
354
  'breeze-group-js' => '0',
355
+ 'breeze-lazy-load' => '0',
356
+ 'breeze-lazy-load-native' => '0',
357
+ 'breeze-preload-links' => '0',
358
  'breeze-exclude-css' => array(),
359
  'breeze-exclude-js' => array(),
360
  'breeze-move-to-footer-js' => array(),
361
  'breeze-defer-js' => array(),
362
  );
363
+
364
+ $is_advanced = get_option( 'breeze_advanced_settings_120' );
365
+
366
+ if ( empty( $is_advanced ) ) {
367
+ $breeze_delay_js_scripts = array(
368
+ 'gtag',
369
+ 'document.write',
370
+ 'html5.js',
371
+ 'show_ads.js',
372
+ 'google_ad',
373
+ 'blogcatalog.com/w',
374
+ 'tweetmeme.com/i',
375
+ 'mybloglog.com/',
376
+ 'histats.com/js',
377
+ 'ads.smowtion.com/ad.js',
378
+ 'statcounter.com/counter/counter.js',
379
+ 'widgets.amung.us',
380
+ 'ws.amazon.com/widgets',
381
+ 'media.fastclick.net',
382
+ '/ads/',
383
+ 'comment-form-quicktags/quicktags.php',
384
+ 'edToolbar',
385
+ 'intensedebate.com',
386
+ 'scripts.chitika.net/',
387
+ '_gaq.push',
388
+ 'jotform.com/',
389
+ 'admin-bar.min.js',
390
+ 'GoogleAnalyticsObject',
391
+ 'plupload.full.min.js',
392
+ 'syntaxhighlighter',
393
+ 'adsbygoogle',
394
+ 'gist.github.com',
395
+ '_stq',
396
+ 'nonce',
397
+ 'post_id',
398
+ 'data-noptimize',
399
+ 'googletagmanager',
400
+ );
401
+ breeze_update_option( 'advanced_settings_120', 'yes', true );
402
+ }
403
+
404
+ $advanced = array_merge( $default_advanced, $advanced );
405
 
406
  //CDN default
407
  $cdn = breeze_get_option( 'cdn_integration' );
429
  $varnish = array_merge( $default_varnish, $varnish );
430
 
431
  if ( is_multisite() ) {
432
+ if ( ! isset( $network_wide ) ) {
433
+ $network_wide = is_network_admin();
434
+ }
435
+
436
  $blogs = get_sites();
437
  foreach ( $blogs as $blog ) {
438
  $blog_basic = get_blog_option( (int) $blog->blog_id, 'breeze_basic_settings', '' );
441
  }
442
 
443
  $blog_advanced = get_blog_option( (int) $blog->blog_id, 'breeze_advanced_settings', '' );
444
+ if ( empty( $blog_advanced ) || empty( $is_advanced ) ) {
445
+ $save_advanced = $advanced;
446
+
447
+ if ( isset( $breeze_delay_js_scripts ) ) {
448
+ if ( empty( $blog_advanced ) ) {
449
+ $save_advanced['breeze-delay-js-scripts'] = $breeze_delay_js_scripts;
450
+ } else {
451
+ $save_advanced = $blog_advanced;
452
+ $save_advanced['breeze-delay-js-scripts'] = $breeze_delay_js_scripts;
453
+ }
454
+
455
+ }
456
+ update_blog_option( (int) $blog->blog_id, 'breeze_advanced_settings', $save_advanced );
457
  }
458
 
459
  $blog_cdn = get_blog_option( (int) $blog->blog_id, 'breeze_cdn_integration', '' );
466
  update_blog_option( (int) $blog->blog_id, 'breeze_varnish_cache', $varnish );
467
  }
468
  }
469
+
470
+ if ( $network_wide ) {
471
+ $network_basic = breeze_get_option( 'basic_settings' );
472
+ if ( ! $network_basic ) {
473
+ breeze_update_option( 'basic_settings', $basic );
474
+ }
475
+
476
+ $network_advanced = breeze_get_option( 'advanced_settings' );
477
+ if ( ! $network_advanced || empty( $is_advanced ) ) {
478
+ $save_advanced = $advanced;
479
+
480
+ if ( isset( $breeze_delay_js_scripts ) ) {
481
+ if ( empty( $network_advanced ) ) {
482
+ $save_advanced['breeze-delay-js-scripts'] = $breeze_delay_js_scripts;
483
+ } else {
484
+ $save_advanced = $network_advanced;
485
+ $save_advanced['breeze-delay-js-scripts'] = $breeze_delay_js_scripts;
486
+ }
487
+
488
+ }
489
+
490
+ breeze_update_option( 'advanced_settings', $save_advanced, true );
491
+ }
492
+
493
+ $network_cdn = breeze_get_option( 'cdn_integration' );
494
+ if ( ! $network_cdn ) {
495
+ breeze_update_option( 'cdn_integration', $cdn );
496
+ }
497
+
498
+ $network_varnish = breeze_get_option( 'varnish_cache' );
499
+ if ( ! $network_varnish ) {
500
+ breeze_update_option( 'varnish_cache', $varnish );
501
+ }
502
+ }
503
  } else {
504
+ $singe_network_basic = breeze_get_option( 'basic_settings' );
505
+ if ( ! $singe_network_basic ) {
506
+ breeze_update_option( 'basic_settings', $basic );
507
+ }
508
+
509
+ $singe_network_advanced = breeze_get_option( 'advanced_settings' );
510
+ if ( ! $singe_network_advanced || empty( $is_advanced ) ) {
511
+ $save_advanced = $advanced;
512
+
513
+ if ( isset( $breeze_delay_js_scripts ) ) {
514
+ if ( empty( $singe_network_advanced ) ) {
515
+ $save_advanced['breeze-delay-js-scripts'] = $breeze_delay_js_scripts;
516
+ } else {
517
+ $save_advanced = $singe_network_advanced;
518
+ $save_advanced['breeze-delay-js-scripts'] = $breeze_delay_js_scripts;
519
+ }
520
+ }
521
+
522
+ breeze_update_option( 'advanced_settings', $save_advanced, true );
523
+ }
524
+
525
+ $singe_network_cdn = breeze_get_option( 'cdn_integration' );
526
+ if ( ! $singe_network_cdn ) {
527
+ breeze_update_option( 'cdn_integration', $cdn );
528
+ }
529
+
530
+ $singe_network_varnish = breeze_get_option( 'varnish_cache' );
531
+ if ( ! $singe_network_varnish ) {
532
+ breeze_update_option( 'varnish_cache', $varnish );
533
+ }
534
  }
535
 
536
  //add header to htaccess if setting is enabled or by default if first installed
inc/breeze-configuration.php CHANGED
@@ -55,9 +55,11 @@ class Breeze_Configuration {
55
 
56
  $basic = array(
57
  'breeze-active' => ( isset( $_POST['cache-system'] ) ? '1' : '0' ),
 
58
  'breeze-ttl' => (int) $_POST['cache-ttl'],
59
  'breeze-minify-html' => ( isset( $_POST['minification-html'] ) ? '1' : '0' ),
60
  'breeze-minify-css' => ( isset( $_POST['minification-css'] ) ? '1' : '0' ),
 
61
  'breeze-minify-js' => ( isset( $_POST['minification-js'] ) ? '1' : '0' ),
62
  'breeze-gzip-compression' => ( isset( $_POST['gzip-compression'] ) ? '1' : '0' ),
63
  'breeze-browser-cache' => ( isset( $_POST['browser-cache'] ) ? '1' : '0' ),
@@ -101,16 +103,30 @@ class Breeze_Configuration {
101
  $exclude_urls = $this->string_convert_arr( sanitize_textarea_field( $_POST['exclude-urls'] ) );
102
  $exclude_css = $this->string_convert_arr( sanitize_textarea_field( $_POST['exclude-css'] ) );
103
  $exclude_js = $this->string_convert_arr( sanitize_textarea_field( $_POST['exclude-js'] ) );
104
- $move_to_footer_js = $defer_js = array();
 
105
 
106
  if ( ! empty( $exclude_js ) ) {
107
  $exclude_js = array_unique( $exclude_js );
108
  }
 
 
 
109
 
110
  if ( ! empty( $exclude_css ) ) {
111
  $exclude_css = array_unique( $exclude_css );
112
  }
113
 
 
 
 
 
 
 
 
 
 
 
114
  if ( ! empty( $_POST['move-to-footer-js'] ) ) {
115
  foreach ( $_POST['move-to-footer-js'] as $url ) {
116
  if ( trim( $url ) == '' ) {
@@ -135,10 +151,15 @@ class Breeze_Configuration {
135
  'breeze-exclude-urls' => $exclude_urls,
136
  'breeze-group-css' => ( isset( $_POST['group-css'] ) ? '1' : '0' ),
137
  'breeze-group-js' => ( isset( $_POST['group-js'] ) ? '1' : '0' ),
 
 
 
138
  'breeze-exclude-css' => $exclude_css,
139
  'breeze-exclude-js' => $exclude_js,
140
  'breeze-move-to-footer-js' => $move_to_footer_js,
141
  'breeze-defer-js' => $defer_js,
 
 
142
  );
143
 
144
  breeze_update_option( 'advanced_settings', $advanced, true );
@@ -337,6 +358,7 @@ class Breeze_Configuration {
337
  * Trigger update to htaccess file.
338
  *
339
  * @param bool $clean If true, will clear custom .htaccess rules.
 
340
  * @return bool
341
  */
342
  public static function update_htaccess( $clean = false ) {
@@ -500,6 +522,7 @@ class Breeze_Configuration {
500
  * Add and remove custom blocks from .htaccess.
501
  *
502
  * @param array $args
 
503
  * @return bool
504
  */
505
  public static function write_htaccess( $args ) {
55
 
56
  $basic = array(
57
  'breeze-active' => ( isset( $_POST['cache-system'] ) ? '1' : '0' ),
58
+ 'breeze-cross-origin' => ( isset( $_POST['safe-cross-origin'] ) ? '1' : '0' ),
59
  'breeze-ttl' => (int) $_POST['cache-ttl'],
60
  'breeze-minify-html' => ( isset( $_POST['minification-html'] ) ? '1' : '0' ),
61
  'breeze-minify-css' => ( isset( $_POST['minification-css'] ) ? '1' : '0' ),
62
+ 'breeze-font-display-swap' => ( isset( $_POST['font-display'] ) ? '1' : '0' ),
63
  'breeze-minify-js' => ( isset( $_POST['minification-js'] ) ? '1' : '0' ),
64
  'breeze-gzip-compression' => ( isset( $_POST['gzip-compression'] ) ? '1' : '0' ),
65
  'breeze-browser-cache' => ( isset( $_POST['browser-cache'] ) ? '1' : '0' ),
103
  $exclude_urls = $this->string_convert_arr( sanitize_textarea_field( $_POST['exclude-urls'] ) );
104
  $exclude_css = $this->string_convert_arr( sanitize_textarea_field( $_POST['exclude-css'] ) );
105
  $exclude_js = $this->string_convert_arr( sanitize_textarea_field( $_POST['exclude-js'] ) );
106
+ $delay_js = $this->string_convert_arr( sanitize_textarea_field( $_POST['delay-js-scripts'] ) );
107
+ $preload_fonts = $move_to_footer_js = $defer_js = array();
108
 
109
  if ( ! empty( $exclude_js ) ) {
110
  $exclude_js = array_unique( $exclude_js );
111
  }
112
+ if ( ! empty( $delay_js ) ) {
113
+ $delay_js = array_unique( $delay_js );
114
+ }
115
 
116
  if ( ! empty( $exclude_css ) ) {
117
  $exclude_css = array_unique( $exclude_css );
118
  }
119
 
120
+ if ( isset( $_POST['breeze-preload-font'] ) && ! empty( $_POST['breeze-preload-font'] ) ) {
121
+ foreach ( $_POST['breeze-preload-font'] as $font_url ) {
122
+ if ( trim( $font_url ) == '' ) {
123
+ continue;
124
+ }
125
+ $font_url = current( explode( '?', $font_url, 2 ) );
126
+ $preload_fonts[ sanitize_text_field( $font_url ) ] = sanitize_text_field( $font_url );
127
+ }
128
+ }
129
+
130
  if ( ! empty( $_POST['move-to-footer-js'] ) ) {
131
  foreach ( $_POST['move-to-footer-js'] as $url ) {
132
  if ( trim( $url ) == '' ) {
151
  'breeze-exclude-urls' => $exclude_urls,
152
  'breeze-group-css' => ( isset( $_POST['group-css'] ) ? '1' : '0' ),
153
  'breeze-group-js' => ( isset( $_POST['group-js'] ) ? '1' : '0' ),
154
+ 'breeze-lazy-load' => ( isset( $_POST['bz-lazy-load'] ) ? '1' : '0' ),
155
+ 'breeze-lazy-load-native' => ( isset( $_POST['bz-lazy-load-nat'] ) ? '1' : '0' ),
156
+ 'breeze-preload-links' => ( isset( $_POST['preload-links'] ) ? '1' : '0' ),
157
  'breeze-exclude-css' => $exclude_css,
158
  'breeze-exclude-js' => $exclude_js,
159
  'breeze-move-to-footer-js' => $move_to_footer_js,
160
  'breeze-defer-js' => $defer_js,
161
+ 'breeze-delay-js-scripts' => $delay_js,
162
+ 'breeze-preload-fonts' => $preload_fonts,
163
  );
164
 
165
  breeze_update_option( 'advanced_settings', $advanced, true );
358
  * Trigger update to htaccess file.
359
  *
360
  * @param bool $clean If true, will clear custom .htaccess rules.
361
+ *
362
  * @return bool
363
  */
364
  public static function update_htaccess( $clean = false ) {
522
  * Add and remove custom blocks from .htaccess.
523
  *
524
  * @param array $args
525
+ *
526
  * @return bool
527
  */
528
  public static function write_htaccess( $args ) {
inc/cache/config-cache.php CHANGED
@@ -173,6 +173,10 @@ class Breeze_ConfigCache {
173
  $storage['blog_id'] = get_current_blog_id();
174
  }
175
 
 
 
 
 
176
  if ( class_exists( 'WooCommerce' ) ) {
177
  $ecommerce_exclude_urls = Breeze_Ecommerce_Cache::factory()->ecommerce_exclude_pages();
178
  }
173
  $storage['blog_id'] = get_current_blog_id();
174
  }
175
 
176
+ $storage['enabled-lazy-load'] = ( isset( $config['breeze-lazy-load'] ) ? $config['breeze-lazy-load'] : 0 );
177
+ $storage['use-lazy-load-native'] = ( isset( $config['breeze-lazy-load-native'] ) ? $config['breeze-lazy-load-native'] : 0 );
178
+ $storage['breeze-preload-links'] = ( isset( $config['breeze-preload-links'] ) ? $config['breeze-preload-links'] : 0 );
179
+
180
  if ( class_exists( 'WooCommerce' ) ) {
181
  $ecommerce_exclude_urls = Breeze_Ecommerce_Cache::factory()->ecommerce_exclude_pages();
182
  }
inc/cache/execute-cache.php CHANGED
@@ -7,6 +7,9 @@ defined( 'ABSPATH' ) || exit;
7
  // Load helper functions.
8
  require_once dirname( __DIR__ ) . '/functions.php';
9
 
 
 
 
10
  // Include and instantiate the class.
11
  require_once 'Mobile-Detect-2.8.25/Mobile_Detect.php';
12
  $detect = new \Cloudways\Breeze\Mobile_Detect\Mobile_Detect;
@@ -213,6 +216,61 @@ function breeze_cache( $buffer, $flags ) {
213
  );
214
  }
215
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  $data = serialize(
217
  array(
218
  'body' => $buffer,
@@ -360,6 +418,7 @@ function breeze_serve_cache( $filename, $url_path, $X1, $opts ) {
360
  header( 'Vary: Accept-Encoding' );
361
  echo $content;
362
  } else {
 
363
  //render page cache
364
  echo $datas['body'];
365
  }
7
  // Load helper functions.
8
  require_once dirname( __DIR__ ) . '/functions.php';
9
 
10
+ // Load lazy Load class.
11
+ require_once dirname( __DIR__ ) . '/class-breeze-lazy-load.php';
12
+
13
  // Include and instantiate the class.
14
  require_once 'Mobile-Detect-2.8.25/Mobile_Detect.php';
15
  $detect = new \Cloudways\Breeze\Mobile_Detect\Mobile_Detect;
216
  );
217
  }
218
 
219
+ // Lazy load implementation
220
+ if ( class_exists( 'Breeze_Lazy_Load' ) ) {
221
+ $is_lazy_load_enabled = filter_var( $GLOBALS['breeze_config']['enabled-lazy-load'], FILTER_VALIDATE_BOOLEAN );
222
+ $is_lazy_load_native = filter_var( $GLOBALS['breeze_config']['use-lazy-load-native'], FILTER_VALIDATE_BOOLEAN );
223
+
224
+ $lazy_load = new Breeze_Lazy_Load( $buffer, $is_lazy_load_enabled, $is_lazy_load_native );
225
+ $buffer = $lazy_load->apply_lazy_load_feature();
226
+ }
227
+
228
+ if ( isset( $GLOBALS['breeze_config']['cache_options']['breeze-cross-origin'] ) && filter_var( $GLOBALS['breeze_config']['cache_options']['breeze-cross-origin'], FILTER_VALIDATE_BOOLEAN ) ) {
229
+ // Extract all <a> tags from the page.
230
+ preg_match_all( '/(?i)<a ([^>]+)>(.+?)<\/a>/', $buffer, $matches );
231
+
232
+ $home_url = $GLOBALS['breeze_config']['homepage'];
233
+ $home_url = ltrim( $home_url, 'https:' );
234
+
235
+ if ( ! empty( $matches ) && isset( $matches[0] ) && ! empty( $matches[0] ) ) {
236
+ $current_links = $matches[0];
237
+
238
+ foreach ( $current_links as $index => $html_a_tag ) {
239
+ // If the A tag qualifies.
240
+ if (
241
+ false === strpos( $html_a_tag, $home_url ) &&
242
+ false !== strpos( $html_a_tag, 'target' ) &&
243
+ false !== strpos( $html_a_tag, '_blank' )
244
+ ) {
245
+ $anchor_attributed = new SimpleXMLElement( $html_a_tag );
246
+ // Only apply on valid URLS.
247
+ if (
248
+ ! empty( $anchor_attributed ) &&
249
+ isset( $anchor_attributed['href'] ) &&
250
+ filter_var( $anchor_attributed['href'], FILTER_VALIDATE_URL )
251
+ ) {
252
+ // Apply noopener noreferrer on the A tag
253
+ $replacement_rel = 'noopener noreferrer';
254
+ $html_a_tag_replace = $html_a_tag;
255
+ if ( isset( $anchor_attributed['rel'] ) && ! empty( $anchor_attributed['rel'] ) ) {
256
+ if ( false === strpos( $anchor_attributed['rel'], 'noopener' ) && false === strpos( $anchor_attributed['rel'], 'noreferrer' ) ) {
257
+ $replacement_rel = 'noopener noreferrer';
258
+ } elseif ( false === strpos( $anchor_attributed['rel'], 'noopener' ) ) {
259
+ $replacement_rel = 'noopener';
260
+ } elseif ( false === strpos( $anchor_attributed['rel'], 'noreferrer' ) ) {
261
+ $replacement_rel = 'noreferrer';
262
+ }
263
+ $replacement_rel .= ' ' . $anchor_attributed['rel'];
264
+ $html_a_tag_replace = preg_replace( '/(<[^>]+) rel=".*?"/i', '$1', $html_a_tag );
265
+ }
266
+ $html_a_tag_rel = preg_replace( '/(<a\b[^><]*)>/i', '$1 rel="' . $replacement_rel . '">', $html_a_tag_replace );
267
+ $buffer = str_replace( $html_a_tag, $html_a_tag_rel, $buffer );
268
+ }
269
+ }
270
+ }
271
+ }
272
+ }
273
+
274
  $data = serialize(
275
  array(
276
  'body' => $buffer,
418
  header( 'Vary: Accept-Encoding' );
419
  echo $content;
420
  } else {
421
+ header( 'Content-Length: ' . strlen( $datas['body'] ) );
422
  //render page cache
423
  echo $datas['body'];
424
  }
inc/class-breeze-lazy-load.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ header( 'Status: 403 Forbidden' );
4
+ header( 'HTTP/1.1 403 Forbidden' );
5
+ exit;
6
+ }
7
+
8
+ class Breeze_Lazy_Load {
9
+ /**
10
+ * Whether Lazy load is active.
11
+ * @var false|mixed
12
+ * @since 1.2.0
13
+ * @access private
14
+ */
15
+ private $lazy_load_enabled = false;
16
+
17
+ /**
18
+ * Must use native Lazy Load.
19
+ * @var false|mixed
20
+ * @since 1.2.0
21
+ * @access private
22
+ */
23
+ private $lazy_load_native = false;
24
+
25
+ /**
26
+ * The page HTML content.
27
+ *
28
+ * @var string
29
+ * @since 1.2.0
30
+ * @access private
31
+ */
32
+ private $content = '';
33
+
34
+ /**
35
+ * Exclude images that have these attributes from processing.
36
+ *
37
+ * @since 1.2.0
38
+ * @var string[]
39
+ */
40
+ private $exclude_if_atts = array();
41
+
42
+ /**
43
+ * Breeze_Lazy_Load constructor.
44
+ *
45
+ * @param false $is_enabled If the base Lazy Load is enabled.
46
+ * @param string $content the HTML content of the page.
47
+ * @param false $is_native Whether to use native lazy load or Javascript based.
48
+ *
49
+ * @access public
50
+ * @since 1.2.0
51
+ */
52
+ function __construct( $content = '', $is_enabled = false, $is_native = false ) {
53
+ $this->lazy_load_enabled = $is_enabled;
54
+ $this->lazy_load_native = $is_native;
55
+ $this->content = $content;
56
+
57
+ $this->exclude_if_atts = apply_filters(
58
+ 'breeze_excluded_attributes',
59
+ array(
60
+ 'data-src',
61
+ 'data-no-lazy',
62
+ 'data-lazy-original',
63
+ 'data-lazy-src',
64
+ 'data-lazysrc',
65
+ 'data-lazyload',
66
+ 'data-bgposition',
67
+ 'data-envira-src',
68
+ 'fullurl',
69
+ 'lazy-slider-img',
70
+ 'data-srcset',
71
+ 'data-spai',
72
+ )
73
+ );
74
+
75
+ }
76
+
77
+ /**
78
+ * Apply lazy load library option.
79
+ *
80
+ * @return false|string
81
+ * @access public
82
+ * @since 1.2.0
83
+ */
84
+ public function apply_lazy_load_feature() {
85
+ $content = $this->content;
86
+
87
+ if ( false === $this->lazy_load_enabled ) {
88
+ return $content;
89
+ }
90
+
91
+ if ( '' === trim( $content ) ) {
92
+ return $content;
93
+ }
94
+
95
+ // If this option is set to true then loading="lazy" attribute will be use instead.
96
+ // The native lazy load is not yet supported by all browsers. ( As of February 2021, 73% of browsers support lazy loading. )
97
+ $use_native = apply_filters( 'breeze_use_native_lazy_load', $this->lazy_load_native );
98
+
99
+ $html_dom = new DOMDocument();
100
+ $html_dom->preserveWhiteSpace = false;// phpcs:ignore
101
+ $html_dom->formatOutput = false;// phpcs:ignore
102
+
103
+ libxml_use_internal_errors( true );
104
+ $html_dom->loadHTML( $content, LIBXML_NOERROR ); // | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
105
+
106
+ $dom_last_error = libxml_get_last_error();
107
+ #error_log( '$dom_last_error: ' . var_export( $dom_last_error, true ) );
108
+ $dom_all_error = libxml_get_errors();
109
+ #error_log( '$dom_all_error: ' . var_export( $dom_all_error, true ) );
110
+
111
+ $dom_xpath = new DOMXPath( $html_dom );
112
+ /**
113
+ * Fetch all images
114
+ */
115
+ $get_dom_images = $dom_xpath->query( '//img' );
116
+ if ( ! is_null( $get_dom_images ) ) {
117
+ foreach ( $get_dom_images as $image_element ) {
118
+ // If native is enabled.
119
+ if ( true === $use_native ) {
120
+ $loading = $image_element->getAttribute( 'loading' );
121
+ if ( ! empty( $loading ) ) {
122
+ $image_element->setAttribute( 'loading', 'lazy' );
123
+ }
124
+ } else {
125
+ // Going the classic way by implementing lazy load via JavaScript.
126
+
127
+ // Check if the image is to be ignored.
128
+ if ( is_array( $this->exclude_if_atts ) && ! empty( $this->exclude_if_atts ) ) {
129
+ $exclude_it = false;
130
+ foreach ( $this->exclude_if_atts as $ex_attr ) {
131
+ $exclude_found = $image_element->getAttribute( $ex_attr );
132
+ if ( ! empty( $exclude_found ) ) {
133
+ $exclude_it = true;
134
+ }
135
+ }
136
+
137
+ if ( true === $exclude_it ) {
138
+ continue;
139
+ }
140
+ }
141
+ // Get the image URL
142
+ $current_src = $image_element->getAttribute( 'src' );
143
+ if ( true !== $this->excluded_images( $current_src ) ) {
144
+ // Add lazy-load data attribute.
145
+ $image_element->setAttribute( 'data-breeze', $current_src );
146
+ // Remove the current image source.
147
+ $image_element->removeAttribute( 'src' );
148
+ $get_width = $image_element->getAttribute( 'width' );
149
+ $get_height = $image_element->getAttribute( 'height' );
150
+ $image_element->setAttribute( 'src', $this->generate_simple_placeholder( $get_width, $get_height ) );
151
+
152
+ // Fetch the current image CSS classes.
153
+ $current_classes = $image_element->getAttribute( 'class' );
154
+ // Append breeze lazy-load CSS class.
155
+ if ( empty( trim( $current_classes ) ) ) {
156
+ $current_classes = 'br-lazy';
157
+ } else {
158
+ $current_classes .= ' br-lazy';
159
+ }
160
+ $image_element->removeAttribute( 'class' );
161
+ $image_element->setAttribute( 'class', $current_classes );
162
+
163
+ // handle SRCSET and SIZES attributes.
164
+ $srcset = $image_element->getAttribute( 'srcset' );
165
+ $sizes = $image_element->getAttribute( 'sizes' );
166
+ if ( ! empty( $srcset ) ) {
167
+ $image_element->setAttribute( 'data-brsrcset', $srcset );
168
+ $image_element->removeAttribute( 'srcset' );
169
+ }
170
+
171
+ if ( ! empty( $sizes ) ) {
172
+ $image_element->setAttribute( 'data-brsizes', $sizes );
173
+ $image_element->removeAttribute( 'sizes' );
174
+ }
175
+ }
176
+ }
177
+ }
178
+ }
179
+
180
+ return $html_dom->saveHTML();
181
+ }
182
+
183
+ /**
184
+ * We need to exclude some images with very specific functionality.
185
+ * Example of excluded: Captcha, WooCommerce placeholder image.
186
+ *
187
+ * @param string $image_url The image full URL path.
188
+ *
189
+ * @return bool
190
+ * @since 1.2.0
191
+ * @access private
192
+ */
193
+ private function excluded_images( $image_url = '' ) {
194
+ $excluded_images_by_url = apply_filters(
195
+ 'breeze_excluded_images_url',
196
+ array(
197
+ 'wpcf7_captcha/', // Contact Form 7 - Really Simple CAPTCHA.
198
+ 'woocommerce/assets/images/placeholder.png',
199
+ )
200
+ );
201
+
202
+ if ( ! empty( $excluded_images_by_url ) ) {
203
+ foreach ( $excluded_images_by_url as $partial_path ) {
204
+ if ( false !== strpos( $image_url, $partial_path ) ) {
205
+ return true;
206
+ }
207
+ }
208
+ }
209
+
210
+ return false;
211
+ }
212
+
213
+ /**
214
+ * Generate a simple svg placeholder image.
215
+ *
216
+ * @param int $width Original image width.
217
+ * @param int $height Original image height.
218
+ *
219
+ * @return string
220
+ * @access private
221
+ * @since 1.2.0
222
+ */
223
+ private function generate_simple_placeholder( $width = 0, $height = 0 ) {
224
+ if ( ! is_numeric( $width ) ) {
225
+ $width = 0;
226
+ }
227
+
228
+ if ( ! is_numeric( $height ) ) {
229
+ $height = 0;
230
+ }
231
+
232
+ if ( ! empty( $width ) ) {
233
+ $width = absint( $width );
234
+ }
235
+
236
+ if ( ! empty( $height ) ) {
237
+ $height = absint( $height );
238
+ }
239
+
240
+ return "data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20{$width}%20{$height}'%3E%3C/svg%3E";
241
+ }
242
+ }
inc/class-breeze-prefetch.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ header( 'Status: 403 Forbidden' );
5
+ header( 'HTTP/1.1 403 Forbidden' );
6
+ exit;
7
+ }
8
+
9
+ if ( ! class_exists( 'Breeze_Prefetch' ) ) {
10
+ /**
11
+ * Handles the Prefetch functionality.
12
+ *
13
+ * Class Breeze_Prefetch
14
+ * v
15
+ */
16
+ class Breeze_Prefetch {
17
+
18
+ public function __construct() {
19
+ add_action( 'wp_enqueue_scripts', array( $this, 'load_prefetch_scripts' ) );
20
+ }
21
+
22
+ /**
23
+ * Load Prefetch JavaScript library.
24
+ * @since 1.2.0
25
+ * @access public
26
+ */
27
+ public function load_prefetch_scripts() {
28
+ $breeze_options = breeze_get_option( 'advanced_settings' );
29
+ // Check if the option is enabled by admin.
30
+ if ( isset( $breeze_options['breeze-preload-links'] ) && true === filter_var( $breeze_options['breeze-preload-links'], FILTER_VALIDATE_BOOLEAN ) ) {
31
+ // Load the prefetch library.
32
+ wp_enqueue_script( 'breeze-prefetch', BREEZE_PLUGIN_URL . 'assets/js/breeze-prefetch-links.js', array(), time(), false );
33
+ wp_localize_script(
34
+ 'breeze-prefetch',
35
+ 'breeze_prefetch',
36
+ array(
37
+ 'local_url' => home_url(),
38
+ 'ignore_remote_prefetch' => true,
39
+ 'ignore_list' => $this->href_ignore_list(),
40
+ )
41
+ );
42
+ }
43
+ }
44
+
45
+
46
+ /**
47
+ * The list of links that do not need prefetch.
48
+ *
49
+ * @return array|mixed
50
+ * @since 1.2.0
51
+ * @access public
52
+ */
53
+ public function href_ignore_list() {
54
+
55
+ $exclude_urls = array();
56
+
57
+ if (
58
+ isset( $GLOBALS['breeze_config'] ) &&
59
+ isset( $GLOBALS['breeze_config']['exclude_url'] ) &&
60
+ ! empty( $GLOBALS['breeze_config']['exclude_url'] )
61
+ ) {
62
+ $exclude_urls = $GLOBALS['breeze_config']['exclude_url'];
63
+
64
+ $clear_star = function ( $value ) {
65
+ $value = str_replace( '*', '', $value );
66
+ $value = str_replace( home_url(), '', $value );
67
+
68
+ return $value;
69
+ };
70
+ $exclude_urls = array_map( $clear_star, $exclude_urls );
71
+ }
72
+ $exclude_urls[] = '/wp-admin/';
73
+
74
+ return $exclude_urls;
75
+ }
76
+ }
77
+
78
+ new Breeze_Prefetch();
79
+ }
inc/class-breeze-preload-fonts.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined( 'ABSPATH' ) ) {
4
+ header( 'Status: 403 Forbidden' );
5
+ header( 'HTTP/1.1 403 Forbidden' );
6
+ exit;
7
+ }
8
+
9
+ if ( ! class_exists( 'Breeze_Preload_Fonts' ) ) {
10
+ /**
11
+ * Handles the Prefetch functionality.
12
+ *
13
+ * Class Breeze_Prefetch
14
+ * @since 1.2.0
15
+ */
16
+ class Breeze_Preload_Fonts {
17
+
18
+ public function __construct() {
19
+ add_action( 'wp_head', array( $this, 'load_preload_scripts' ) );
20
+ }
21
+
22
+ /**
23
+ * Preload the website fonts added in the options.
24
+ *
25
+ * @since 1.2.0
26
+ * @access public
27
+ */
28
+ public function load_preload_scripts() {
29
+ $breeze_options = breeze_get_option( 'advanced_settings' );
30
+ $fonts_extensions = array(
31
+ 'woff',
32
+ 'woff2',
33
+ 'ttf',
34
+ 'eot',
35
+ 'bmap',
36
+ 'otf',
37
+ 'otf',
38
+ 'svg',
39
+ );
40
+
41
+ $fonts_extensions = apply_filters( 'breeze_preload_fonts_exception', $fonts_extensions );
42
+
43
+ // Check if the option is enabled by admin.
44
+ if ( isset( $breeze_options['breeze-preload-fonts'] ) && ! empty( $breeze_options['breeze-preload-fonts'] ) ) {
45
+
46
+ foreach ( $breeze_options['breeze-preload-fonts'] as $index => $preload_url ) {
47
+ $extension = pathinfo( $preload_url, PATHINFO_EXTENSION );
48
+
49
+ if ( 'css' === $extension ) {
50
+ echo '<link rel="preload" as="style" onload="this.rel = \'stylesheet\'" href="' . $preload_url . '" crossorigin>' . "\n";
51
+ } elseif ( in_array( $extension, $fonts_extensions ) ) {
52
+ echo '<link rel="preload" as="font" type="font/' . $extension . '" href="' . $preload_url . '" crossorigin>' . "\n";
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ }
59
+
60
+ new Breeze_Preload_Fonts();
61
+ }
inc/compatibility/class-breeze-shortpixel-compatibility.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ header( 'Status: 403 Forbidden' );
4
+ header( 'HTTP/1.1 403 Forbidden' );
5
+ exit;
6
+ }
7
+
8
+ if ( ! class_exists( 'Breeze_Shortpixel_Compatibility' ) ) {
9
+ class Breeze_Shortpixel_Compatibility {
10
+
11
+ function __construct() {
12
+ // on ShortPixel Clear cache.
13
+ add_action( 'wp_ajax_shortpixel_ai_handle_page_action', array( &$this, 'clear_breeze_cache' ), 5 );
14
+
15
+ add_action( 'init', array( &$this, 'schedule_breeze_cache_reset' ) );
16
+
17
+ add_action( 'breeze_pixel_cache_event', array( &$this, 'clear_all_breeze_cache' ) );
18
+ }
19
+
20
+ public function schedule_breeze_cache_reset() {
21
+ // If ShortPixel event is active, we get the next running time.
22
+ $next_timer = wp_next_scheduled( 'spai_lqip_generate_event' );
23
+ if ( false !== $next_timer ) {
24
+ $next_timer = $next_timer + 30; // add 30 seconds.
25
+ // Clear the the Breeze cache using a single event.
26
+ wp_schedule_single_event( $next_timer, 'breeze_pixel_cache_event', array() );
27
+ }
28
+ }
29
+
30
+
31
+ public function clear_breeze_cache() {
32
+ $data = $_POST['data'];
33
+
34
+ $action = isset( $data['action'] ) ? $data['action'] : null;
35
+ // Clear LQIP cache and Clear CSS cache.
36
+ if ( 'clear lqip cache' === $action || 'clear css cache' === $action ) {
37
+ $this->clear_all_breeze_cache();
38
+ }
39
+
40
+
41
+ }
42
+
43
+ public function clear_all_breeze_cache() {
44
+ //delete cache after settings
45
+ do_action( 'breeze_clear_all_cache' );
46
+ }
47
+ }
48
+
49
+ new Breeze_Shortpixel_Compatibility();
50
+ }
inc/minification/breeze-js-deferred-loading.php CHANGED
@@ -141,6 +141,22 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
141
  'post_id',
142
  'data-noptimize',
143
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
  /**
146
  * Reads the page content and fetches the JavaScript script tags.
@@ -153,6 +169,11 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
153
  */
154
  public function read( $options = array() ) {
155
 
 
 
 
 
 
156
  // Read the list of scripts that need defer tag.
157
  if ( ! empty( $options['defer_js'] ) ) {
158
  $this->defer_js = $options['defer_js'];
@@ -236,6 +257,13 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
236
  continue;
237
  }
238
 
 
 
 
 
 
 
 
239
  // External script
240
  $url = current( explode( '?', $source[2], 2 ) );
241
  if ( $url[0] == "'" || $url[0] == '"' ) {
@@ -286,6 +314,22 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
286
  $this->move['first'][] = $tag;
287
  }
288
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  //We shouldn't touch this
290
  $tag = '';
291
  }
@@ -307,6 +351,21 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
307
  }
308
  //Remove the original script tag
309
  $content = str_replace( $tag, '', $content );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
  }
311
  }
312
  }
@@ -364,6 +423,47 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
364
  }
365
  }
366
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  // Load inline JS to html
368
  if ( ! empty( $this->head_scripts ) ) {
369
 
@@ -379,7 +479,14 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
379
 
380
  $js_url_trim = ltrim( $js_url, 'https:' );
381
 
382
- if ( gettype( $js_url ) == 'string' && ( in_array( $js_url, $this->defer_js ) || in_array( $js_url_trim, $this->defer_js ) ) ) {
 
 
 
 
 
 
 
383
  $defer = 'defer ';
384
  }
385
 
@@ -402,7 +509,14 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
402
 
403
  $js_url_trim = ltrim( $js_url, 'https:' );
404
 
405
- if ( gettype( $js_url ) == 'string' && ( in_array( $js_url, $this->defer_js ) || in_array( $js_url_trim, $this->defer_js ) ) ) {
 
 
 
 
 
 
 
406
  $defer = 'defer ';
407
  }
408
 
@@ -494,6 +608,24 @@ class Breeze_Js_Deferred_Loading extends Breeze_MinificationBase {
494
  return true;
495
  }
496
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
497
  /**
498
  * Move the script last
499
  *
141
  'post_id',
142
  'data-noptimize',
143
  );
144
+ /**
145
+ * Defer/Delay the inline scripts.
146
+ *
147
+ * @var array
148
+ */
149
+ private $delay_inline_js = array();
150
+
151
+ /**
152
+ * Contains all the scripts that will be delayed.
153
+ *
154
+ * @var array
155
+ */
156
+ private $delay_scripts = array(
157
+ 'header' => array(),
158
+ 'footer' => array(),
159
+ );
160
 
161
  /**
162
  * Reads the page content and fetches the JavaScript script tags.
169
  */
170
  public function read( $options = array() ) {
171
 
172
+ // Inline delay scripts
173
+ if ( ! empty( $options['delay_inline_js'] ) ) {
174
+ $this->delay_inline_js = $options['delay_inline_js'];
175
+ }
176
+
177
  // Read the list of scripts that need defer tag.
178
  if ( ! empty( $options['defer_js'] ) ) {
179
  $this->defer_js = $options['defer_js'];
257
  continue;
258
  }
259
 
260
+ // Get the script version.
261
+ $script_version = '';
262
+ $explode_url = explode( '?', $source[2] );
263
+ if ( isset( $explode_url[1] ) ) {
264
+ $script_version = $explode_url[1];
265
+ }
266
+
267
  // External script
268
  $url = current( explode( '?', $source[2], 2 ) );
269
  if ( $url[0] == "'" || $url[0] == '"' ) {
314
  $this->move['first'][] = $tag;
315
  }
316
  } else {
317
+ $is_delayed = $this->is_inline_delay( $tag );
318
+ if ( $is_delayed ) {
319
+ if ( true === $head ) {
320
+ $this->delay_scripts['header'][ $url ] = array(
321
+ 'path' => $path,
322
+ 'version' => $script_version,
323
+ );
324
+ } else {
325
+ $this->delay_scripts['footer'][ $url ] = array(
326
+ 'path' => $path,
327
+ 'version' => $script_version,
328
+ );
329
+ }
330
+ $content = str_replace( $tag, '', $content );
331
+ }
332
+
333
  //We shouldn't touch this
334
  $tag = '';
335
  }
351
  }
352
  //Remove the original script tag
353
  $content = str_replace( $tag, '', $content );
354
+ } else {
355
+
356
+ $is_delayed = $this->is_inline_delay( $tag );
357
+ if ( true === $is_delayed ) {
358
+
359
+ preg_match( '#<script.*>(.*)</script>#Usmi', $tag, $code );
360
+ $code = preg_replace( '#.*<!\[CDATA\[(?:\s*\*/)?(.*)(?://|/\*)\s*?\]\]>.*#sm', '$1', $code[1] );
361
+ $code = preg_replace( '/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $code );
362
+ if ( true === $head ) {
363
+ $this->delay_scripts['header'][] = $code;
364
+ } else {
365
+ $this->delay_scripts['footer'][] = $code;
366
+ }
367
+ $content = str_replace( $tag, '', $content );
368
+ }
369
  }
370
  }
371
  }
423
  }
424
  }
425
 
426
+ // handle the 3rd party defer scripts in header.
427
+ if ( ! empty( $this->delay_scripts ) && ! empty( $this->delay_scripts['header'] ) ) {
428
+ $replace_tag = array( '</head>', 'before' );
429
+ $js_head_defer = array();
430
+ $defer = 'defer ';
431
+ foreach ( $this->delay_scripts['header'] as $js_url => $js_script ) {
432
+ if ( filter_var( $js_url, FILTER_VALIDATE_URL ) ) {
433
+ if ( ! empty( $js_script['version'] ) ) {
434
+ $js_url .= '?' . $js_script['version'];
435
+ }
436
+ $js_head_defer[] = "<script type='application/javascript' {$defer}src='{$js_url}'></script>\n";
437
+ } else {
438
+ $js_head_defer[] = "<script type='module'>{$js_script}</script>\n";
439
+ }
440
+ }
441
+ $js_replacement = '';
442
+ $js_replacement .= implode( '', $js_head_defer );
443
+ $this->inject_in_html( $js_replacement, $replace_tag );
444
+ }
445
+
446
+ // handle the 3rd party defer scripts in footer.
447
+ if ( ! empty( $this->delay_scripts ) && ! empty( $this->delay_scripts['footer'] ) ) {
448
+ $replace_tag = array( '</body>', 'before' );
449
+ $js_footer_defer = array();
450
+ $defer = 'defer ';
451
+ foreach ( $this->delay_scripts['footer'] as $js_url => $js_script ) {
452
+ if ( filter_var( $js_url, FILTER_VALIDATE_URL ) ) {
453
+ if ( ! empty( $js_script['version'] ) ) {
454
+ $js_url .= '?' . $js_script['version'];
455
+ }
456
+ $js_footer_defer[] = "<script type='application/javascript' {$defer}src='{$js_url}'></script>\n";
457
+ } else {
458
+ $js_footer_defer[] = "<script type='module'>{$js_script}</script>\n";
459
+ }
460
+ }
461
+
462
+ $js_replacement = '';
463
+ $js_replacement .= implode( '', $js_footer_defer );
464
+ $this->inject_in_html( $js_replacement, $replace_tag );
465
+ }
466
+
467
  // Load inline JS to html
468
  if ( ! empty( $this->head_scripts ) ) {
469
 
479
 
480
  $js_url_trim = ltrim( $js_url, 'https:' );
481
 
482
+ if (
483
+ gettype( $js_url ) == 'string' &&
484
+ (
485
+ in_array( $js_url, $this->defer_js ) ||
486
+ in_array( $js_url_trim, $this->defer_js ) ||
487
+ $this->is_inline_delay( $js_url )
488
+ )
489
+ ) {
490
  $defer = 'defer ';
491
  }
492
 
509
 
510
  $js_url_trim = ltrim( $js_url, 'https:' );
511
 
512
+ if (
513
+ gettype( $js_url ) == 'string' &&
514
+ (
515
+ in_array( $js_url, $this->defer_js ) ||
516
+ in_array( $js_url_trim, $this->defer_js ) ||
517
+ $this->is_inline_delay( $js_url )
518
+ )
519
+ ) {
520
  $defer = 'defer ';
521
  }
522
 
608
  return true;
609
  }
610
 
611
+ /**
612
+ * Check if the inline script is in the list of delay.
613
+ *
614
+ * @param $tag
615
+ *
616
+ * @return bool
617
+ */
618
+ private function is_inline_delay( $tag ) {
619
+ foreach ( $this->delay_inline_js as $match ) {
620
+ if ( strpos( $tag, $match ) !== false ) {
621
+ //Matched something
622
+ return true;
623
+ }
624
+ }
625
+
626
+ return false;
627
+ }
628
+
629
  /**
630
  * Move the script last
631
  *
inc/minification/breeze-minification-scripts.php CHANGED
@@ -44,6 +44,7 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
44
  'nonce',
45
  'post_id',
46
  'data-noptimize',
 
47
  );
48
  private $donotmove_exception = array( 'jQuery' );
49
 
@@ -61,6 +62,7 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
61
  'tiny_mce.js',
62
  'tinyMCEPreInit.go',
63
  'post_id',
 
64
  );
65
  private $trycatch = false;
66
  private $alreadyminified = false;
@@ -96,6 +98,22 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
96
  private $original_content = '';
97
  private $show_original_content = 0;
98
  private $do_process = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
  //Reads the page and collects script tags
101
  public function read( $options ) {
@@ -158,6 +176,11 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
158
  $this->defer_js = $options['defer_js'];
159
  }
160
 
 
 
 
 
 
161
  // filter to "late inject minified JS", default to true for now (it is faster)
162
  $this->inject_min_late = apply_filters( 'breeze_filter_js_inject_min_late', true );
163
 
@@ -241,6 +264,13 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
241
  continue;
242
  }
243
 
 
 
 
 
 
 
 
244
  // External script
245
  $url = current( explode( '?', $source[2], 2 ) );
246
  if ( $url[0] == "'" || $url[0] == '"' ) {
@@ -297,10 +327,26 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
297
  } else {
298
  $this->move['first'][] = $tag;
299
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  } else {
301
  //We shouldn't touch this
302
  $tag = '';
303
  }
 
 
304
  }
305
  } else {
306
  // Inline script
@@ -330,10 +376,24 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
330
  } else {
331
  $this->move['first'][] = $tag;
332
  }
 
 
 
 
 
 
 
 
 
 
 
 
333
  } else {
334
  //We shouldn't touch this
335
  $tag = '';
336
  }
 
 
337
  }
338
  // re-hide comments to be able to do the removal based on tag from $this->content
339
  $tag = $this->hide_comments( $tag );
@@ -624,9 +684,13 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
624
  $url_exists = false;
625
  } else {
626
  $url = breeze_CACHE_URL . breeze_current_user_type() . $cache->getname();
 
 
 
627
  $this->url_group_head[ $old_url ] = $this->url_replace_cdn( $url );
628
  }
629
  }
 
630
 
631
  foreach ( $this->js_min_footer as $old_url => $js_min ) {
632
  $namehash = substr( $js_min, 0, strpos( $js_min, '_breezejsgroup_' ) );
@@ -642,8 +706,13 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
642
  $url_exists = false;
643
  } else {
644
  $url = breeze_CACHE_URL . breeze_current_user_type() . $cache->getname();
 
 
 
645
  $this->url_group_footer[ $old_url ] = $this->url_replace_cdn( $url );
646
  }
 
 
647
  }
648
 
649
  if ( false === $url_exists ) {
@@ -671,8 +740,13 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
671
  $replaceTag = array( '</head>', 'before' );
672
 
673
  foreach ( $this->jscode_inline_head as $js ) {
 
 
 
674
  $jsHead[] = '<script type="text/javascript">' . $js . '</script>';
675
  }
 
 
676
  $jsReplacement = '';
677
  $jsReplacement .= implode( '', $jsHead );
678
  $this->inject_in_html( $jsReplacement, $replaceTag );
@@ -682,8 +756,12 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
682
  $replaceTag = array( '</body>', 'before' );
683
 
684
  foreach ( $this->jscode_inline_footer as $js ) {
 
 
 
685
  $jsFooter[] = '<script type="text/javascript">' . $js . '</script>';
686
  }
 
687
  $jsReplacement = '';
688
  $jsReplacement .= implode( '', $jsFooter );
689
  $this->inject_in_html( $jsReplacement, $replaceTag );
@@ -707,6 +785,49 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
707
  $this->inject_in_html( $bodyreplacement, $replaceTag );
708
  }
709
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
710
  $headScript = array();
711
  $footerScript = array();
712
 
@@ -715,7 +836,14 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
715
 
716
  foreach ( $this->url_group_head as $old_url => $url ) {
717
  $defer = '';
718
- if ( gettype( $old_url ) == 'string' && in_array( $old_url, $this->defer_js ) ) {
 
 
 
 
 
 
 
719
  $defer = 'defer ';
720
  }
721
 
@@ -738,7 +866,13 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
738
 
739
  foreach ( $this->url_group_footer as $old_url => $url ) {
740
  $defer = '';
741
- if ( gettype( $old_url ) == 'string' && in_array( $old_url, $this->defer_js ) ) {
 
 
 
 
 
 
742
  $defer = 'defer ';
743
  }
744
 
@@ -932,4 +1066,22 @@ class Breeze_MinificationScripts extends Breeze_MinificationBase {
932
 
933
  return false;
934
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
935
  }
44
  'nonce',
45
  'post_id',
46
  'data-noptimize',
47
+ 'googletagmanager',
48
  );
49
  private $donotmove_exception = array( 'jQuery' );
50
 
62
  'tiny_mce.js',
63
  'tinyMCEPreInit.go',
64
  'post_id',
65
+ 'googletagmanager',
66
  );
67
  private $trycatch = false;
68
  private $alreadyminified = false;
98
  private $original_content = '';
99
  private $show_original_content = 0;
100
  private $do_process = false;
101
+ /**
102
+ * Defer/Delay the inline scripts.
103
+ *
104
+ * @var array
105
+ */
106
+ private $delay_inline_js = array();
107
+
108
+ /**
109
+ * Contains all the scripts that will be delayed.
110
+ *
111
+ * @var array
112
+ */
113
+ private $delay_scripts = array(
114
+ 'header' => array(),
115
+ 'footer' => array(),
116
+ );
117
 
118
  //Reads the page and collects script tags
119
  public function read( $options ) {
176
  $this->defer_js = $options['defer_js'];
177
  }
178
 
179
+ // Inline delay scripts
180
+ if ( ! empty( $options['delay_inline_js'] ) ) {
181
+ $this->delay_inline_js = $options['delay_inline_js'];
182
+ }
183
+
184
  // filter to "late inject minified JS", default to true for now (it is faster)
185
  $this->inject_min_late = apply_filters( 'breeze_filter_js_inject_min_late', true );
186
 
264
  continue;
265
  }
266
 
267
+ // Get the script version.
268
+ $script_version = '';
269
+ $explode_url = explode( '?', $source[2] );
270
+ if ( isset( $explode_url[1] ) ) {
271
+ $script_version = $explode_url[1];
272
+ }
273
+
274
  // External script
275
  $url = current( explode( '?', $source[2], 2 ) );
276
  if ( $url[0] == "'" || $url[0] == '"' ) {
327
  } else {
328
  $this->move['first'][] = $tag;
329
  }
330
+ } else {
331
+ $is_delayed = $this->is_inline_delay( $tag );
332
+ if ( $is_delayed ) {
333
+ if ( true === $head ) {
334
+ $this->delay_scripts['header'][ $url ] = array(
335
+ 'path' => $path,
336
+ 'version' => $script_version,
337
+ );
338
+ } else {
339
+ $this->delay_scripts['footer'][ $url ] = array(
340
+ 'path' => $path,
341
+ 'version' => $script_version,
342
+ );
343
+ }
344
  } else {
345
  //We shouldn't touch this
346
  $tag = '';
347
  }
348
+
349
+ }
350
  }
351
  } else {
352
  // Inline script
376
  } else {
377
  $this->move['first'][] = $tag;
378
  }
379
+ } else {
380
+ $is_delayed = $this->is_inline_delay( $tag );
381
+ if ( true === $is_delayed ) {
382
+ preg_match( '#<script.*>(.*)</script>#Usmi', $tag, $code );
383
+ $code = preg_replace( '#.*<!\[CDATA\[(?:\s*\*/)?(.*)(?://|/\*)\s*?\]\]>.*#sm', '$1', $code[1] );
384
+ $code = preg_replace( '/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $code );
385
+ if ( true === $head ) {
386
+ $this->delay_scripts['header'][] = $code;
387
+ } else {
388
+ $this->delay_scripts['footer'][] = $code;
389
+ }
390
+
391
  } else {
392
  //We shouldn't touch this
393
  $tag = '';
394
  }
395
+
396
+ }
397
  }
398
  // re-hide comments to be able to do the removal based on tag from $this->content
399
  $tag = $this->hide_comments( $tag );
684
  $url_exists = false;
685
  } else {
686
  $url = breeze_CACHE_URL . breeze_current_user_type() . $cache->getname();
687
+ if ( is_numeric( $old_url ) && $this->is_inline_delay( $js_code ) ) {
688
+ $this->url_group_head['defer'] = $this->url_replace_cdn( $url );
689
+ } else {
690
  $this->url_group_head[ $old_url ] = $this->url_replace_cdn( $url );
691
  }
692
  }
693
+ }
694
 
695
  foreach ( $this->js_min_footer as $old_url => $js_min ) {
696
  $namehash = substr( $js_min, 0, strpos( $js_min, '_breezejsgroup_' ) );
706
  $url_exists = false;
707
  } else {
708
  $url = breeze_CACHE_URL . breeze_current_user_type() . $cache->getname();
709
+ if ( is_numeric( $old_url ) && $this->is_inline_delay( $js_code ) ) {
710
+ $this->url_group_footer['defer'] = $this->url_replace_cdn( $url );
711
+ } else {
712
  $this->url_group_footer[ $old_url ] = $this->url_replace_cdn( $url );
713
  }
714
+
715
+ }
716
  }
717
 
718
  if ( false === $url_exists ) {
740
  $replaceTag = array( '</head>', 'before' );
741
 
742
  foreach ( $this->jscode_inline_head as $js ) {
743
+ if ( $is_delayed = $this->is_inline_delay( $js ) ) {
744
+ $jsHead[] = '<script type="module">' . $js . '</script>';
745
+ } else {
746
  $jsHead[] = '<script type="text/javascript">' . $js . '</script>';
747
  }
748
+
749
+ }
750
  $jsReplacement = '';
751
  $jsReplacement .= implode( '', $jsHead );
752
  $this->inject_in_html( $jsReplacement, $replaceTag );
756
  $replaceTag = array( '</body>', 'before' );
757
 
758
  foreach ( $this->jscode_inline_footer as $js ) {
759
+ if ( $is_delayed = $this->is_inline_delay( $js ) ) {
760
+ $jsFooter[] = '<script type="module">' . $js . '</script>';
761
+ }else{
762
  $jsFooter[] = '<script type="text/javascript">' . $js . '</script>';
763
  }
764
+ }
765
  $jsReplacement = '';
766
  $jsReplacement .= implode( '', $jsFooter );
767
  $this->inject_in_html( $jsReplacement, $replaceTag );
785
  $this->inject_in_html( $bodyreplacement, $replaceTag );
786
  }
787
  } else {
788
+
789
+ // handle the 3rd party defer scripts in header.
790
+ if ( ! empty( $this->delay_scripts ) && ! empty( $this->delay_scripts['header'] ) ) {
791
+ $replace_tag = array( '</head>', 'before' );
792
+ $js_head_defer = array();
793
+ $defer = 'defer ';
794
+ foreach ( $this->delay_scripts['header'] as $js_url => $js_script ) {
795
+ if ( filter_var( $js_url, FILTER_VALIDATE_URL ) ) {
796
+ if ( ! empty( $js_script['version'] ) ) {
797
+ $js_url .= '?' . $js_script['version'];
798
+ }
799
+ $js_head_defer[] = "<script type='application/javascript' {$defer}src='{$js_url}'></script>\n";
800
+ } else {
801
+ $js_head_defer[] = "<script type='module'>{$js_script}</script>\n";
802
+ }
803
+ }
804
+ $js_replacement = '';
805
+ $js_replacement .= implode( '', $js_head_defer );
806
+ $this->inject_in_html( $js_replacement, $replace_tag );
807
+ }
808
+
809
+ // handle the 3rd party defer scripts in footer.
810
+ if ( ! empty( $this->delay_scripts ) && ! empty( $this->delay_scripts['footer'] ) ) {
811
+ $replace_tag = array( '</body>', 'before' );
812
+ $js_footer_defer = array();
813
+ $defer = 'defer ';
814
+ foreach ( $this->delay_scripts['footer'] as $js_url => $js_script ) {
815
+ if ( filter_var( $js_url, FILTER_VALIDATE_URL ) ) {
816
+ if ( ! empty( $js_script['version'] ) ) {
817
+ $js_url .= '?' . $js_script['version'];
818
+ }
819
+ $js_footer_defer[] = "<script type='application/javascript' {$defer}src='{$js_url}'></script>\n";
820
+ } else {
821
+ $js_footer_defer[] = "<script type='module'>{$js_script}</script>\n";
822
+ }
823
+ }
824
+
825
+ $js_replacement = '';
826
+ $js_replacement .= implode( '', $js_footer_defer );
827
+ $this->inject_in_html( $js_replacement, $replace_tag );
828
+ }
829
+
830
+
831
  $headScript = array();
832
  $footerScript = array();
833
 
836
 
837
  foreach ( $this->url_group_head as $old_url => $url ) {
838
  $defer = '';
839
+ if (
840
+ gettype( $old_url ) == 'string' &&
841
+ (
842
+ in_array( $old_url, $this->defer_js ) ||
843
+ $this->is_inline_delay( $url ) ||
844
+ 'defer' === $old_url
845
+ )
846
+ ) {
847
  $defer = 'defer ';
848
  }
849
 
866
 
867
  foreach ( $this->url_group_footer as $old_url => $url ) {
868
  $defer = '';
869
+ if ( gettype( $old_url ) == 'string' &&
870
+ (
871
+ in_array( $old_url, $this->defer_js ) ||
872
+ $this->is_inline_delay( $url ) ||
873
+ 'defer' === $old_url
874
+ )
875
+ ) {
876
  $defer = 'defer ';
877
  }
878
 
1066
 
1067
  return false;
1068
  }
1069
+
1070
+ /**
1071
+ * Check if the inline script is in the list of delay.
1072
+ *
1073
+ * @param $tag
1074
+ *
1075
+ * @return bool
1076
+ */
1077
+ private function is_inline_delay( $tag ) {
1078
+ foreach ( $this->delay_inline_js as $match ) {
1079
+ if ( strpos( $tag, $match ) !== false ) {
1080
+ //Matched something
1081
+ return true;
1082
+ }
1083
+ }
1084
+
1085
+ return false;
1086
+ }
1087
  }
inc/minification/breeze-minification-styles.php CHANGED
@@ -21,6 +21,7 @@ class Breeze_MinificationStyles extends Breeze_MinificationBase {
21
  private $cssinlinesize = '';
22
  private $cssremovables = array();
23
  private $include_inline = false;
 
24
  private $inject_min_late = '';
25
  private $group_css = false;
26
  private $custom_css_exclude = array();
@@ -81,6 +82,12 @@ class Breeze_MinificationStyles extends Breeze_MinificationBase {
81
  if ( apply_filters( 'breeze_css_include_inline', $options['groupcss'] ) == true ) {
82
  $this->group_css = true;
83
  }
 
 
 
 
 
 
84
  //custom js exclude
85
  if ( ! empty( $options['custom_css_exclude'] ) ) {
86
  $this->custom_css_exclude = array_merge( $this->custom_css_exclude, $options['custom_css_exclude'] );
@@ -543,6 +550,7 @@ class Breeze_MinificationStyles extends Breeze_MinificationBase {
543
  $whole_css_file .= $code;
544
  }
545
 
 
546
  $md5 = md5( $whole_css_file );
547
  $cache = new Breeze_MinificationCache( $md5, 'css' );
548
  if ( ! $cache->check() ) {
@@ -569,6 +577,7 @@ class Breeze_MinificationStyles extends Breeze_MinificationBase {
569
  $cache = new Breeze_MinificationCache( $hash, 'css' );
570
  if ( ! $cache->check() ) {
571
  // Cache our code
 
572
  $cache->cache( $css, 'text/css' );
573
  }
574
 
@@ -860,4 +869,33 @@ class Breeze_MinificationStyles extends Breeze_MinificationBase {
860
 
861
  return false;
862
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
  }
21
  private $cssinlinesize = '';
22
  private $cssremovables = array();
23
  private $include_inline = false;
24
+ private $font_swap = false;
25
  private $inject_min_late = '';
26
  private $group_css = false;
27
  private $custom_css_exclude = array();
82
  if ( apply_filters( 'breeze_css_include_inline', $options['groupcss'] ) == true ) {
83
  $this->group_css = true;
84
  }
85
+
86
+ // group css?
87
+ if ( apply_filters( 'breeze_css_font_swap', $options['font_swap'] ) == true ) {
88
+ $this->font_swap = true;
89
+ }
90
+
91
  //custom js exclude
92
  if ( ! empty( $options['custom_css_exclude'] ) ) {
93
  $this->custom_css_exclude = array_merge( $this->custom_css_exclude, $options['custom_css_exclude'] );
550
  $whole_css_file .= $code;
551
  }
552
 
553
+ $whole_css_file = $this->append_font_swap( $whole_css_file );
554
  $md5 = md5( $whole_css_file );
555
  $cache = new Breeze_MinificationCache( $md5, 'css' );
556
  if ( ! $cache->check() ) {
577
  $cache = new Breeze_MinificationCache( $hash, 'css' );
578
  if ( ! $cache->check() ) {
579
  // Cache our code
580
+ $css = $this->append_font_swap( $css );
581
  $cache->cache( $css, 'text/css' );
582
  }
583
 
869
 
870
  return false;
871
  }
872
+
873
+ /**
874
+ * Append font-display: wap parameter to font-face definitions.
875
+ *
876
+ * @param string $code
877
+ *
878
+ * @return mixed|string|string[]
879
+ * @since 1.2.0
880
+ * @access private
881
+ */
882
+ private function append_font_swap( $code = '' ) {
883
+ if ( false === $this->font_swap ) {
884
+ return $code;
885
+ }
886
+
887
+ if ( ! empty( $code ) ) {
888
+ preg_match_all( '/[\s+]?\@font-face[\s+]?(\{[a-zA-Z\s\:\;\0-9\,\?\=]+\})/mi', $code, $matches );
889
+ if ( isset( $matches ) && ! empty( $matches ) && isset( $matches[0] ) && ! empty( $matches[0] ) ) {
890
+ foreach ( $matches[0] as $index => $css_font_face ) {
891
+ if ( ! substr_count( $css_font_face, 'font-display' ) ) {
892
+ $font_display = str_replace( '{', '{font-display:swap;', $css_font_face );
893
+ $code = str_replace( $css_font_face, $font_display, $code );
894
+ }
895
+ }
896
+ }
897
+ }
898
+
899
+ return $code;
900
+ }
901
  }
inc/minification/breeze-minify-main.php CHANGED
@@ -36,7 +36,7 @@ class Breeze_Minify {
36
  if ( Breeze_MinificationCache::create_cache_minification_folder() ) {
37
  $conf = breeze_get_option( 'basic_settings' );
38
  $config_advanced = breeze_get_option( 'advanced_settings' );
39
- if ( ! empty( $conf['breeze-minify-html'] ) || ! empty( $conf['breeze-minify-css'] ) || ! empty( $conf['breeze-minify-js'] ) || ! empty( $config_advanced['breeze-defer-js'] ) || ! empty( $config_advanced['breeze-move-to-footer-js'] ) ) {
40
 
41
  if ( defined( 'breeze_INIT_EARLIER' ) ) {
42
  add_action( 'init', array( $this, 'breeze_start_buffering' ), - 1 );
@@ -103,7 +103,7 @@ class Breeze_Minify {
103
  if ( ! defined( 'COMPRESS_SCRIPTS' ) ) {
104
  define( 'COMPRESS_SCRIPTS', false );
105
  }
106
- } elseif ( ! empty( $config_advanced['breeze-defer-js'] ) || ! empty( $config_advanced['breeze-move-to-footer-js'] ) ) {
107
  // If we have defer scripts to handle, load only the script for this action.
108
  include_once( BREEZE_PLUGIN_DIR . 'inc/minification/breeze-js-deferred-loading.php' );
109
  }
@@ -169,7 +169,7 @@ class Breeze_Minify {
169
  $js_include_inline = $css_include_inline = false;
170
  if ( ! empty( $conf['breeze-minify-js'] ) ) {
171
  $classes[] = 'Breeze_MinificationScripts';
172
- } elseif ( ! empty( $minify['breeze-defer-js'] ) || ! empty( $minify['breeze-move-to-footer-js'] ) ) {
173
  $classes[] = 'Breeze_Js_Deferred_Loading';
174
  }
175
 
@@ -194,6 +194,11 @@ class Breeze_Minify {
194
  $groupjs = true;
195
  }
196
 
 
 
 
 
 
197
  // Set some options
198
  $classoptions = array(
199
  'Breeze_MinificationScripts' => array(
@@ -207,6 +212,7 @@ class Breeze_Minify {
207
  'custom_js_exclude' => $minify['breeze-exclude-js'],
208
  'move_to_footer_js' => $minify['breeze-move-to-footer-js'],
209
  'defer_js' => $minify['breeze-defer-js'],
 
210
  ),
211
  'Breeze_MinificationStyles' => array(
212
  'justhead' => false,
@@ -217,6 +223,7 @@ class Breeze_Minify {
217
  'css_exclude' => 'admin-bar.min.css, dashicons.min.css',
218
  'cdn_url' => '',
219
  'include_inline' => $css_include_inline,
 
220
  'nogooglefont' => false,
221
  'groupcss' => $groupcss,
222
  'custom_css_exclude' => $minify['breeze-exclude-css'],
@@ -228,6 +235,7 @@ class Breeze_Minify {
228
  'Breeze_Js_Deferred_Loading' => array(
229
  'move_to_footer_js' => $minify['breeze-move-to-footer-js'],
230
  'defer_js' => $minify['breeze-defer-js'],
 
231
  'cdn_url' => $cdn_url,
232
  ),
233
  );
@@ -363,6 +371,7 @@ class Breeze_Minify {
363
  * @access public
364
  */
365
  public function read_the_config_file() {
 
366
  $config_dir = trailingslashit( WP_CONTENT_DIR ) . 'breeze-config';
367
  $filename = 'breeze-config';
368
  if ( is_multisite() && ! is_network_admin() ) {
36
  if ( Breeze_MinificationCache::create_cache_minification_folder() ) {
37
  $conf = breeze_get_option( 'basic_settings' );
38
  $config_advanced = breeze_get_option( 'advanced_settings' );
39
+ if ( ! empty( $conf['breeze-minify-html'] ) || ! empty( $conf['breeze-minify-css'] ) || ! empty( $conf['breeze-minify-js'] ) || ! empty( $config_advanced['breeze-defer-js'] ) || ! empty( $config_advanced['breeze-move-to-footer-js'] ) || ! empty( $config_advanced['breeze-delay-js-scripts'] ) ) {
40
 
41
  if ( defined( 'breeze_INIT_EARLIER' ) ) {
42
  add_action( 'init', array( $this, 'breeze_start_buffering' ), - 1 );
103
  if ( ! defined( 'COMPRESS_SCRIPTS' ) ) {
104
  define( 'COMPRESS_SCRIPTS', false );
105
  }
106
+ } elseif ( ! empty( $config_advanced['breeze-defer-js'] ) || ! empty( $config_advanced['breeze-move-to-footer-js'] ) || ! empty( $config_advanced['breeze-delay-js-scripts'] )) {
107
  // If we have defer scripts to handle, load only the script for this action.
108
  include_once( BREEZE_PLUGIN_DIR . 'inc/minification/breeze-js-deferred-loading.php' );
109
  }
169
  $js_include_inline = $css_include_inline = false;
170
  if ( ! empty( $conf['breeze-minify-js'] ) ) {
171
  $classes[] = 'Breeze_MinificationScripts';
172
+ } elseif ( ! empty( $minify['breeze-defer-js'] ) || ! empty( $minify['breeze-move-to-footer-js'] ) || ! empty( $minify['breeze-delay-js-scripts'] ) ) {
173
  $classes[] = 'Breeze_Js_Deferred_Loading';
174
  }
175
 
194
  $groupjs = true;
195
  }
196
 
197
+ $font_swap = false;
198
+ if ( isset( $conf['breeze-font-display-swap'] ) ) {
199
+ $font_swap = filter_var( $conf['breeze-font-display-swap'], FILTER_VALIDATE_BOOLEAN );
200
+ }
201
+
202
  // Set some options
203
  $classoptions = array(
204
  'Breeze_MinificationScripts' => array(
212
  'custom_js_exclude' => $minify['breeze-exclude-js'],
213
  'move_to_footer_js' => $minify['breeze-move-to-footer-js'],
214
  'defer_js' => $minify['breeze-defer-js'],
215
+ 'delay_inline_js' => $minify['breeze-delay-js-scripts'],
216
  ),
217
  'Breeze_MinificationStyles' => array(
218
  'justhead' => false,
223
  'css_exclude' => 'admin-bar.min.css, dashicons.min.css',
224
  'cdn_url' => '',
225
  'include_inline' => $css_include_inline,
226
+ 'font_swap' => $font_swap,
227
  'nogooglefont' => false,
228
  'groupcss' => $groupcss,
229
  'custom_css_exclude' => $minify['breeze-exclude-css'],
235
  'Breeze_Js_Deferred_Loading' => array(
236
  'move_to_footer_js' => $minify['breeze-move-to-footer-js'],
237
  'defer_js' => $minify['breeze-defer-js'],
238
+ 'delay_inline_js' => $minify['breeze-delay-js-scripts'],
239
  'cdn_url' => $cdn_url,
240
  ),
241
  );
371
  * @access public
372
  */
373
  public function read_the_config_file() {
374
+ global $wpdb;
375
  $config_dir = trailingslashit( WP_CONTENT_DIR ) . 'breeze-config';
376
  $filename = 'breeze-config';
377
  if ( is_multisite() && ! is_network_admin() ) {
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: Cloudways
3
  Tags: cache,caching, performance, wp-cache, cdn, combine, compress, speed plugin, database cache,gzip, http compression, js cache, minify, optimize, page cache, performance, speed, expire headers
4
  Requires at least: 4.5
5
  Tested up to: 5.7
6
- Stable tag: 1.1.11
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -145,6 +145,15 @@ Using Gzip, Breeze compresses the request files, further reducing the size of th
145
 
146
  == Changelog ==
147
 
 
 
 
 
 
 
 
 
 
148
  = 1.1.11 =
149
 
150
  * Fix: Improved handling of forms using nonce in Permalinks and Options pages.
3
  Tags: cache,caching, performance, wp-cache, cdn, combine, compress, speed plugin, database cache,gzip, http compression, js cache, minify, optimize, page cache, performance, speed, expire headers
4
  Requires at least: 4.5
5
  Tested up to: 5.7
6
+ Stable tag: 1.2.0
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
145
 
146
  == Changelog ==
147
 
148
+ = 1.2.0 =
149
+
150
+ * Add: “noreferrer noopener” attributes tag on external links when process HTML for caching.
151
+ * Add: Preload fonts allow to text remain visible during webfont load.
152
+ * Add: Preload key request of fonts OR CSS file which load fonts from local resource.
153
+ * Add: Preload links allow to enable preload next page of application.
154
+ * Add: lazy load display images on a page only when they are visible to the user.
155
+ * Add: Minimize the impact of third-party code.
156
+
157
  = 1.1.11 =
158
 
159
  * Fix: Improved handling of forms using nonce in Permalinks and Options pages.
vendor/composer/ClassLoader.php CHANGED
@@ -37,11 +37,13 @@ namespace Composer\Autoload;
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
- * @see http://www.php-fig.org/psr/psr-0/
41
- * @see http://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
 
 
45
  // PSR-4
46
  private $prefixLengthsPsr4 = array();
47
  private $prefixDirsPsr4 = array();
@@ -57,10 +59,17 @@ class ClassLoader
57
  private $missingClasses = array();
58
  private $apcuPrefix;
59
 
 
 
 
 
 
 
 
60
  public function getPrefixes()
61
  {
62
  if (!empty($this->prefixesPsr0)) {
63
- return call_user_func_array('array_merge', $this->prefixesPsr0);
64
  }
65
 
66
  return array();
@@ -300,6 +309,17 @@ class ClassLoader
300
  public function register($prepend = false)
301
  {
302
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 
 
 
 
 
 
 
 
 
 
 
303
  }
304
 
305
  /**
@@ -308,6 +328,10 @@ class ClassLoader
308
  public function unregister()
309
  {
310
  spl_autoload_unregister(array($this, 'loadClass'));
 
 
 
 
311
  }
312
 
313
  /**
@@ -367,6 +391,16 @@ class ClassLoader
367
  return $file;
368
  }
369
 
 
 
 
 
 
 
 
 
 
 
370
  private function findFileWithExtension($class, $ext)
371
  {
372
  // PSR-4 lookup
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see https://www.php-fig.org/psr/psr-0/
41
+ * @see https://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
45
+ private $vendorDir;
46
+
47
  // PSR-4
48
  private $prefixLengthsPsr4 = array();
49
  private $prefixDirsPsr4 = array();
59
  private $missingClasses = array();
60
  private $apcuPrefix;
61
 
62
+ private static $registeredLoaders = array();
63
+
64
+ public function __construct($vendorDir = null)
65
+ {
66
+ $this->vendorDir = $vendorDir;
67
+ }
68
+
69
  public function getPrefixes()
70
  {
71
  if (!empty($this->prefixesPsr0)) {
72
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
73
  }
74
 
75
  return array();
309
  public function register($prepend = false)
310
  {
311
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
312
+
313
+ if (null === $this->vendorDir) {
314
+ return;
315
+ }
316
+
317
+ if ($prepend) {
318
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
319
+ } else {
320
+ unset(self::$registeredLoaders[$this->vendorDir]);
321
+ self::$registeredLoaders[$this->vendorDir] = $this;
322
+ }
323
  }
324
 
325
  /**
328
  public function unregister()
329
  {
330
  spl_autoload_unregister(array($this, 'loadClass'));
331
+
332
+ if (null !== $this->vendorDir) {
333
+ unset(self::$registeredLoaders[$this->vendorDir]);
334
+ }
335
  }
336
 
337
  /**
391
  return $file;
392
  }
393
 
394
+ /**
395
+ * Returns the currently registered loaders indexed by their corresponding vendor directories.
396
+ *
397
+ * @return self[]
398
+ */
399
+ public static function getRegisteredLoaders()
400
+ {
401
+ return self::$registeredLoaders;
402
+ }
403
+
404
  private function findFileWithExtension($class, $ext)
405
  {
406
  // PSR-4 lookup
vendor/composer/InstalledVersions.php ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+ namespace Composer;
14
+
15
+ use Composer\Autoload\ClassLoader;
16
+ use Composer\Semver\VersionParser;
17
+
18
+
19
+
20
+
21
+
22
+
23
+ class InstalledVersions
24
+ {
25
+ private static $installed = array (
26
+ 'root' =>
27
+ array (
28
+ 'pretty_version' => 'dev-master',
29
+ 'version' => 'dev-master',
30
+ 'aliases' =>
31
+ array (
32
+ ),
33
+ 'reference' => 'f5b740e4072f92ba4683f979e13d2e679980c347',
34
+ 'name' => '__root__',
35
+ ),
36
+ 'versions' =>
37
+ array (
38
+ '__root__' =>
39
+ array (
40
+ 'pretty_version' => 'dev-master',
41
+ 'version' => 'dev-master',
42
+ 'aliases' =>
43
+ array (
44
+ ),
45
+ 'reference' => 'f5b740e4072f92ba4683f979e13d2e679980c347',
46
+ ),
47
+ 'matthiasmullie/minify' =>
48
+ array (
49
+ 'pretty_version' => '1.3.66',
50
+ 'version' => '1.3.66.0',
51
+ 'aliases' =>
52
+ array (
53
+ ),
54
+ 'reference' => '45fd3b0f1dfa2c965857c6d4a470bea52adc31a6',
55
+ ),
56
+ 'matthiasmullie/path-converter' =>
57
+ array (
58
+ 'pretty_version' => '1.1.3',
59
+ 'version' => '1.1.3.0',
60
+ 'aliases' =>
61
+ array (
62
+ ),
63
+ 'reference' => 'e7d13b2c7e2f2268e1424aaed02085518afa02d9',
64
+ ),
65
+ ),
66
+ );
67
+ private static $canGetVendors;
68
+ private static $installedByVendor = array();
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+ public static function getInstalledPackages()
77
+ {
78
+ $packages = array();
79
+ foreach (self::getInstalled() as $installed) {
80
+ $packages[] = array_keys($installed['versions']);
81
+ }
82
+
83
+
84
+ if (1 === \count($packages)) {
85
+ return $packages[0];
86
+ }
87
+
88
+ return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
89
+ }
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+ public static function isInstalled($packageName)
100
+ {
101
+ foreach (self::getInstalled() as $installed) {
102
+ if (isset($installed['versions'][$packageName])) {
103
+ return true;
104
+ }
105
+ }
106
+
107
+ return false;
108
+ }
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+ public static function satisfies(VersionParser $parser, $packageName, $constraint)
124
+ {
125
+ $constraint = $parser->parseConstraints($constraint);
126
+ $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
127
+
128
+ return $provided->matches($constraint);
129
+ }
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+ public static function getVersionRanges($packageName)
141
+ {
142
+ foreach (self::getInstalled() as $installed) {
143
+ if (!isset($installed['versions'][$packageName])) {
144
+ continue;
145
+ }
146
+
147
+ $ranges = array();
148
+ if (isset($installed['versions'][$packageName]['pretty_version'])) {
149
+ $ranges[] = $installed['versions'][$packageName]['pretty_version'];
150
+ }
151
+ if (array_key_exists('aliases', $installed['versions'][$packageName])) {
152
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
153
+ }
154
+ if (array_key_exists('replaced', $installed['versions'][$packageName])) {
155
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
156
+ }
157
+ if (array_key_exists('provided', $installed['versions'][$packageName])) {
158
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
159
+ }
160
+
161
+ return implode(' || ', $ranges);
162
+ }
163
+
164
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
165
+ }
166
+
167
+
168
+
169
+
170
+
171
+ public static function getVersion($packageName)
172
+ {
173
+ foreach (self::getInstalled() as $installed) {
174
+ if (!isset($installed['versions'][$packageName])) {
175
+ continue;
176
+ }
177
+
178
+ if (!isset($installed['versions'][$packageName]['version'])) {
179
+ return null;
180
+ }
181
+
182
+ return $installed['versions'][$packageName]['version'];
183
+ }
184
+
185
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
186
+ }
187
+
188
+
189
+
190
+
191
+
192
+ public static function getPrettyVersion($packageName)
193
+ {
194
+ foreach (self::getInstalled() as $installed) {
195
+ if (!isset($installed['versions'][$packageName])) {
196
+ continue;
197
+ }
198
+
199
+ if (!isset($installed['versions'][$packageName]['pretty_version'])) {
200
+ return null;
201
+ }
202
+
203
+ return $installed['versions'][$packageName]['pretty_version'];
204
+ }
205
+
206
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
207
+ }
208
+
209
+
210
+
211
+
212
+
213
+ public static function getReference($packageName)
214
+ {
215
+ foreach (self::getInstalled() as $installed) {
216
+ if (!isset($installed['versions'][$packageName])) {
217
+ continue;
218
+ }
219
+
220
+ if (!isset($installed['versions'][$packageName]['reference'])) {
221
+ return null;
222
+ }
223
+
224
+ return $installed['versions'][$packageName]['reference'];
225
+ }
226
+
227
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
228
+ }
229
+
230
+
231
+
232
+
233
+
234
+ public static function getRootPackage()
235
+ {
236
+ $installed = self::getInstalled();
237
+
238
+ return $installed[0]['root'];
239
+ }
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+ public static function getRawData()
248
+ {
249
+ return self::$installed;
250
+ }
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+
270
+ public static function reload($data)
271
+ {
272
+ self::$installed = $data;
273
+ self::$installedByVendor = array();
274
+ }
275
+
276
+
277
+
278
+
279
+ private static function getInstalled()
280
+ {
281
+ if (null === self::$canGetVendors) {
282
+ self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
283
+ }
284
+
285
+ $installed = array();
286
+
287
+ if (self::$canGetVendors) {
288
+ foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
289
+ if (isset(self::$installedByVendor[$vendorDir])) {
290
+ $installed[] = self::$installedByVendor[$vendorDir];
291
+ } elseif (is_file($vendorDir.'/composer/installed.php')) {
292
+ $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
293
+ }
294
+ }
295
+ }
296
+
297
+ $installed[] = self::$installed;
298
+
299
+ return $installed;
300
+ }
301
+ }
vendor/composer/autoload_classmap.php CHANGED
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
  );
vendor/composer/autoload_real.php CHANGED
@@ -13,19 +13,24 @@ class ComposerAutoloaderInit34a6ba7dda38aa84053804314c2a6c35
13
  }
14
  }
15
 
 
 
 
16
  public static function getLoader()
17
  {
18
  if (null !== self::$loader) {
19
  return self::$loader;
20
  }
21
 
 
 
22
  spl_autoload_register(array('ComposerAutoloaderInit34a6ba7dda38aa84053804314c2a6c35', 'loadClassLoader'), true, true);
23
- self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
  spl_autoload_unregister(array('ComposerAutoloaderInit34a6ba7dda38aa84053804314c2a6c35', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
- require_once __DIR__ . '/autoload_static.php';
29
 
30
  call_user_func(\Composer\Autoload\ComposerStaticInit34a6ba7dda38aa84053804314c2a6c35::getInitializer($loader));
31
  } else {
13
  }
14
  }
15
 
16
+ /**
17
+ * @return \Composer\Autoload\ClassLoader
18
+ */
19
  public static function getLoader()
20
  {
21
  if (null !== self::$loader) {
22
  return self::$loader;
23
  }
24
 
25
+ require __DIR__ . '/platform_check.php';
26
+
27
  spl_autoload_register(array('ComposerAutoloaderInit34a6ba7dda38aa84053804314c2a6c35', 'loadClassLoader'), true, true);
28
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
29
  spl_autoload_unregister(array('ComposerAutoloaderInit34a6ba7dda38aa84053804314c2a6c35', 'loadClassLoader'));
30
 
31
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
32
  if ($useStaticLoader) {
33
+ require __DIR__ . '/autoload_static.php';
34
 
35
  call_user_func(\Composer\Autoload\ComposerStaticInit34a6ba7dda38aa84053804314c2a6c35::getInitializer($loader));
36
  } else {
vendor/composer/autoload_static.php CHANGED
@@ -25,11 +25,16 @@ class ComposerStaticInit34a6ba7dda38aa84053804314c2a6c35
25
  ),
26
  );
27
 
 
 
 
 
28
  public static function getInitializer(ClassLoader $loader)
29
  {
30
  return \Closure::bind(function () use ($loader) {
31
  $loader->prefixLengthsPsr4 = ComposerStaticInit34a6ba7dda38aa84053804314c2a6c35::$prefixLengthsPsr4;
32
  $loader->prefixDirsPsr4 = ComposerStaticInit34a6ba7dda38aa84053804314c2a6c35::$prefixDirsPsr4;
 
33
 
34
  }, null, ClassLoader::class);
35
  }
25
  ),
26
  );
27
 
28
+ public static $classMap = array (
29
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
30
+ );
31
+
32
  public static function getInitializer(ClassLoader $loader)
33
  {
34
  return \Closure::bind(function () use ($loader) {
35
  $loader->prefixLengthsPsr4 = ComposerStaticInit34a6ba7dda38aa84053804314c2a6c35::$prefixLengthsPsr4;
36
  $loader->prefixDirsPsr4 = ComposerStaticInit34a6ba7dda38aa84053804314c2a6c35::$prefixDirsPsr4;
37
+ $loader->classMap = ComposerStaticInit34a6ba7dda38aa84053804314c2a6c35::$classMap;
38
 
39
  }, null, ClassLoader::class);
40
  }
vendor/composer/installed.json CHANGED
@@ -1,115 +1,139 @@
1
- [
2
- {
3
- "name": "matthiasmullie/minify",
4
- "version": "1.3.63",
5
- "version_normalized": "1.3.63.0",
6
- "source": {
7
- "type": "git",
8
- "url": "https://github.com/matthiasmullie/minify.git",
9
- "reference": "9ba1b459828adc13430f4dd6c49dae4950dc4117"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  },
11
- "dist": {
12
- "type": "zip",
13
- "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/9ba1b459828adc13430f4dd6c49dae4950dc4117",
14
- "reference": "9ba1b459828adc13430f4dd6c49dae4950dc4117",
15
- "shasum": ""
16
- },
17
- "require": {
18
- "ext-pcre": "*",
19
- "matthiasmullie/path-converter": "~1.1",
20
- "php": ">=5.3.0"
21
- },
22
- "require-dev": {
23
- "friendsofphp/php-cs-fixer": "~2.0",
24
- "matthiasmullie/scrapbook": "~1.0",
25
- "phpunit/phpunit": "~4.8"
26
- },
27
- "suggest": {
28
- "psr/cache-implementation": "Cache implementation to use with Minify::cache"
29
- },
30
- "time": "2020-01-21T20:21:08+00:00",
31
- "bin": [
32
- "bin/minifycss",
33
- "bin/minifyjs"
34
- ],
35
- "type": "library",
36
- "installation-source": "dist",
37
- "autoload": {
38
- "psr-4": {
39
- "MatthiasMullie\\Minify\\": "src/"
40
- }
41
- },
42
- "notification-url": "https://packagist.org/downloads/",
43
- "license": [
44
- "MIT"
45
- ],
46
- "authors": [
47
- {
48
- "name": "Matthias Mullie",
49
- "email": "minify@mullie.eu",
50
- "homepage": "http://www.mullie.eu",
51
- "role": "Developer"
52
- }
53
- ],
54
- "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.",
55
- "homepage": "http://www.minifier.org",
56
- "keywords": [
57
- "JS",
58
- "css",
59
- "javascript",
60
- "minifier",
61
- "minify"
62
- ]
63
- },
64
- {
65
- "name": "matthiasmullie/path-converter",
66
- "version": "1.1.3",
67
- "version_normalized": "1.1.3.0",
68
- "source": {
69
- "type": "git",
70
- "url": "https://github.com/matthiasmullie/path-converter.git",
71
- "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9"
72
- },
73
- "dist": {
74
- "type": "zip",
75
- "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9",
76
- "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9",
77
- "shasum": ""
78
- },
79
- "require": {
80
- "ext-pcre": "*",
81
- "php": ">=5.3.0"
82
- },
83
- "require-dev": {
84
- "phpunit/phpunit": "~4.8"
85
- },
86
- "time": "2019-02-05T23:41:09+00:00",
87
- "type": "library",
88
- "installation-source": "dist",
89
- "autoload": {
90
- "psr-4": {
91
- "MatthiasMullie\\PathConverter\\": "src/"
92
- }
93
- },
94
- "notification-url": "https://packagist.org/downloads/",
95
- "license": [
96
- "MIT"
97
- ],
98
- "authors": [
99
- {
100
- "name": "Matthias Mullie",
101
- "email": "pathconverter@mullie.eu",
102
- "homepage": "http://www.mullie.eu",
103
- "role": "Developer"
104
- }
105
- ],
106
- "description": "Relative path converter",
107
- "homepage": "http://github.com/matthiasmullie/path-converter",
108
- "keywords": [
109
- "converter",
110
- "path",
111
- "paths",
112
- "relative"
113
- ]
114
- }
115
- ]
1
+ {
2
+ "packages": [
3
+ {
4
+ "name": "matthiasmullie/minify",
5
+ "version": "1.3.66",
6
+ "version_normalized": "1.3.66.0",
7
+ "source": {
8
+ "type": "git",
9
+ "url": "https://github.com/matthiasmullie/minify.git",
10
+ "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6"
11
+ },
12
+ "dist": {
13
+ "type": "zip",
14
+ "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/45fd3b0f1dfa2c965857c6d4a470bea52adc31a6",
15
+ "reference": "45fd3b0f1dfa2c965857c6d4a470bea52adc31a6",
16
+ "shasum": ""
17
+ },
18
+ "require": {
19
+ "ext-pcre": "*",
20
+ "matthiasmullie/path-converter": "~1.1",
21
+ "php": ">=5.3.0"
22
+ },
23
+ "require-dev": {
24
+ "friendsofphp/php-cs-fixer": "~2.0",
25
+ "matthiasmullie/scrapbook": "dev-master",
26
+ "phpunit/phpunit": ">=4.8"
27
+ },
28
+ "suggest": {
29
+ "psr/cache-implementation": "Cache implementation to use with Minify::cache"
30
+ },
31
+ "time": "2021-01-06T15:18:10+00:00",
32
+ "bin": [
33
+ "bin/minifycss",
34
+ "bin/minifyjs"
35
+ ],
36
+ "type": "library",
37
+ "installation-source": "dist",
38
+ "autoload": {
39
+ "psr-4": {
40
+ "MatthiasMullie\\Minify\\": "src/"
41
+ }
42
+ },
43
+ "notification-url": "https://packagist.org/downloads/",
44
+ "license": [
45
+ "MIT"
46
+ ],
47
+ "authors": [
48
+ {
49
+ "name": "Matthias Mullie",
50
+ "email": "minify@mullie.eu",
51
+ "homepage": "http://www.mullie.eu",
52
+ "role": "Developer"
53
+ }
54
+ ],
55
+ "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.",
56
+ "homepage": "http://www.minifier.org",
57
+ "keywords": [
58
+ "JS",
59
+ "css",
60
+ "javascript",
61
+ "minifier",
62
+ "minify"
63
+ ],
64
+ "support": {
65
+ "issues": "https://github.com/matthiasmullie/minify/issues",
66
+ "source": "https://github.com/matthiasmullie/minify/tree/1.3.66"
67
+ },
68
+ "funding": [
69
+ {
70
+ "url": "https://github.com/[user1",
71
+ "type": "github"
72
+ },
73
+ {
74
+ "url": "https://github.com/matthiasmullie] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g.",
75
+ "type": "github"
76
+ },
77
+ {
78
+ "url": "https://github.com/user2",
79
+ "type": "github"
80
+ }
81
+ ],
82
+ "install-path": "../matthiasmullie/minify"
83
  },
84
+ {
85
+ "name": "matthiasmullie/path-converter",
86
+ "version": "1.1.3",
87
+ "version_normalized": "1.1.3.0",
88
+ "source": {
89
+ "type": "git",
90
+ "url": "https://github.com/matthiasmullie/path-converter.git",
91
+ "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9"
92
+ },
93
+ "dist": {
94
+ "type": "zip",
95
+ "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9",
96
+ "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9",
97
+ "shasum": ""
98
+ },
99
+ "require": {
100
+ "ext-pcre": "*",
101
+ "php": ">=5.3.0"
102
+ },
103
+ "require-dev": {
104
+ "phpunit/phpunit": "~4.8"
105
+ },
106
+ "time": "2019-02-05T23:41:09+00:00",
107
+ "type": "library",
108
+ "installation-source": "dist",
109
+ "autoload": {
110
+ "psr-4": {
111
+ "MatthiasMullie\\PathConverter\\": "src/"
112
+ }
113
+ },
114
+ "notification-url": "https://packagist.org/downloads/",
115
+ "license": [
116
+ "MIT"
117
+ ],
118
+ "authors": [
119
+ {
120
+ "name": "Matthias Mullie",
121
+ "email": "pathconverter@mullie.eu",
122
+ "homepage": "http://www.mullie.eu",
123
+ "role": "Developer"
124
+ }
125
+ ],
126
+ "description": "Relative path converter",
127
+ "homepage": "http://github.com/matthiasmullie/path-converter",
128
+ "keywords": [
129
+ "converter",
130
+ "path",
131
+ "paths",
132
+ "relative"
133
+ ],
134
+ "install-path": "../matthiasmullie/path-converter"
135
+ }
136
+ ],
137
+ "dev": true,
138
+ "dev-package-names": []
139
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/installed.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php return array (
2
+ 'root' =>
3
+ array (
4
+ 'pretty_version' => 'dev-master',
5
+ 'version' => 'dev-master',
6
+ 'aliases' =>
7
+ array (
8
+ ),
9
+ 'reference' => 'f5b740e4072f92ba4683f979e13d2e679980c347',
10
+ 'name' => '__root__',
11
+ ),
12
+ 'versions' =>
13
+ array (
14
+ '__root__' =>
15
+ array (
16
+ 'pretty_version' => 'dev-master',
17
+ 'version' => 'dev-master',
18
+ 'aliases' =>
19
+ array (
20
+ ),
21
+ 'reference' => 'f5b740e4072f92ba4683f979e13d2e679980c347',
22
+ ),
23
+ 'matthiasmullie/minify' =>
24
+ array (
25
+ 'pretty_version' => '1.3.66',
26
+ 'version' => '1.3.66.0',
27
+ 'aliases' =>
28
+ array (
29
+ ),
30
+ 'reference' => '45fd3b0f1dfa2c965857c6d4a470bea52adc31a6',
31
+ ),
32
+ 'matthiasmullie/path-converter' =>
33
+ array (
34
+ 'pretty_version' => '1.1.3',
35
+ 'version' => '1.1.3.0',
36
+ 'aliases' =>
37
+ array (
38
+ ),
39
+ 'reference' => 'e7d13b2c7e2f2268e1424aaed02085518afa02d9',
40
+ ),
41
+ ),
42
+ );
vendor/composer/platform_check.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // platform_check.php @generated by Composer
4
+
5
+ $issues = array();
6
+
7
+ if (!(PHP_VERSION_ID >= 50300)) {
8
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 5.3.0". You are running ' . PHP_VERSION . '.';
9
+ }
10
+
11
+ if ($issues) {
12
+ if (!headers_sent()) {
13
+ header('HTTP/1.1 500 Internal Server Error');
14
+ }
15
+ if (!ini_get('display_errors')) {
16
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
17
+ fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
18
+ } elseif (!headers_sent()) {
19
+ echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
20
+ }
21
+ }
22
+ trigger_error(
23
+ 'Composer detected issues in your platform: ' . implode(' ', $issues),
24
+ E_USER_ERROR
25
+ );
26
+ }
vendor/matthiasmullie/minify/.github/FUNDING.yml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # These are supported funding model platforms
2
+
3
+ github: [matthiasmullie] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ otechie: # Replace with a single Otechie username
12
+ custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
vendor/matthiasmullie/minify/Dockerfile CHANGED
@@ -5,7 +5,7 @@ COPY . /var/www
5
  WORKDIR /var/www
6
 
7
  RUN apt-get update
8
- RUN apt-get install -y zip unzip zlib1g-dev
9
  RUN docker-php-ext-install zip
10
  RUN docker-php-ext-install pcntl
11
  RUN curl -sS https://getcomposer.org/installer | php
5
  WORKDIR /var/www
6
 
7
  RUN apt-get update
8
+ RUN apt-get install -y zip unzip libzip-dev git
9
  RUN docker-php-ext-install zip
10
  RUN docker-php-ext-install pcntl
11
  RUN curl -sS https://getcomposer.org/installer | php
vendor/matthiasmullie/minify/composer.json CHANGED
@@ -19,8 +19,8 @@
19
  "matthiasmullie/path-converter": "~1.1"
20
  },
21
  "require-dev": {
22
- "matthiasmullie/scrapbook": "~1.0",
23
- "phpunit/phpunit": "~4.8",
24
  "friendsofphp/php-cs-fixer": "~2.0"
25
  },
26
  "suggest": {
19
  "matthiasmullie/path-converter": "~1.1"
20
  },
21
  "require-dev": {
22
+ "matthiasmullie/scrapbook": "dev-master",
23
+ "phpunit/phpunit": ">=4.8",
24
  "friendsofphp/php-cs-fixer": "~2.0"
25
  },
26
  "suggest": {
vendor/matthiasmullie/minify/docker-compose.yml CHANGED
@@ -9,6 +9,21 @@ services:
9
  - ./data:/var/www/data
10
  - ./tests:/var/www/tests
11
  - ./phpunit.xml.dist:/var/www/phpunit.xml.dist
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  '7.2':
13
  extends: php
14
  build:
9
  - ./data:/var/www/data
10
  - ./tests:/var/www/tests
11
  - ./phpunit.xml.dist:/var/www/phpunit.xml.dist
12
+ '8.0':
13
+ extends: php
14
+ build:
15
+ args:
16
+ version: 8.0-cli
17
+ '7.4':
18
+ extends: php
19
+ build:
20
+ args:
21
+ version: 7.4-cli
22
+ '7.3':
23
+ extends: php
24
+ build:
25
+ args:
26
+ version: 7.3-cli
27
  '7.2':
28
  extends: php
29
  build:
vendor/matthiasmullie/minify/src/CSS.php CHANGED
@@ -216,7 +216,7 @@ class CSS extends Minify
216
 
217
  // grab referenced file & minify it (which may include importing
218
  // yet other @import statements recursively)
219
- $minifier = new static($importPath);
220
  $minifier->setMaxImportSize($this->maxImportSize);
221
  $minifier->setImportExtensions($this->importExtensions);
222
  $importContent = $minifier->execute($source, $parents);
@@ -307,7 +307,8 @@ class CSS extends Minify
307
  */
308
  $this->extractStrings();
309
  $this->stripComments();
310
- $this->extractCalcs();
 
311
  $css = $this->replace($css);
312
 
313
  $css = $this->stripWhitespace($css);
@@ -678,19 +679,29 @@ class CSS extends Minify
678
  }
679
 
680
  /**
681
- * Replace all `calc()` occurrences.
 
682
  */
683
- protected function extractCalcs()
684
  {
 
 
 
685
  // PHP only supports $this inside anonymous functions since 5.4
686
  $minifier = $this;
687
- $callback = function ($match) use ($minifier) {
688
- $length = strlen($match[1]);
 
689
  $expr = '';
690
  $opened = 0;
691
 
 
 
 
 
 
692
  for ($i = 0; $i < $length; $i++) {
693
- $char = $match[1][$i];
694
  $expr .= $char;
695
  if ($char === '(') {
696
  $opened++;
@@ -698,18 +709,41 @@ class CSS extends Minify
698
  break;
699
  }
700
  }
701
- $rest = str_replace($expr, '', $match[1]);
702
- $expr = trim(substr($expr, 1, -1));
703
 
 
704
  $count = count($minifier->extracted);
705
- $placeholder = 'calc('.$count.')';
706
- $minifier->extracted[$placeholder] = 'calc('.$expr.')';
 
 
 
 
 
 
707
 
708
  return $placeholder.$rest;
709
  };
710
 
711
- $this->registerPattern('/calc(\(.+?)(?=$|;|}|calc\()/', $callback);
712
- $this->registerPattern('/calc(\(.+?)(?=$|;|}|calc\()/m', $callback);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
  }
714
 
715
  /**
216
 
217
  // grab referenced file & minify it (which may include importing
218
  // yet other @import statements recursively)
219
+ $minifier = new self($importPath);
220
  $minifier->setMaxImportSize($this->maxImportSize);
221
  $minifier->setImportExtensions($this->importExtensions);
222
  $importContent = $minifier->execute($source, $parents);
307
  */
308
  $this->extractStrings();
309
  $this->stripComments();
310
+ $this->extractMath();
311
+ $this->extractCustomProperties();
312
  $css = $this->replace($css);
313
 
314
  $css = $this->stripWhitespace($css);
679
  }
680
 
681
  /**
682
+ * Replace all occurrences of functions that may contain math, where
683
+ * whitespace around operators needs to be preserved (e.g. calc, clamp)
684
  */
685
+ protected function extractMath()
686
  {
687
+ $functions = array('calc', 'clamp', 'min', 'max');
688
+ $pattern = '/\b('. implode('|', $functions) .')(\(.+?)(?=$|;|})/m';
689
+
690
  // PHP only supports $this inside anonymous functions since 5.4
691
  $minifier = $this;
692
+ $callback = function ($match) use ($minifier, $pattern, &$callback) {
693
+ $function = $match[1];
694
+ $length = strlen($match[2]);
695
  $expr = '';
696
  $opened = 0;
697
 
698
+ // the regular expression for extracting math has 1 significant problem:
699
+ // it can't determine the correct closing parenthesis...
700
+ // instead, it'll match a larger portion of code to where it's certain that
701
+ // the calc() musts have ended, and we'll figure out which is the correct
702
+ // closing parenthesis here, by counting how many have opened
703
  for ($i = 0; $i < $length; $i++) {
704
+ $char = $match[2][$i];
705
  $expr .= $char;
706
  if ($char === '(') {
707
  $opened++;
709
  break;
710
  }
711
  }
 
 
712
 
713
+ // now that we've figured out where the calc() starts and ends, extract it
714
  $count = count($minifier->extracted);
715
+ $placeholder = 'math('.$count.')';
716
+ $minifier->extracted[$placeholder] = $function.'('.trim(substr($expr, 1, -1)).')';
717
+
718
+ // and since we've captured more code than required, we may have some leftover
719
+ // calc() in here too - go recursive on the remaining but of code to go figure
720
+ // that out and extract what is needed
721
+ $rest = str_replace($function.$expr, '', $match[0]);
722
+ $rest = preg_replace_callback($pattern, $callback, $rest);
723
 
724
  return $placeholder.$rest;
725
  };
726
 
727
+ $this->registerPattern($pattern, $callback);
728
+ }
729
+
730
+ /**
731
+ * Replace custom properties, whose values may be used in scenarios where
732
+ * we wouldn't want them to be minified (e.g. inside calc)
733
+ */
734
+ protected function extractCustomProperties()
735
+ {
736
+ // PHP only supports $this inside anonymous functions since 5.4
737
+ $minifier = $this;
738
+ $this->registerPattern(
739
+ '/(?<=^|[;}])(--[^:;{}"\'\s]+)\s*:([^;{}]+)/m',
740
+ function ($match) use ($minifier) {
741
+ $placeholder = '--custom-'. count($minifier->extracted) . ':0';
742
+ $minifier->extracted[$placeholder] = $match[1] .':'. trim($match[2]);
743
+ return $placeholder;
744
+
745
+ }
746
+ );
747
  }
748
 
749
  /**
vendor/matthiasmullie/minify/src/JS.php CHANGED
@@ -254,7 +254,7 @@ class JS extends Minify
254
  // of the RegExp methods (a `\` followed by a variable or value is
255
  // likely part of a division, not a regex)
256
  $keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
257
- $before = '([=:,;\+\-\*\/\}\(\{\[&\|!]|^|'.implode('|', $keywords).')\s*';
258
  $propertiesAndMethods = array(
259
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
260
  'constructor',
254
  // of the RegExp methods (a `\` followed by a variable or value is
255
  // likely part of a division, not a regex)
256
  $keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
257
+ $before = '(^|[=:,;\+\-\*\/\}\(\{\[&\|!]|'.implode('|', $keywords).')\s*';
258
  $propertiesAndMethods = array(
259
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
260
  'constructor',
vendor/matthiasmullie/minify/src/Minify.php CHANGED
@@ -105,7 +105,7 @@ abstract class Minify
105
  * @param string|string[] $data
106
  *
107
  * @return static
108
- *
109
  * @throws IOException
110
  */
111
  public function addFile($data /* $data = null, ... */)
@@ -472,7 +472,7 @@ abstract class Minify
472
  */
473
  protected function openFileForWriting($path)
474
  {
475
- if (($handler = @fopen($path, 'w')) === false) {
476
  throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.');
477
  }
478
 
@@ -490,7 +490,11 @@ abstract class Minify
490
  */
491
  protected function writeToFile($handler, $content, $path = '')
492
  {
493
- if (($result = @fwrite($handler, $content)) === false || ($result < strlen($content))) {
 
 
 
 
494
  throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.');
495
  }
496
  }
105
  * @param string|string[] $data
106
  *
107
  * @return static
108
+ *
109
  * @throws IOException
110
  */
111
  public function addFile($data /* $data = null, ... */)
472
  */
473
  protected function openFileForWriting($path)
474
  {
475
+ if ($path === '' || ($handler = @fopen($path, 'w')) === false) {
476
  throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.');
477
  }
478
 
490
  */
491
  protected function writeToFile($handler, $content, $path = '')
492
  {
493
+ if (
494
+ !is_resource($handler) ||
495
+ ($result = @fwrite($handler, $content)) === false ||
496
+ ($result < strlen($content))
497
+ ) {
498
  throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.');
499
  }
500
  }
views/tabs/advanced.php CHANGED
@@ -25,8 +25,81 @@ if ( isset( $advanced['breeze-exclude-js'] ) && ! empty( $advanced['breeze-exclu
25
  if ( isset( $advanced['breeze-exclude-urls'] ) && ! empty( $advanced['breeze-exclude-urls'] ) ) {
26
  $excluded_url_list = breeze_validate_urls( $advanced['breeze-exclude-urls'] );
27
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  ?>
29
- <table cellspacing="15">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  <tr>
31
  <td>
32
  <label for="exclude-urls" class="breeze_tool_tip"><?php _e( 'Never Cache these URLs', 'breeze' ); ?></label>
@@ -79,6 +152,21 @@ if ( isset( $advanced['breeze-exclude-urls'] ) && ! empty( $advanced['breeze-exc
79
  </tr>
80
  <tr>
81
  <td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  <label for="exclude-css" class="breeze_tool_tip"><?php _e( 'Exclude CSS', 'breeze' ); ?></label>
83
  </td>
84
  <td>
@@ -125,6 +213,70 @@ if ( isset( $advanced['breeze-exclude-urls'] ) && ! empty( $advanced['breeze-exc
125
  <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'Use this option to exclude JS files from Minification and Grouping. Enter the URLs of JS files on each line.', 'breeze' ); ?></span>
126
  </td>
127
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  <tr>
129
  <td>
130
  <label for="move-to-footer-js" class="breeze_tool_tip"><?php _e( 'Move JS files to footer', 'breeze' ); ?></label>
@@ -228,4 +380,21 @@ if ( isset( $advanced['breeze-exclude-urls'] ) && ! empty( $advanced['breeze-exc
228
  </div>
229
  </td>
230
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  </table>
25
  if ( isset( $advanced['breeze-exclude-urls'] ) && ! empty( $advanced['breeze-exclude-urls'] ) ) {
26
  $excluded_url_list = breeze_validate_urls( $advanced['breeze-exclude-urls'] );
27
  }
28
+
29
+ if ( ! isset( $advanced['breeze-preload-links'] ) ) {
30
+ $advanced['breeze-preload-links'] = '0';
31
+ }
32
+
33
+ if ( ! isset( $advanced['breeze-lazy-load'] ) ) {
34
+ $advanced['breeze-lazy-load'] = '0';
35
+ }
36
+
37
+ if ( ! isset( $advanced['breeze-lazy-load-native'] ) ) {
38
+ $advanced['breeze-lazy-load-native'] = '0';
39
+ }
40
+
41
+ if ( ! isset( $advanced['breeze-group-css'] ) ) {
42
+ $advanced['breeze-group-css'] = '0';
43
+ }
44
+
45
+ if ( ! isset( $advanced['breeze-group-js'] ) ) {
46
+ $advanced['breeze-group-js'] = '0';
47
+ }
48
  ?>
49
+ <table cellspacing="15" id="advanced-options-tab">
50
+ <tr>
51
+ <td><label for="bz-lazy-load" class="breeze_tool_tip"><?php _e( 'Lazy-Load images', 'breeze' ); ?></label></td>
52
+ <td>
53
+ <?php
54
+ $disabled = 'disabled';
55
+
56
+ if ( class_exists( 'DOMDocument' ) && class_exists( 'DOMXPath' ) ) {
57
+ $disabled = '';
58
+ }
59
+ ?>
60
+ <input type="checkbox" id="bz-lazy-load" name="bz-lazy-load"
61
+ value='1' <?php checked( $advanced['breeze-lazy-load'], '1' ); ?> <?php echo $disabled; ?>/>
62
+ <span class="breeze_tool_tip">
63
+ <?php _e( 'Images will begin to load before being displayed on screen.', 'breeze' ); ?>
64
+ </span>
65
+ <?php
66
+ if ( ! empty( $disabled ) ) {
67
+ ?>
68
+ <br/>
69
+ <span class="breeze_tool_tip" style="color: #ff0000">
70
+ <?php _e( 'This option requires the library PHP DOMDocument and PHP DOMXPath', 'breeze' ); ?>
71
+ </span>
72
+ <br/>
73
+ <?php
74
+ } else {
75
+ echo '<br/>';
76
+ }
77
+
78
+
79
+ $is_checked_lazy = checked( $advanced['breeze-lazy-load'], '1', false );
80
+ if ( ! empty( $is_checked_lazy ) ) {
81
+ if ( ! empty( $disabled ) ) {
82
+ $hide = ' style="display:none"';
83
+ } else {
84
+ $hide = '';
85
+ }
86
+
87
+ } else {
88
+ $hide = ' style="display:none"';
89
+ }
90
+
91
+ ?>
92
+ <br/>
93
+ <span <?php echo $hide; ?> id="native-lazy-option">
94
+ <input type="checkbox" id="bz-lazy-load-nat" name="bz-lazy-load-nat"
95
+ value='1' <?php checked( $advanced['breeze-lazy-load-native'], '1' ); ?>/>
96
+ <span class="breeze_tool_tip">
97
+ <strong><?php _e( 'Enable native browser lazy load', 'breeze' ); ?></strong><br/>
98
+ <?php _e( '<strong>Note</strong>: This is not supported by all browsers.', 'breeze' ); ?>
99
+ </span>
100
+ </span>
101
+ </td>
102
+ </tr>
103
  <tr>
104
  <td>
105
  <label for="exclude-urls" class="breeze_tool_tip"><?php _e( 'Never Cache these URLs', 'breeze' ); ?></label>
152
  </tr>
153
  <tr>
154
  <td>
155
+ <label class="breeze_tool_tip"><?php _e( 'Preload links', 'breeze' ); ?></label>
156
+ </td>
157
+ <td>
158
+ <input type="checkbox" name="preload-links" id="preload-links"
159
+ value="1" <?php checked( $advanced['breeze-preload-links'], '1' ); ?>/>
160
+ <label class="breeze_tool_tip" for="preload-links"><?php _e( 'Activate preload links feature', 'breeze' ); ?></label>
161
+ <br/>
162
+ <span class="breeze_tool_tip">
163
+ <b>Note:&nbsp;</b><?php _e( 'When users hover over links, the cache is created in advance. The page will load faster upon link visiting.', 'breeze' ); ?><br/>
164
+ <b><?php _e( 'Important: This feature is supported by Chromium based browsers (Chrome, Opera, Microsoft Edge Chromium, Brave...)', 'breeze' ); ?>;</b>
165
+ </span>
166
+ </td>
167
+ </tr>
168
+ <tr>
169
+ <td>
170
  <label for="exclude-css" class="breeze_tool_tip"><?php _e( 'Exclude CSS', 'breeze' ); ?></label>
171
  </td>
172
  <td>
213
  <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'Use this option to exclude JS files from Minification and Grouping. Enter the URLs of JS files on each line.', 'breeze' ); ?></span>
214
  </td>
215
  </tr>
216
+ <tr>
217
+ <td>
218
+ <label for="breeze-preload-font" class="breeze_tool_tip"><?php _e( 'Preload your webfonts', 'breeze' ); ?></label>
219
+ </td>
220
+ <td>
221
+ <div class="breeze-list-url">
222
+ <?php if ( ! empty( $advanced['breeze-preload-fonts'] ) ) : ?>
223
+ <?php foreach ( $advanced['breeze-preload-fonts'] as $font_url ) : ?>
224
+ <div class="breeze-input-group">
225
+ <span class="sort-handle">
226
+ <span class="dashicons dashicons-arrow-up moveUp"></span>
227
+ <span class="dashicons dashicons-arrow-down moveDown"></span>
228
+ </span>
229
+ <input type="text" size="98"
230
+ class="breeze-input-url"
231
+ name="breeze-preload-font[]"
232
+ placeholder="<?php _e( 'Enter Font/CSS URL...', 'breeze' ); ?>"
233
+ value="<?php echo esc_html( $font_url ); ?>"/>
234
+ <span class="dashicons dashicons-no item-remove" title="<?php _e( 'Remove', 'breeze' ); ?>"></span>
235
+ </div>
236
+ <?php endforeach; ?>
237
+ <?php else : ?>
238
+ <div class="breeze-input-group">
239
+ <span class="sort-handle">
240
+ <span class="dashicons dashicons-arrow-up moveUp"></span>
241
+ <span class="dashicons dashicons-arrow-down moveDown"></span>
242
+ </span>
243
+ <input type="text" size="98"
244
+ class="breeze-input-url"
245
+ id="breeze-preload-font"
246
+ name="breeze-preload-font[]"
247
+ placeholder="<?php _e( 'Enter Font/CSS URL...', 'breeze' ); ?>"
248
+ value=""/>
249
+ <span class="dashicons dashicons-no" title="<?php _e( 'Remove', 'breeze' ); ?>"></span>
250
+ </div>
251
+ <?php endif; ?>
252
+ </div>
253
+ <div style="margin: 10px 0">
254
+ <button type="button" class="button add-url" id="add-breeze-preload-fonts">
255
+ <?php _e( 'Add URL', 'breeze' ); ?>
256
+ </button>
257
+ </div>
258
+ <div>
259
+ <span class="breeze_tool_tip">
260
+ <b>Note:&nbsp;</b>
261
+ <?php _e( 'Specify the local font URL or the URL for the CSS file which loads only fonts.', 'breeze' ); ?>
262
+ </span>
263
+ <span class="breeze_tool_tip">
264
+ <?php _e( 'Load WOFF format fonts for the best performance.', 'breeze' ); ?>
265
+ </span>
266
+ <span class="breeze_tool_tip">
267
+ <?php _e( 'Do not preload the whole website CSS file as it will slow down your website.', 'breeze' ); ?>
268
+ </span>
269
+ <span class="breeze_tool_tip">
270
+ <?php _e( 'Do not add Google Fonts links as those already use preload.', 'breeze' ); ?>
271
+ </span>
272
+ <br/>
273
+ <span class="breeze_tool_tip">
274
+ <?php $theme_url = get_template_directory_uri().'/assets/fonts/my-font.woff';?>
275
+ <?php _e( 'Example:<code>'.$theme_url.'</code>', 'breeze' ); ?>
276
+ </span>
277
+ </div>
278
+ </td>
279
+ </tr>
280
  <tr>
281
  <td>
282
  <label for="move-to-footer-js" class="breeze_tool_tip"><?php _e( 'Move JS files to footer', 'breeze' ); ?></label>
380
  </div>
381
  </td>
382
  </tr>
383
+ <tr>
384
+ <td>
385
+ <label for="delay-js-scripts" class="breeze_tool_tip"><?php _e( 'Delay JS inline scripts', 'breeze' ); ?></label>
386
+ </td>
387
+ <td>
388
+ <?php
389
+ $js_output = '';
390
+ if ( ! empty( $advanced['breeze-delay-js-scripts'] ) ) {
391
+ $output = implode( "\n", $advanced['breeze-delay-js-scripts'] );
392
+ $js_output = esc_textarea( $output );
393
+ }
394
+ ?>
395
+ <textarea cols="100" rows="7" id="delay-js-scripts" name="delay-js-scripts"><?php echo $js_output; ?></textarea>
396
+ <br/>
397
+ <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'You can add specififc keywords to identify the inline JavaScript to be delayed. Each script identifying keyword must be added on a new line.', 'breeze' ); ?></span>
398
+ </td>
399
+ </tr>
400
  </table>
views/tabs/basic.php CHANGED
@@ -3,84 +3,104 @@ defined( 'ABSPATH' ) or die;
3
 
4
  $basic = breeze_get_option( 'basic_settings', true );
5
  ?>
6
- <table cellspacing="15">
7
- <tr>
8
- <td>
9
  <label for="cache-system"><?php _e( 'Cache System', 'breeze' ); ?></label>
10
- </td>
11
- <td>
12
- <input type="checkbox" id="cache-system" name="cache-system"
13
- value='1' <?php checked( $basic['breeze-active'], '1' ); ?>/>
14
- <span class="breeze_tool_tip">
15
  <?php _e( 'This is the basic cache that we recommend should be kept enabled in all cases. Basic cache will build the internal and static caches for the WordPress websites.', 'breeze' ); ?>
16
- </span>
17
- </td>
18
- </tr>
19
- <tr>
20
- <td>
 
 
 
 
 
 
 
 
 
 
 
 
21
  <label for="cache-ttl"><?php _e( 'Purge cache after', 'breeze' ); ?></label>
22
- </td>
23
- <td>
24
- <input type="text" id="cache-ttl" size="5" name="cache-ttl"
25
- value='<?php echo( ! empty( $basic['breeze-ttl'] ) ? (int) $basic['breeze-ttl'] : '1440' ); ?>'/>
26
- <span class="breeze_tool_tip" style="vertical-align: baseline">
27
  <?php _e( 'Automatically purge internal cache after X minutes. By default this is set to 1440 minutes (1 day)', 'breeze' ); ?>
28
- </span>
29
- </td>
30
- </tr>
31
- <tr>
32
- <td>
33
  <label class="breeze_tool_tip"><?php _e( 'Minification', 'breeze' ); ?></label>
34
- </td>
35
- <td>
36
- <ul>
37
- <li>
38
- <input type="checkbox" name="minification-html" id="minification-html"
39
- value="1" <?php checked( $basic['breeze-minify-html'], '1' ); ?>/>
40
- <label class="breeze_tool_tip" for="minification-html">
41
  <?php _e( 'HTML', 'breeze' ); ?>
42
- </label>
43
- </li>
44
- <li>
45
- <input type="checkbox" name="minification-css" id="minification-css"
46
- value="1" <?php checked( $basic['breeze-minify-css'], '1' ); ?>/>
47
- <label class="breeze_tool_tip" for="minification-css">
48
  <?php _e( 'CSS', 'breeze' ); ?>
49
- </label>
50
- </li>
51
- <li>
52
- <input type="checkbox" name="minification-js" id="minification-js"
53
- value="1" <?php checked( $basic['breeze-minify-js'], '1' ); ?>/>
54
- <label class="breeze_tool_tip" for="minification-js">
 
 
 
 
 
 
 
 
55
  <?php _e( 'JS', 'breeze' ); ?>
56
- </label>
57
- </li>
58
- <li>
59
- <input type="checkbox" name="include-inline-js" id="include-inline-js"
60
- value="1" <?php checked( $basic['breeze-include-inline-js'], '1' ); ?>/>
61
- <label class="breeze_tool_tip" for="include-inline-js">
62
  <?php _e( 'Include inline JS', 'breeze' ); ?>
63
- </label>
64
- </li>
65
- <li>
66
- <input type="checkbox" name="include-inline-css" id="include-inline-css"
67
- value="1" <?php checked( $basic['breeze-include-inline-css'], '1' ); ?>/>
68
- <label class="breeze_tool_tip" for="include-inline-css">
69
  <?php _e( 'Include inline CSS', 'breeze' ); ?>
70
- </label>
71
- </li>
72
- <li>
73
  <span><?php _e( 'Check the above boxes to minify HTML, CSS, or JS files.', 'breeze' ); ?></span>
74
- <br>
75
- <span>
76
  <b><?php esc_html_e( 'Note', 'breeze' ); ?>:&nbsp;</b>
77
  <span style="color: #ff0000"><?php _e( 'We recommend testing minification on a staging website before deploying it on a live website. Minification is known to cause issues on the frontend.', 'breeze' ); ?></span>
78
- </span>
79
- </li>
80
- </ul>
81
 
82
- </td>
83
- </tr>
84
 
85
  <?php
86
 
@@ -108,7 +128,7 @@ $basic = breeze_get_option( 'basic_settings', true );
108
  </td>
109
  <td>
110
  <input type="checkbox" id="<?php echo esc_attr( $fid ); ?>" name="<?php echo esc_attr( $fid ); ?>"
111
- value='1' <?php checked( $is_checked, true ); ?> <?php echo $is_disabled ? 'disabled="disabled"' : ''; ?>/>
112
  <span class="breeze_tool_tip"><?php echo esc_html( $field['desc'] ); ?></span>
113
  <?php if ( $is_disabled ) { ?>
114
  <br>
@@ -124,50 +144,50 @@ $basic = breeze_get_option( 'basic_settings', true );
124
 
125
  ?>
126
 
127
- <tr style="display: none;">
128
- <td style="vertical-align: middle">
129
  <label for="desktop-cache" class="breeze_tool_tip"> <?php _e( 'Desktop Cache', 'breeze' ); ?></label>
130
- </td>
131
- <td>
132
- <select id="desktop-cache" name="desktop-cache">
133
  <option value="1" <?php echo ( $basic['breeze-desktop-cache'] == '1' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Activated', 'breeze' ); ?></option>
134
  <option value="2" <?php echo ( $basic['breeze-desktop-cache'] == '2' ) ? 'selected="selected"' : ''; ?>><?php _e( 'No cache for desktop', 'breeze' ); ?></option>
135
- </select>
136
- </td>
137
- </tr>
138
 
139
- <tr style="display: none;">
140
- <td style="vertical-align: middle">
141
  <label for="mobile-cache" class="breeze_tool_tip"> <?php _e( 'Mobile Cache', 'breeze' ); ?></label>
142
- </td>
143
- <td>
144
- <select id="mobile-cache" name="mobile-cache">
145
  <option value="1" <?php echo ( $basic['breeze-mobile-cache'] == '1' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Automatic (same as desktop)', 'breeze' ); ?></option>
146
  <option value="2" <?php echo ( $basic['breeze-mobile-cache'] == '2' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Specific mobile cache', 'breeze' ); ?></option>
147
  <option value="3" <?php echo ( $basic['breeze-mobile-cache'] == '3' ) ? 'selected="selected"' : ''; ?>><?php _e( 'No cache for mobile', 'breeze' ); ?></option>
148
- </select>
149
- </td>
150
- </tr>
151
- <tr>
152
- <td>
153
- <label class="breeze_tool_tip"><?php _e( 'Enable cache for loggedin users', 'breeze' ); ?></label>
154
- </td>
155
- <td>
156
- <ul>
157
- <li>
158
- <input type="checkbox" name="breeze-admin-cache" id="breeze-admin-cache"
159
- value="0" <?php checked( $basic['breeze-disable-admin'], '0' ); ?>/>
160
- <label class="breeze_tool_tip" for="breeze-admin-cache">
161
  <?php _e( 'Enable cache for WP standard user roles: Administrator, Editor, Author, Contributor.', 'breeze' ); ?>
162
 
163
- </label>
164
- <br/>
165
- <span>
166
  <b><?php esc_html_e( 'Note', 'breeze' ); ?>:&nbsp;</b>
167
  <span style="color: #ff0000"><?php echo esc_html__( 'This option might not work properly with some page builders.', 'breeze' ); ?></span>
168
  </span>
169
- </li>
170
- </ul>
171
- </td>
172
- </tr>
173
  </table>
3
 
4
  $basic = breeze_get_option( 'basic_settings', true );
5
  ?>
6
+ <table cellspacing="15" id="basic-panel">
7
+ <tr>
8
+ <td>
9
  <label for="cache-system"><?php _e( 'Cache System', 'breeze' ); ?></label>
10
+ </td>
11
+ <td>
12
+ <input type="checkbox" id="cache-system" name="cache-system"
13
+ value='1' <?php ( isset( $basic['breeze-active'] ) ) ? checked( $basic['breeze-active'], '1' ) : ''; ?> />
14
+ <span class="breeze_tool_tip">
15
  <?php _e( 'This is the basic cache that we recommend should be kept enabled in all cases. Basic cache will build the internal and static caches for the WordPress websites.', 'breeze' ); ?>
16
+ </span>
17
+ </td>
18
+ </tr>
19
+ <tr>
20
+ <td>
21
+ <label for="safe-cross-origin"><?php _e( 'Cross-origin safe links', 'breeze' ); ?></label>
22
+ </td>
23
+ <td>
24
+ <input type="checkbox" id="safe-cross-origin" name="safe-cross-origin"
25
+ value='1' <?php ( isset( $basic['breeze-cross-origin'] ) ) ? checked( $basic['breeze-cross-origin'], '1' ) : ''; ?>/>
26
+ <span class="breeze_tool_tip">
27
+ <?php _e( 'Apply "noopener noreferrer" to links which have target"_blank" attribute and the anchor leads to external websites.', 'breeze' ); ?>
28
+ </span>
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <td>
33
  <label for="cache-ttl"><?php _e( 'Purge cache after', 'breeze' ); ?></label>
34
+ </td>
35
+ <td>
36
+ <input type="text" id="cache-ttl" size="5" name="cache-ttl"
37
+ value='<?php echo( isset( $basic['breeze-ttl'] ) && ! empty( $basic['breeze-ttl'] ) ? (int) $basic['breeze-ttl'] : '1440' ); ?>'/>
38
+ <span class="breeze_tool_tip" style="vertical-align: baseline">
39
  <?php _e( 'Automatically purge internal cache after X minutes. By default this is set to 1440 minutes (1 day)', 'breeze' ); ?>
40
+ </span>
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <td>
45
  <label class="breeze_tool_tip"><?php _e( 'Minification', 'breeze' ); ?></label>
46
+ </td>
47
+ <td>
48
+ <ul>
49
+ <li>
50
+ <input type="checkbox" name="minification-html" id="minification-html"
51
+ value="1" <?php ( isset( $basic['breeze-minify-html'] ) ) ? checked( $basic['breeze-minify-html'], '1' ) : ''; ?> />
52
+ <label class="breeze_tool_tip" for="minification-html">
53
  <?php _e( 'HTML', 'breeze' ); ?>
54
+ </label>
55
+ </li>
56
+ <li>
57
+ <input type="checkbox" name="minification-css" id="minification-css"
58
+ value="1" <?php ( isset( $basic['breeze-minify-css'] ) ) ? checked( $basic['breeze-minify-css'], '1' ) : ''; ?> />
59
+ <label class="breeze_tool_tip" for="minification-css">
60
  <?php _e( 'CSS', 'breeze' ); ?>
61
+ </label>
62
+ </li>
63
+ <li id="font-display-swap" style="display: none">
64
+ &nbsp;&nbsp;&nbsp;&nbsp;
65
+ <input type="checkbox" name="font-display" id="font-display"
66
+ value="1" <?php ( isset( $basic['breeze-font-display-swap'] ) ) ? checked( $basic['breeze-font-display-swap'], '1' ) : ''; ?>/>
67
+ <label class="breeze_tool_tip" for="font-display">
68
+ <?php _e( 'Font remain visible during load', 'breeze' ); ?>
69
+ </label>
70
+ </li>
71
+ <li>
72
+ <input type="checkbox" name="minification-js" id="minification-js"
73
+ value="1" <?php ( isset( $basic['breeze-minify-js'] ) ) ? checked( $basic['breeze-minify-js'], '1' ) : ''; ?> />
74
+ <label class="breeze_tool_tip" for="minification-js">
75
  <?php _e( 'JS', 'breeze' ); ?>
76
+ </label>
77
+ </li>
78
+ <li>
79
+ <input type="checkbox" name="include-inline-js" id="include-inline-js"
80
+ value="1" <?php ( isset( $basic['breeze-include-inline-js'] ) ) ? checked( $basic['breeze-include-inline-js'], '1' ) : ''; ?>/>
81
+ <label class="breeze_tool_tip" for="include-inline-js">
82
  <?php _e( 'Include inline JS', 'breeze' ); ?>
83
+ </label>
84
+ </li>
85
+ <li>
86
+ <input type="checkbox" name="include-inline-css" id="include-inline-css"
87
+ value="1" <?php ( isset( $basic['breeze-include-inline-css'] ) ) ? checked( $basic['breeze-include-inline-css'], '1' ) : ''; ?> />
88
+ <label class="breeze_tool_tip" for="include-inline-css">
89
  <?php _e( 'Include inline CSS', 'breeze' ); ?>
90
+ </label>
91
+ </li>
92
+ <li>
93
  <span><?php _e( 'Check the above boxes to minify HTML, CSS, or JS files.', 'breeze' ); ?></span>
94
+ <br>
95
+ <span>
96
  <b><?php esc_html_e( 'Note', 'breeze' ); ?>:&nbsp;</b>
97
  <span style="color: #ff0000"><?php _e( 'We recommend testing minification on a staging website before deploying it on a live website. Minification is known to cause issues on the frontend.', 'breeze' ); ?></span>
98
+ </span>
99
+ </li>
100
+ </ul>
101
 
102
+ </td>
103
+ </tr>
104
 
105
  <?php
106
 
128
  </td>
129
  <td>
130
  <input type="checkbox" id="<?php echo esc_attr( $fid ); ?>" name="<?php echo esc_attr( $fid ); ?>"
131
+ value='1' <?php checked( $is_checked, true ); ?> <?php echo $is_disabled ? 'disabled="disabled"' : ''; ?>/>
132
  <span class="breeze_tool_tip"><?php echo esc_html( $field['desc'] ); ?></span>
133
  <?php if ( $is_disabled ) { ?>
134
  <br>
144
 
145
  ?>
146
 
147
+ <tr style="display: none;">
148
+ <td style="vertical-align: middle">
149
  <label for="desktop-cache" class="breeze_tool_tip"> <?php _e( 'Desktop Cache', 'breeze' ); ?></label>
150
+ </td>
151
+ <td>
152
+ <select id="desktop-cache" name="desktop-cache">
153
  <option value="1" <?php echo ( $basic['breeze-desktop-cache'] == '1' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Activated', 'breeze' ); ?></option>
154
  <option value="2" <?php echo ( $basic['breeze-desktop-cache'] == '2' ) ? 'selected="selected"' : ''; ?>><?php _e( 'No cache for desktop', 'breeze' ); ?></option>
155
+ </select>
156
+ </td>
157
+ </tr>
158
 
159
+ <tr style="display: none;">
160
+ <td style="vertical-align: middle">
161
  <label for="mobile-cache" class="breeze_tool_tip"> <?php _e( 'Mobile Cache', 'breeze' ); ?></label>
162
+ </td>
163
+ <td>
164
+ <select id="mobile-cache" name="mobile-cache">
165
  <option value="1" <?php echo ( $basic['breeze-mobile-cache'] == '1' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Automatic (same as desktop)', 'breeze' ); ?></option>
166
  <option value="2" <?php echo ( $basic['breeze-mobile-cache'] == '2' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Specific mobile cache', 'breeze' ); ?></option>
167
  <option value="3" <?php echo ( $basic['breeze-mobile-cache'] == '3' ) ? 'selected="selected"' : ''; ?>><?php _e( 'No cache for mobile', 'breeze' ); ?></option>
168
+ </select>
169
+ </td>
170
+ </tr>
171
+ <tr>
172
+ <td>
173
+ <label class="breeze_tool_tip"><?php _e( 'Enable cache for loggedin users', 'breeze' ); ?></label>
174
+ </td>
175
+ <td>
176
+ <ul>
177
+ <li>
178
+ <input type="checkbox" name="breeze-admin-cache" id="breeze-admin-cache"
179
+ value="0" <?php ( isset( $basic['breeze-disable-admin'] ) ) ? checked( $basic['breeze-disable-admin'], '0' ) : ''; ?> />
180
+ <label class="breeze_tool_tip" for="breeze-admin-cache">
181
  <?php _e( 'Enable cache for WP standard user roles: Administrator, Editor, Author, Contributor.', 'breeze' ); ?>
182
 
183
+ </label>
184
+ <br/>
185
+ <span>
186
  <b><?php esc_html_e( 'Note', 'breeze' ); ?>:&nbsp;</b>
187
  <span style="color: #ff0000"><?php echo esc_html__( 'This option might not work properly with some page builders.', 'breeze' ); ?></span>
188
  </span>
189
+ </li>
190
+ </ul>
191
+ </td>
192
+ </tr>
193
  </table>
views/tabs/cdn.php CHANGED
@@ -11,35 +11,47 @@ if ( ! empty( $cdn_integration['cdn-content'] ) ) {
11
  if ( ! empty( $cdn_integration['cdn-exclude-content'] ) ) {
12
  $cdn_exclude_content_value = implode( ',', $cdn_integration['cdn-exclude-content'] );
13
  }
 
 
 
 
 
 
 
 
 
 
 
 
14
  ?>
15
  <table cellspacing="15">
16
- <tr>
17
- <td>
18
  <label for="activate-cdn" class="breeze_tool_tip"><?php _e( 'Activate CDN', 'breeze' ); ?></label>
19
- </td>
20
- <td>
21
  <input type="checkbox" id="activate-cdn" name="activate-cdn" value="1" <?php checked( $cdn_integration['cdn-active'], '1' ); ?>/>
22
  <span class="breeze_tool_tip"><?php _e( 'Enable to make CDN effective on your website.', 'breeze' ); ?></span>
23
- </td>
24
- </tr>
25
- <tr>
26
- <td>
27
  <label for="cdn-url" class="breeze_tool_tip"><?php _e( 'CDN CNAME', 'breeze' ); ?></label>
28
- </td>
29
- <td>
30
  <?php
31
  $cdn_url = ( ( $cdn_integration['cdn-url'] ) ? esc_html( $cdn_integration['cdn-url'] ) : '' );
32
  $cdn_url_validation = breeze_validate_url_via_regexp( $cdn_url );
33
  ?>
34
  <input type="text" id="cdn-url" name="cdn-url" size="50" placeholder="<?php _e( 'https://www.domain.com', 'breeze' ); ?>" value="<?php echo $cdn_url; ?>"/>
35
  <span style="vertical-align: baseline" class="breeze_tool_tip"><?php _e( 'Enter CDN CNAME.', 'breeze' ); ?></span>
36
- <br>
37
  <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'Use double slash ‘//’ at the start of CDN CNAME, if you have some pages on HTTP and some are on HTTPS.', 'breeze' ); ?></span>
38
  <?php
39
  if ( false === $cdn_url_validation && ! empty( $cdn_url ) ) {
40
  ?>
41
- <br/>
42
- <span>
43
  <b><?php esc_html_e( 'Note', 'breeze' ); ?>:&nbsp;</b>
44
  <span style="color: #ff0000">
45
  <?php
@@ -51,35 +63,35 @@ if ( ! empty( $cdn_integration['cdn-exclude-content'] ) ) {
51
  <?php
52
  }
53
  ?>
54
- </td>
55
- </tr>
56
- <tr>
57
- <td>
58
  <label for="cdn-content" class="breeze_tool_tip" ><?php _e( 'CDN Content', 'breeze' ); ?></label>
59
- </td>
60
- <td>
61
  <input type="text" id="cdn-content" name="cdn-content" size="50" value="<?php echo ( ( $cdn_content_value ) ? esc_html( $cdn_content_value ) : '' ); ?>"/>
62
- <br>
63
  <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'Enter the directories (comma separated) of which you want the CDN to serve the content.', 'breeze' ); ?></span>
64
- </td>
65
- </tr>
66
- <tr>
67
- <td>
68
  <label for="cdn-exclude-content" class="breeze_tool_tip" ><?php _e( 'Exclude Content', 'breeze' ); ?></label>
69
- </td>
70
- <td>
71
  <input type="text" id="cdn-exclude-content" name="cdn-exclude-content" size="50" value="<?php echo ( ( $cdn_exclude_content_value ) ? esc_html( $cdn_exclude_content_value ) : '' ); ?>" />
72
- <br>
73
  <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'Exclude file types or directories from CDN. Example, enter .css to exclude the CSS files.', 'breeze' ); ?></span>
74
- </td>
75
- </tr>
76
- <tr>
77
- <td>
78
  <label for="cdn-relative-path" class="breeze_tool_tip" ><?php _e( 'Relative path', 'breeze' ); ?></label>
79
- </td>
80
- <td>
81
  <input type="checkbox" id="cdn-relative-path" name="cdn-relative-path" value="1" <?php checked( $cdn_integration['cdn-relative-path'], '1' ); ?>/>
82
  <span class="breeze_tool_tip"><?php _e( 'Keep this option enabled. Use this option to enable relative path for your CDN on your WordPress site.', 'breeze' ); ?></span>
83
- </td>
84
- </tr>
85
  </table>
11
  if ( ! empty( $cdn_integration['cdn-exclude-content'] ) ) {
12
  $cdn_exclude_content_value = implode( ',', $cdn_integration['cdn-exclude-content'] );
13
  }
14
+
15
+ if ( ! isset( $cdn_integration['cdn-active'] ) ) {
16
+ $cdn_integration['cdn-active'] = '0';
17
+ }
18
+
19
+ if ( ! isset( $cdn_integration['cdn-url'] ) ) {
20
+ $cdn_integration['cdn-url'] = '';
21
+ }
22
+
23
+ if ( ! isset( $cdn_integration['cdn-relative-path'] ) ) {
24
+ $cdn_integration['cdn-relative-path'] = '0';
25
+ }
26
  ?>
27
  <table cellspacing="15">
28
+ <tr>
29
+ <td>
30
  <label for="activate-cdn" class="breeze_tool_tip"><?php _e( 'Activate CDN', 'breeze' ); ?></label>
31
+ </td>
32
+ <td>
33
  <input type="checkbox" id="activate-cdn" name="activate-cdn" value="1" <?php checked( $cdn_integration['cdn-active'], '1' ); ?>/>
34
  <span class="breeze_tool_tip"><?php _e( 'Enable to make CDN effective on your website.', 'breeze' ); ?></span>
35
+ </td>
36
+ </tr>
37
+ <tr>
38
+ <td>
39
  <label for="cdn-url" class="breeze_tool_tip"><?php _e( 'CDN CNAME', 'breeze' ); ?></label>
40
+ </td>
41
+ <td>
42
  <?php
43
  $cdn_url = ( ( $cdn_integration['cdn-url'] ) ? esc_html( $cdn_integration['cdn-url'] ) : '' );
44
  $cdn_url_validation = breeze_validate_url_via_regexp( $cdn_url );
45
  ?>
46
  <input type="text" id="cdn-url" name="cdn-url" size="50" placeholder="<?php _e( 'https://www.domain.com', 'breeze' ); ?>" value="<?php echo $cdn_url; ?>"/>
47
  <span style="vertical-align: baseline" class="breeze_tool_tip"><?php _e( 'Enter CDN CNAME.', 'breeze' ); ?></span>
48
+ <br>
49
  <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'Use double slash ‘//’ at the start of CDN CNAME, if you have some pages on HTTP and some are on HTTPS.', 'breeze' ); ?></span>
50
  <?php
51
  if ( false === $cdn_url_validation && ! empty( $cdn_url ) ) {
52
  ?>
53
+ <br/>
54
+ <span>
55
  <b><?php esc_html_e( 'Note', 'breeze' ); ?>:&nbsp;</b>
56
  <span style="color: #ff0000">
57
  <?php
63
  <?php
64
  }
65
  ?>
66
+ </td>
67
+ </tr>
68
+ <tr>
69
+ <td>
70
  <label for="cdn-content" class="breeze_tool_tip" ><?php _e( 'CDN Content', 'breeze' ); ?></label>
71
+ </td>
72
+ <td>
73
  <input type="text" id="cdn-content" name="cdn-content" size="50" value="<?php echo ( ( $cdn_content_value ) ? esc_html( $cdn_content_value ) : '' ); ?>"/>
74
+ <br>
75
  <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'Enter the directories (comma separated) of which you want the CDN to serve the content.', 'breeze' ); ?></span>
76
+ </td>
77
+ </tr>
78
+ <tr>
79
+ <td>
80
  <label for="cdn-exclude-content" class="breeze_tool_tip" ><?php _e( 'Exclude Content', 'breeze' ); ?></label>
81
+ </td>
82
+ <td>
83
  <input type="text" id="cdn-exclude-content" name="cdn-exclude-content" size="50" value="<?php echo ( ( $cdn_exclude_content_value ) ? esc_html( $cdn_exclude_content_value ) : '' ); ?>" />
84
+ <br>
85
  <span class="breeze_tool_tip"><b>Note:&nbsp;</b><?php _e( 'Exclude file types or directories from CDN. Example, enter .css to exclude the CSS files.', 'breeze' ); ?></span>
86
+ </td>
87
+ </tr>
88
+ <tr>
89
+ <td>
90
  <label for="cdn-relative-path" class="breeze_tool_tip" ><?php _e( 'Relative path', 'breeze' ); ?></label>
91
+ </td>
92
+ <td>
93
  <input type="checkbox" id="cdn-relative-path" name="cdn-relative-path" value="1" <?php checked( $cdn_integration['cdn-relative-path'], '1' ); ?>/>
94
  <span class="breeze_tool_tip"><?php _e( 'Keep this option enabled. Use this option to enable relative path for your CDN on your WordPress site.', 'breeze' ); ?></span>
95
+ </td>
96
+ </tr>
97
  </table>
views/tabs/varnish.php CHANGED
@@ -3,44 +3,48 @@ defined( 'ABSPATH' ) or die;
3
 
4
  $varnish = breeze_get_option( 'varnish_cache', true );
5
  $check_varnish = is_varnish_cache_started();
 
 
 
 
6
  ?>
7
  <div class="breeze-top-notice">
8
  <p class="breeze_tool_tip"><?php _e( 'By default Varnish is enabled on all WordPress websites hosted on Cloudways.', 'breeze' ); ?></p>
9
  </div>
10
  <table cellspacing="15">
11
- <tr>
12
- <td>
13
  <label for="auto-purge-varnish" class="breeze_tool_tip"><?php _e( 'Auto Purge Varnish', 'breeze' ); ?></label>
14
- </td>
15
- <td>
16
  <input type="checkbox" id="auto-purge-varnish" name="auto-purge-varnish" value="1" <?php checked( $varnish['auto-purge-varnish'], '1' ); ?>/>
17
  <span class="breeze_tool_tip" ><?php _e( 'Keep this option enabled to automatically purge Varnish cache on actions like publishing new blog posts, pages and comments.', 'breeze' ); ?></span>
18
- <br>
19
  <?php if ( ! $check_varnish ) : ?>
20
- <span><b>Note:&nbsp;</b>
21
  <span style="color: #ff0000"><?php _e( 'Seems Varnish is disabled on your Application. Please refer to ', 'breeze' ); ?><a href="https://support.cloudways.com/most-common-varnish-issues-and-queries/" target="_blank"><?php _e( 'this KB', 'breeze' ); ?></a><?php _e( ' and learn how to enable it.', 'breeze' ); ?> </span>
22
- </span>
23
  <?php endif; ?>
24
- </td>
25
- </tr>
26
- <tr>
27
- <td>
28
  <label for="varnish-server-ip" class="breeze_tool_tip"><?php _e( 'Varnish server', 'breeze' ); ?></label>
29
- </td>
30
- <td>
31
- <input type="text" id="varnish-server-ip" size="20" name="varnish-server-ip"
32
  value='<?php echo( ! empty( $varnish['breeze-varnish-server-ip'] ) ? esc_html( $varnish['breeze-varnish-server-ip'] ) : '127.0.0.1' ); ?>'/>
33
- <br/>
34
  <span class="breeze_tool_tip"><strong><?php _e( 'Note: Keep this default if you are a Cloudways customer. Otherwise ask your hosting provider on what to set here.', 'breeze' ); ?></strong></span>
35
- </td>
36
- </tr>
37
- <tr>
38
- <td style="vertical-align: middle">
39
  <label class="breeze_tool_tip"><?php _e( 'Purge Varnish Cache', 'breeze' ); ?></label>
40
- </td>
41
- <td>
42
  <input type="button" id="purge-varnish-button" class="button" value="<?php _e( 'Purge', 'breeze' ); ?>" />
43
  <span style="vertical-align: bottom; margin-left: 5px"><?php _e( 'Use this option to instantly Purge Varnish Cache on entire website. ', 'breeze' ); ?></span>
44
- </td>
45
- </tr>
46
  </table>
3
 
4
  $varnish = breeze_get_option( 'varnish_cache', true );
5
  $check_varnish = is_varnish_cache_started();
6
+
7
+ if ( ! isset( $varnish['auto-purge-varnish'] ) ) {
8
+ $varnish['auto-purge-varnish'] = '0';
9
+ }
10
  ?>
11
  <div class="breeze-top-notice">
12
  <p class="breeze_tool_tip"><?php _e( 'By default Varnish is enabled on all WordPress websites hosted on Cloudways.', 'breeze' ); ?></p>
13
  </div>
14
  <table cellspacing="15">
15
+ <tr>
16
+ <td>
17
  <label for="auto-purge-varnish" class="breeze_tool_tip"><?php _e( 'Auto Purge Varnish', 'breeze' ); ?></label>
18
+ </td>
19
+ <td>
20
  <input type="checkbox" id="auto-purge-varnish" name="auto-purge-varnish" value="1" <?php checked( $varnish['auto-purge-varnish'], '1' ); ?>/>
21
  <span class="breeze_tool_tip" ><?php _e( 'Keep this option enabled to automatically purge Varnish cache on actions like publishing new blog posts, pages and comments.', 'breeze' ); ?></span>
22
+ <br>
23
  <?php if ( ! $check_varnish ) : ?>
24
+ <span><b>Note:&nbsp;</b>
25
  <span style="color: #ff0000"><?php _e( 'Seems Varnish is disabled on your Application. Please refer to ', 'breeze' ); ?><a href="https://support.cloudways.com/most-common-varnish-issues-and-queries/" target="_blank"><?php _e( 'this KB', 'breeze' ); ?></a><?php _e( ' and learn how to enable it.', 'breeze' ); ?> </span>
26
+ </span>
27
  <?php endif; ?>
28
+ </td>
29
+ </tr>
30
+ <tr>
31
+ <td>
32
  <label for="varnish-server-ip" class="breeze_tool_tip"><?php _e( 'Varnish server', 'breeze' ); ?></label>
33
+ </td>
34
+ <td>
35
+ <input type="text" id="varnish-server-ip" size="20" name="varnish-server-ip"
36
  value='<?php echo( ! empty( $varnish['breeze-varnish-server-ip'] ) ? esc_html( $varnish['breeze-varnish-server-ip'] ) : '127.0.0.1' ); ?>'/>
37
+ <br/>
38
  <span class="breeze_tool_tip"><strong><?php _e( 'Note: Keep this default if you are a Cloudways customer. Otherwise ask your hosting provider on what to set here.', 'breeze' ); ?></strong></span>
39
+ </td>
40
+ </tr>
41
+ <tr>
42
+ <td style="vertical-align: middle">
43
  <label class="breeze_tool_tip"><?php _e( 'Purge Varnish Cache', 'breeze' ); ?></label>
44
+ </td>
45
+ <td>
46
  <input type="button" id="purge-varnish-button" class="button" value="<?php _e( 'Purge', 'breeze' ); ?>" />
47
  <span style="vertical-align: bottom; margin-left: 5px"><?php _e( 'Use this option to instantly Purge Varnish Cache on entire website. ', 'breeze' ); ?></span>
48
+ </td>
49
+ </tr>
50
  </table>