Version Description
- Improvement: Better detection of the tags when the source of a tag (e.g. "src" or "href") is not wrapped around quotes or even has spaces added after or before the equal sign / e.g. OR <link rel=stylesheet href
Download this release
Release Info
Developer | gabelivan |
Plugin | Asset CleanUp: Page Speed Booster |
Version | 1.3.8.9 |
Comparing to | |
See all releases |
Code changes from version 1.3.8.8 to 1.3.8.9
- classes/CleanUp.php +1 -1
- classes/FileSystem.php +1 -1
- classes/HardcodedAssets.php +503 -81
- classes/Main.php +42 -29
- classes/Menu.php +1 -1
- classes/MetaBoxes.php +1 -1
- classes/Misc.php +133 -3
- classes/ObjectCache.php +1 -1
- classes/OptimiseAssets/CombineCssImports.php +3 -3
- classes/OptimiseAssets/CombineJs.php +2 -2
- classes/OptimiseAssets/DynamicLoadedAssets.php +2 -2
- classes/OptimiseAssets/FontsGoogle.php +5 -7
- classes/OptimiseAssets/MinifyCss.php +5 -4
- classes/OptimiseAssets/MinifyJs.php +3 -3
- classes/OptimiseAssets/OptimizeCommon.php +6 -11
- classes/OptimiseAssets/OptimizeCss.php +27 -21
- classes/OptimiseAssets/OptimizeJs.php +28 -15
- classes/OwnAssets.php +4 -0
- classes/Plugin.php +2 -2
- classes/Preloads.php +36 -33
- classes/Settings.php +4 -4
- classes/Tips.php +2 -2
- classes/Tools.php +1 -1
- classes/Update.php +2 -2
- readme.txt +8 -2
- templates/_admin-page-settings-plugin-areas/_html-source-cleanup.php +13 -3
- templates/admin-page-settings-bulk-changes.php +9 -9
- templates/meta-box-loaded-assets/_assets-hardcoded-list.php +25 -45
- templates/meta-box-loaded-assets/_common/_asset-single-row-load-exceptions.php +14 -14
- wpacu.php +2 -2
classes/CleanUp.php
CHANGED
@@ -36,7 +36,7 @@ class CleanUp
|
|
36 |
$settings = Main::instance()->settings;
|
37 |
|
38 |
// Remove "Really Simple Discovery (RSD)" link?
|
39 |
-
if ($settings['remove_rsd_link'] == 1) {
|
40 |
// <link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://yourwebsite.com/xmlrpc.php?rsd" />
|
41 |
remove_action('wp_head', 'rsd_link');
|
42 |
}
|
36 |
$settings = Main::instance()->settings;
|
37 |
|
38 |
// Remove "Really Simple Discovery (RSD)" link?
|
39 |
+
if ($settings['remove_rsd_link'] == 1 || $settings['disable_xmlrpc'] === 'disable_all') {
|
40 |
// <link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://yourwebsite.com/xmlrpc.php?rsd" />
|
41 |
remove_action('wp_head', 'rsd_link');
|
42 |
}
|
classes/FileSystem.php
CHANGED
@@ -73,7 +73,7 @@ class FileSystem
|
|
73 |
* @param $localPathToFile
|
74 |
* @param $contents
|
75 |
*
|
76 |
-
* @return
|
77 |
*/
|
78 |
public static function filePutContents($localPathToFile, $contents)
|
79 |
{
|
73 |
* @param $localPathToFile
|
74 |
* @param $contents
|
75 |
*
|
76 |
+
* @return bool
|
77 |
*/
|
78 |
public static function filePutContents($localPathToFile, $contents)
|
79 |
{
|
classes/HardcodedAssets.php
CHANGED
@@ -106,12 +106,182 @@ class HardcodedAssets
|
|
106 |
'script_src_and_inline_tags' => array(), // SCRIPT (with "src" attribute) & SCRIPT (inline)
|
107 |
);
|
108 |
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
/*
|
111 |
* [START] Collect Hardcoded LINK (stylesheet) & STYLE tags
|
112 |
*/
|
113 |
-
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
if ( ! empty( $matchesSourcesFromTags ) ) {
|
117 |
// Only the hashes are set
|
@@ -137,8 +307,8 @@ class HardcodedAssets
|
|
137 |
if ( isset( $matchedTag['link_tag'] ) && trim( $matchedTag['link_tag'] ) !== '' && ( trim( strip_tags( $matchedTag['link_tag'] ) ) === '' ) ) {
|
138 |
$matchedTagOutput = trim( $matchedTag['link_tag'] );
|
139 |
|
140 |
-
|
141 |
-
|
142 |
continue;
|
143 |
}
|
144 |
|
@@ -152,7 +322,7 @@ class HardcodedAssets
|
|
152 |
/*
|
153 |
* Strip certain STYLE tags irrelevant for the list (e.g. related to the WordPress Admin Bar, etc.)
|
154 |
*/
|
155 |
-
if ( in_array(
|
156 |
continue;
|
157 |
}
|
158 |
|
@@ -162,16 +332,8 @@ class HardcodedAssets
|
|
162 |
}
|
163 |
}
|
164 |
|
165 |
-
//
|
166 |
-
if (
|
167 |
-
&& strpos( $matchedTagOutput, 'img.emoji' ) !== false
|
168 |
-
&& strpos( $matchedTagOutput, '!important;' ) !== false ) {
|
169 |
-
continue;
|
170 |
-
}
|
171 |
-
|
172 |
-
if ( (strpos( $matchedTagOutput, 'data-wpacu-own-inline-style=' ) !== false) ||
|
173 |
-
(strpos( $matchedTagOutput, 'data-wpacu-inline-css-file=') !== false) ) {
|
174 |
-
// remove plugin's own STYLE tags as they are not relevant in this context
|
175 |
continue;
|
176 |
}
|
177 |
|
@@ -196,14 +358,26 @@ class HardcodedAssets
|
|
196 |
/*
|
197 |
* [START] Collect Hardcoded SCRIPT (src/inline)
|
198 |
*/
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
|
201 |
-
|
202 |
-
$allInlineAssocWithJsHandle = array();
|
203 |
|
|
|
204 |
foreach ( wp_scripts()->done as $assetHandle ) {
|
205 |
// Now, go through the list of inline SCRIPTs associated with an enqueued SCRIPT (with "src" attribute)
|
206 |
-
// And make sure they do not show to the hardcoded list, since they are related to the handle and they are stripped when the handle is dequeued
|
207 |
$anyInlineAssocWithJsHandle = OptimizeJs::getInlineAssociatedWithScriptHandle( $assetHandle, wp_scripts()->registered, 'handle' );
|
208 |
if ( ! empty( $anyInlineAssocWithJsHandle ) ) {
|
209 |
foreach ( $anyInlineAssocWithJsHandle as $jsInlineTagContent ) {
|
@@ -253,10 +427,15 @@ class HardcodedAssets
|
|
253 |
if ( isset( $matchedTag[0] ) && $matchedTag[0] && strpos( $matchedTag[0], '<script' ) === 0 ) {
|
254 |
$matchedTagOutput = trim( $matchedTag[0] );
|
255 |
|
|
|
|
|
|
|
|
|
|
|
256 |
/*
|
257 |
* Strip certain SCRIPT tags irrelevant for the list (e.g. related to WordPress Customiser, Admin Bar, etc.)
|
258 |
*/
|
259 |
-
if ( in_array(
|
260 |
continue;
|
261 |
}
|
262 |
|
@@ -266,89 +445,173 @@ class HardcodedAssets
|
|
266 |
}
|
267 |
}
|
268 |
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
|
|
|
|
|
|
|
|
273 |
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
preg_match_all( '#type=(["\'])' . '(.*)' . '(["\'])#Usmi', $matchedTagOnlyTags,
|
278 |
-
$outputMatches );
|
279 |
-
$scriptType = isset( $outputMatches[2][0] ) ? trim( $outputMatches[2][0],
|
280 |
-
'"\'' ) : 'text/javascript';
|
281 |
|
282 |
-
|
283 |
-
continue;
|
284 |
-
}
|
285 |
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
continue;
|
295 |
-
}
|
296 |
|
297 |
-
|
298 |
-
|
299 |
-
continue;
|
300 |
-
}
|
301 |
|
302 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
|
304 |
-
|
305 |
-
|
306 |
-
|
|
|
|
|
307 |
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
|
|
|
|
|
|
312 |
|
313 |
-
|
|
|
|
|
|
|
|
|
314 |
|
315 |
-
|
316 |
-
|
|
|
|
|
|
|
317 |
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
$matchedTagOutputInnerCleaner = trim($matchedTagOutputInnerCleaner);
|
323 |
-
}
|
324 |
|
325 |
-
|
326 |
-
|
327 |
-
|
|
|
328 |
|
329 |
-
|
|
|
|
|
330 |
|
331 |
-
|
332 |
-
|
|
|
|
|
333 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
}
|
335 |
-
/*
|
336 |
-
* [END] Collect Hardcoded SCRIPT (src/inline)
|
337 |
-
*/
|
338 |
}
|
339 |
|
340 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
}
|
346 |
|
347 |
-
|
348 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
349 |
}
|
350 |
|
351 |
-
return $
|
352 |
}
|
353 |
|
354 |
/**
|
@@ -425,6 +688,165 @@ class HardcodedAssets
|
|
425 |
return false;
|
426 |
}
|
427 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
428 |
/**
|
429 |
* @param $data
|
430 |
*
|
106 |
'script_src_and_inline_tags' => array(), // SCRIPT (with "src" attribute) & SCRIPT (inline)
|
107 |
);
|
108 |
|
109 |
+
$matchesSourcesFromTags = array();
|
110 |
+
|
111 |
+
$fallbackToRegex = true;
|
112 |
+
|
113 |
+
if ( $collectLinkStyles ) {
|
114 |
+
if ( ! $fallbackToRegex && Misc::isDOMDocumentOn() ) {
|
115 |
+
$domDoc = Misc::initDOMDocument();
|
116 |
+
$domDoc->loadHTML($htmlSourceAlt);
|
117 |
+
|
118 |
+
$selector = new \DOMXPath($domDoc);
|
119 |
+
|
120 |
+
$domTagQuery = $selector->query('//link[@rel="stylesheet"]|//style|//script');
|
121 |
+
|
122 |
+
if (count($domTagQuery) > 1) {
|
123 |
+
foreach($domTagQuery as $tagFound) {
|
124 |
+
$tagType = in_array($tagFound->nodeName, array('link', 'style')) ? 'css' : 'js';
|
125 |
+
|
126 |
+
if (self::skipTagIfNotRelevant(CleanUp::getOuterHTML($tagFound), 'whole_tag', $tagType)) {
|
127 |
+
continue; // no point in wasting more resources as the tag will never be shown, since it's irrelevant
|
128 |
+
}
|
129 |
+
|
130 |
+
if ( $tagFound->hasAttributes() ) {
|
131 |
+
foreach ( $tagFound->attributes as $attr ) {
|
132 |
+
if ( self::skipTagIfNotRelevant( $attr->nodeName, 'attribute', $tagType ) ) {
|
133 |
+
continue 2;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
if ($tagFound->nodeName === 'link') {
|
139 |
+
if ( ! $tagFound->hasAttributes() ) {
|
140 |
+
continue;
|
141 |
+
}
|
142 |
+
|
143 |
+
$linkTagParts = array();
|
144 |
+
$linkTagParts[] = '<link ';
|
145 |
+
|
146 |
+
foreach ($tagFound->attributes as $attr) {
|
147 |
+
$attrName = $attr->nodeName;
|
148 |
+
$attrValue = $attr->nodeValue;
|
149 |
+
|
150 |
+
if ($attrName) {
|
151 |
+
if ($attrValue !== '') {
|
152 |
+
$linkTagParts[] = '(\s+|)' . preg_quote($attrName, '/') . '(\s+|)=(\s+|)(|"|\')' . preg_quote($attrValue, '/') . '(|"|\')(|\s+)';
|
153 |
+
} else {
|
154 |
+
$linkTagParts[] = '(\s+|)' . preg_quote($attrName, '/') . '(|((\s+|)=(\s+|)(|"|\')(|"|\')))';
|
155 |
+
}
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
$linkTagParts[] = '(|\s+)(|/)>';
|
160 |
+
|
161 |
+
$linkTagFinalRegExPart = implode('', $linkTagParts);
|
162 |
+
|
163 |
+
preg_match_all(
|
164 |
+
'#'.$linkTagFinalRegExPart.'#Umi',
|
165 |
+
$htmlSource,
|
166 |
+
$matchSourceFromTag,
|
167 |
+
PREG_SET_ORDER
|
168 |
+
);
|
169 |
+
|
170 |
+
// It always has to be a match from the DOM generated tag
|
171 |
+
// Otherwise, default it to RegEx
|
172 |
+
if ( empty($matchSourceFromTag) || ! (isset($matchSourceFromTag[0][0]) && ! empty($matchSourceFromTag[0][0])) ) {
|
173 |
+
$fallbackToRegex = true;
|
174 |
+
break;
|
175 |
+
}
|
176 |
+
|
177 |
+
$matchesSourcesFromTags[] = array('link_tag' => $matchSourceFromTag[0][0]);
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
if (! $fallbackToRegex) {
|
182 |
+
$shaOneToOriginal = array();
|
183 |
+
|
184 |
+
$htmlSourceAltEncoded = $htmlSourceAlt;
|
185 |
+
|
186 |
+
foreach($domTagQuery as $tagFound) {
|
187 |
+
if ( $tagFound->nodeValue && in_array( $tagFound->nodeName, array( 'style', 'script' ) ) ) {
|
188 |
+
if (strpos($htmlSourceAlt, $tagFound->nodeValue) === false) {
|
189 |
+
$fallbackToRegex = true;
|
190 |
+
break;
|
191 |
+
}
|
192 |
+
|
193 |
+
$shaOneToOriginal[sha1($tagFound->nodeValue)] = $tagFound->nodeValue;
|
194 |
+
|
195 |
+
$htmlSourceAltEncoded = str_replace(
|
196 |
+
$tagFound->nodeValue,
|
197 |
+
'/*[wpacu]*/' . sha1($tagFound->nodeValue) . '/*[/wpacu]*/',
|
198 |
+
$htmlSourceAltEncoded
|
199 |
+
);
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
$domDocForTwo = Misc::initDOMDocument();
|
204 |
+
|
205 |
+
$domDocForTwo->loadHTML($htmlSourceAltEncoded);
|
206 |
+
|
207 |
+
$selectorTwo = new \DOMXPath($domDocForTwo);
|
208 |
+
|
209 |
+
$domTagQueryTwo = $selectorTwo->query('//style|//script');
|
210 |
+
|
211 |
+
foreach($domTagQueryTwo as $tagFoundTwo) {
|
212 |
+
$tagType = in_array($tagFoundTwo->nodeName, array('link', 'style')) ? 'css' : 'js';
|
213 |
+
|
214 |
+
if ( $tagFoundTwo->hasAttributes() ) {
|
215 |
+
foreach ( $tagFoundTwo->attributes as $attr ) {
|
216 |
+
if ( self::skipTagIfNotRelevant( $attr->nodeName, 'attribute', $tagType ) ) {
|
217 |
+
continue 2;
|
218 |
+
}
|
219 |
+
}
|
220 |
+
}
|
221 |
+
|
222 |
+
$tagParts = array();
|
223 |
+
$tagParts[] = '<'.$tagFoundTwo->nodeName;
|
224 |
+
|
225 |
+
foreach ($tagFoundTwo->attributes as $attr) {
|
226 |
+
$attrName = $attr->nodeName;
|
227 |
+
$attrValue = $attr->nodeValue;
|
228 |
+
|
229 |
+
if ($attrName) {
|
230 |
+
if ($attrValue !== '') {
|
231 |
+
$tagParts[] = '(\s+|)' . preg_quote($attrName, '/') . '(\s+|)=(\s+|)(|"|\')' . preg_quote($attrValue, '/') . '(|"|\')(|\s+)';
|
232 |
+
} else {
|
233 |
+
$tagParts[] = '(\s+|)' . preg_quote($attrName, '/') . '(|((\s+|)=(\s+|)(|"|\')(|"|\')))';
|
234 |
+
}
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
$tagParts[] = '(|\s+)>';
|
239 |
+
|
240 |
+
if ($tagFoundTwo->nodeValue) {
|
241 |
+
$tagParts[] = preg_quote($tagFoundTwo->nodeValue, '/');
|
242 |
+
}
|
243 |
+
|
244 |
+
$tagParts[] = '</'.$tagFoundTwo->nodeName.'>';
|
245 |
+
|
246 |
+
$tagFinalRegExPart = implode('', $tagParts);
|
247 |
+
|
248 |
+
preg_match_all(
|
249 |
+
'#'.$tagFinalRegExPart.'#Umi',
|
250 |
+
$htmlSourceAltEncoded,
|
251 |
+
$matchSourceFromTagTwo,
|
252 |
+
PREG_SET_ORDER
|
253 |
+
);
|
254 |
+
|
255 |
+
// It always has to be a match from the DOM generated tag
|
256 |
+
// Otherwise, default it to RegEx
|
257 |
+
if ( empty($matchSourceFromTagTwo) || ! (isset($matchSourceFromTagTwo[0][0]) && ! empty($matchSourceFromTagTwo[0][0])) ) {
|
258 |
+
$fallbackToRegex = true;
|
259 |
+
break;
|
260 |
+
}
|
261 |
+
|
262 |
+
$encodedNodeValue = Misc::extractBetween($matchSourceFromTagTwo[0][0], '/*[wpacu]*/', '/*[/wpacu]*/');
|
263 |
+
|
264 |
+
$matchedTag = str_replace('/*[wpacu]*/'.$encodedNodeValue.'/*[/wpacu]*/', $shaOneToOriginal[$encodedNodeValue], $matchSourceFromTagTwo[0][0]);
|
265 |
+
|
266 |
+
$tagTypeForReference = ($tagFoundTwo->nodeName === 'style') ? 'style_tag' : 'script_tag';
|
267 |
+
|
268 |
+
$matchesSourcesFromTags[] = array($tagTypeForReference => $matchedTag);
|
269 |
+
}
|
270 |
+
}
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
/*
|
275 |
* [START] Collect Hardcoded LINK (stylesheet) & STYLE tags
|
276 |
*/
|
277 |
+
if ($fallbackToRegex || ! Misc::isDOMDocumentOn()) {
|
278 |
+
preg_match_all(
|
279 |
+
'#(?=(?P<link_tag><link[^>]*stylesheet[^>]*(>)))|(?=(?P<style_tag><style[^>]*?>.*</style>))#Umsi',
|
280 |
+
$htmlSourceAlt,
|
281 |
+
$matchesSourcesFromTags,
|
282 |
+
PREG_SET_ORDER
|
283 |
+
);
|
284 |
+
}
|
285 |
|
286 |
if ( ! empty( $matchesSourcesFromTags ) ) {
|
287 |
// Only the hashes are set
|
307 |
if ( isset( $matchedTag['link_tag'] ) && trim( $matchedTag['link_tag'] ) !== '' && ( trim( strip_tags( $matchedTag['link_tag'] ) ) === '' ) ) {
|
308 |
$matchedTagOutput = trim( $matchedTag['link_tag'] );
|
309 |
|
310 |
+
// Own plugin assets and enqueued ones since they aren't hardcoded
|
311 |
+
if (self::skipTagIfNotRelevant($matchedTagOutput)) {
|
312 |
continue;
|
313 |
}
|
314 |
|
322 |
/*
|
323 |
* Strip certain STYLE tags irrelevant for the list (e.g. related to the WordPress Admin Bar, etc.)
|
324 |
*/
|
325 |
+
if ( in_array( self::determineHardcodedAssetSha1( $matchedTagOutput ), $stripsSpecificStylesHashes ) ) {
|
326 |
continue;
|
327 |
}
|
328 |
|
332 |
}
|
333 |
}
|
334 |
|
335 |
+
// Own plugin assets and enqueued ones since they aren't hardcoded
|
336 |
+
if (self::skipTagIfNotRelevant($matchedTagOutput)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
337 |
continue;
|
338 |
}
|
339 |
|
358 |
/*
|
359 |
* [START] Collect Hardcoded SCRIPT (src/inline)
|
360 |
*/
|
361 |
+
if ($fallbackToRegex || ! Misc::isDOMDocumentOn()) {
|
362 |
+
preg_match_all( '@<script[^>]*?>.*?</script>@si', $htmlSourceAlt, $matchesScriptTags, PREG_SET_ORDER );
|
363 |
+
} else {
|
364 |
+
$matchesScriptTags = array();
|
365 |
+
|
366 |
+
if (! empty($matchesSourcesFromTags)) {
|
367 |
+
foreach ($matchesSourcesFromTags as $matchedTag) {
|
368 |
+
if (isset($matchedTag['script_tag']) && $matchedTag['script_tag']) {
|
369 |
+
$matchesScriptTags[][0] = $matchedTag['script_tag'];
|
370 |
+
}
|
371 |
+
}
|
372 |
+
}
|
373 |
+
}
|
374 |
|
375 |
+
$allInlineAssocWithJsHandle = array();
|
|
|
376 |
|
377 |
+
if ( isset( wp_scripts()->done ) && ! empty( wp_scripts()->done ) ) {
|
378 |
foreach ( wp_scripts()->done as $assetHandle ) {
|
379 |
// Now, go through the list of inline SCRIPTs associated with an enqueued SCRIPT (with "src" attribute)
|
380 |
+
// And make sure they do not show to the hardcoded list, since they are related to the handle, and they are stripped when the handle is dequeued
|
381 |
$anyInlineAssocWithJsHandle = OptimizeJs::getInlineAssociatedWithScriptHandle( $assetHandle, wp_scripts()->registered, 'handle' );
|
382 |
if ( ! empty( $anyInlineAssocWithJsHandle ) ) {
|
383 |
foreach ( $anyInlineAssocWithJsHandle as $jsInlineTagContent ) {
|
427 |
if ( isset( $matchedTag[0] ) && $matchedTag[0] && strpos( $matchedTag[0], '<script' ) === 0 ) {
|
428 |
$matchedTagOutput = trim( $matchedTag[0] );
|
429 |
|
430 |
+
// Own plugin assets and enqueued ones since they aren't hardcoded
|
431 |
+
if (self::skipTagIfNotRelevant($matchedTagOutput, 'whole_tag', 'js', array('all_inline_assoc_with_js_handle' => $allInlineAssocWithJsHandle))) {
|
432 |
+
continue;
|
433 |
+
}
|
434 |
+
|
435 |
/*
|
436 |
* Strip certain SCRIPT tags irrelevant for the list (e.g. related to WordPress Customiser, Admin Bar, etc.)
|
437 |
*/
|
438 |
+
if ( in_array( self::determineHardcodedAssetSha1( $matchedTagOutput ), $stripsSpecificScriptsHashes ) ) {
|
439 |
continue;
|
440 |
}
|
441 |
|
445 |
}
|
446 |
}
|
447 |
|
448 |
+
$hardCodedAssets['script_src_and_inline_tags'][] = trim( $matchedTag[0] );
|
449 |
+
}
|
450 |
+
}
|
451 |
+
}
|
452 |
+
/*
|
453 |
+
* [END] Collect Hardcoded SCRIPT (src/inline)
|
454 |
+
*/
|
455 |
+
}
|
456 |
|
457 |
+
if ($fallbackToRegex && ! empty($hardCodedAssets['link_and_style_tags']) && ! empty($hardCodedAssets['script_src_and_inline_tags'])) {
|
458 |
+
$hardCodedAssets = self::removeAnyLinkTagsThatMightBeDetectedWithinScriptTags( $hardCodedAssets );
|
459 |
+
}
|
|
|
|
|
|
|
|
|
460 |
|
461 |
+
$tagsWithinConditionalComments = self::extractHtmlFromConditionalComments( $htmlSourceAlt );
|
|
|
|
|
462 |
|
463 |
+
if (Main::instance()->isGetAssetsCall) {
|
464 |
+
// AJAX call within the Dashboard
|
465 |
+
$hardCodedAssets['within_conditional_comments'] = $tagsWithinConditionalComments;
|
466 |
+
}
|
467 |
|
468 |
+
if ($encodeIt) {
|
469 |
+
return base64_encode( wp_json_encode( $hardCodedAssets ) );
|
470 |
+
}
|
|
|
|
|
471 |
|
472 |
+
return $hardCodedAssets;
|
473 |
+
}
|
|
|
|
|
474 |
|
475 |
+
/**
|
476 |
+
* @param $value
|
477 |
+
* @param $via ('whole_tag', 'attribute')
|
478 |
+
* @param string $type ('css', 'js')
|
479 |
+
* @param array $extras ('all_inline_assoc_with_js_handle')
|
480 |
+
*
|
481 |
+
* @return bool
|
482 |
+
*/
|
483 |
+
public static function skipTagIfNotRelevant($value, $via = 'whole_tag', $type = 'css', $extras = array())
|
484 |
+
{
|
485 |
+
if ($via === 'whole_tag') {
|
486 |
+
if ($type === 'css') {
|
487 |
+
if ( strpos( $value, 'data-wpacu-style-handle=' ) !== false ) {
|
488 |
+
// skip the SCRIPT with src that was enqueued properly and keep the hardcoded ones
|
489 |
+
return true;
|
490 |
+
}
|
491 |
|
492 |
+
if ( ( strpos( $value, 'data-wpacu-own-inline-style=' ) !== false ) ||
|
493 |
+
( strpos( $value, 'data-wpacu-inline-css-file=' ) !== false ) ) {
|
494 |
+
// remove plugin's own STYLE tags as they are not relevant in this context
|
495 |
+
return true;
|
496 |
+
}
|
497 |
|
498 |
+
// Do not add to the list elements such as Emojis (not relevant for hard-coded tags)
|
499 |
+
if ( strpos( $value, 'img.wp-smiley' ) !== false
|
500 |
+
&& strpos( $value, 'img.emoji' ) !== false
|
501 |
+
&& strpos( $value, '!important;' ) !== false ) {
|
502 |
+
return true;
|
503 |
+
}
|
504 |
+
}
|
505 |
|
506 |
+
if ($type === 'js') {
|
507 |
+
if ( strpos( $value, 'data-wpacu-script-handle=' ) !== false ) {
|
508 |
+
// skip the SCRIPT with src that was enqueued properly and keep the hardcoded ones
|
509 |
+
return true;
|
510 |
+
}
|
511 |
|
512 |
+
if ( ( strpos( $value, 'data-wpacu-own-inline-script=' ) !== false ) ||
|
513 |
+
( strpos( $value, 'data-wpacu-inline-js-file=' ) !== false ) ) {
|
514 |
+
// skip plugin's own SCRIPT tags as they are not relevant in this context
|
515 |
+
return true;
|
516 |
+
}
|
517 |
|
518 |
+
if ( strpos( $value, 'wpacu-preload-async-css-fallback' ) !== false ) {
|
519 |
+
// skip plugin's own SCRIPT tags as they are not relevant in this context
|
520 |
+
return true;
|
521 |
+
}
|
|
|
|
|
522 |
|
523 |
+
if ( strpos( $value, 'window._wpemojiSettings' ) !== false
|
524 |
+
&& strpos( $value, 'twemoji' ) !== false ) {
|
525 |
+
return true;
|
526 |
+
}
|
527 |
|
528 |
+
// Check the type and only allow SCRIPT tags with type='text/javascript' or no type at all (it will default to 'text/javascript')
|
529 |
+
$matchedTagInner = strip_tags( $value );
|
530 |
+
$matchedTagOnlyTags = str_replace( $matchedTagInner, '', $value );
|
531 |
|
532 |
+
$scriptType = Misc::getValueFromTag($matchedTagOnlyTags, 'type') ?: 'text/javascript';
|
533 |
+
|
534 |
+
if ( strpos( $scriptType, 'text/javascript' ) === false ) {
|
535 |
+
return true;
|
536 |
}
|
537 |
+
|
538 |
+
$allInlineAssocWithJsHandle = isset($extras['all_inline_assoc_with_js_handle']) ? $extras['all_inline_assoc_with_js_handle'] : array();
|
539 |
+
|
540 |
+
$hasSrc = false;
|
541 |
+
|
542 |
+
if (strpos($matchedTagOnlyTags, ' src=') !== false) {
|
543 |
+
$hasSrc = true;
|
544 |
+
}
|
545 |
+
|
546 |
+
if ( ! $hasSrc && ! empty( $allInlineAssocWithJsHandle ) ) {
|
547 |
+
preg_match_all("'<script[^>]*?>(.*?)</script>'si", $value, $matchesFromTagOutput);
|
548 |
+
$matchedTagOutputInner = isset($matchesFromTagOutput[1][0]) && trim($matchesFromTagOutput[1][0])
|
549 |
+
? trim($matchesFromTagOutput[1][0]) : false;
|
550 |
+
|
551 |
+
$matchedTagOutputInnerCleaner = $matchedTagOutputInner;
|
552 |
+
|
553 |
+
$stripStrStart = '/* <![CDATA[ */';
|
554 |
+
$stripStrEnd = '/* ]]> */';
|
555 |
+
|
556 |
+
if (strpos($matchedTagOutputInnerCleaner, $stripStrStart) === 0
|
557 |
+
&& Misc::endsWith($matchedTagOutputInnerCleaner, '/* ]]> */')) {
|
558 |
+
$matchedTagOutputInnerCleaner = substr($matchedTagOutputInnerCleaner, strlen($stripStrStart));
|
559 |
+
$matchedTagOutputInnerCleaner = substr($matchedTagOutputInnerCleaner, 0, -strlen($stripStrEnd));
|
560 |
+
$matchedTagOutputInnerCleaner = trim($matchedTagOutputInnerCleaner);
|
561 |
+
}
|
562 |
+
|
563 |
+
if (in_array($matchedTagOutputInnerCleaner, $allInlineAssocWithJsHandle)) {
|
564 |
+
return true;
|
565 |
+
}
|
566 |
+
|
567 |
+
}
|
568 |
}
|
|
|
|
|
|
|
569 |
}
|
570 |
|
571 |
+
if ($via === 'attribute') {
|
572 |
+
if ( $type === 'css' ) {
|
573 |
+
$possibleSignatures = array(
|
574 |
+
'data-wpacu-style-handle',
|
575 |
+
'data-wpacu-own-inline-style',
|
576 |
+
'data-wpacu-inline-css-file'
|
577 |
+
);
|
578 |
+
} else {
|
579 |
+
$possibleSignatures = array(
|
580 |
+
'data-wpacu-script-handle',
|
581 |
+
'data-wpacu-own-inline-script',
|
582 |
+
'data-wpacu-inline-js-file',
|
583 |
+
'wpacu-preload-async-css-fallback'
|
584 |
+
);
|
585 |
+
}
|
586 |
|
587 |
+
if (in_array($value, $possibleSignatures)) {
|
588 |
+
return true;
|
589 |
+
}
|
590 |
}
|
591 |
|
592 |
+
return false; // default
|
593 |
+
}
|
594 |
+
|
595 |
+
/**
|
596 |
+
*
|
597 |
+
* @param $hardcodedAssets
|
598 |
+
*
|
599 |
+
* @return mixed
|
600 |
+
*/
|
601 |
+
public static function removeAnyLinkTagsThatMightBeDetectedWithinScriptTags($hardcodedAssets)
|
602 |
+
{
|
603 |
+
foreach ($hardcodedAssets['link_and_style_tags'] as $cssTagIndex => $cssTag) {
|
604 |
+
if ($cssTag) {
|
605 |
+
foreach ($hardcodedAssets['script_src_and_inline_tags'] as $scriptTag) {
|
606 |
+
if (strpos($scriptTag, $cssTag) !== false) {
|
607 |
+
// e.g. could be '<script>var linkToCss="<link href='[path_to_custom_css_file_here]'>";</script>'
|
608 |
+
unset($hardcodedAssets['link_and_style_tags'][$cssTagIndex]);
|
609 |
+
}
|
610 |
+
}
|
611 |
+
}
|
612 |
}
|
613 |
|
614 |
+
return $hardcodedAssets;
|
615 |
}
|
616 |
|
617 |
/**
|
688 |
return false;
|
689 |
}
|
690 |
|
691 |
+
/**
|
692 |
+
* @param $tagOutput
|
693 |
+
*
|
694 |
+
* @return string
|
695 |
+
*/
|
696 |
+
public static function determineHardcodedAssetSha1($tagOutput)
|
697 |
+
{
|
698 |
+
// Look if the "href" or "src" ends with '.css' or '.js'
|
699 |
+
// Only hash the actual path to the file
|
700 |
+
// In case the tag changes (e.g. an attribute will be added), the tag will be considered the same for the plugin rules
|
701 |
+
// To avoid the rules from not working / e.g. the file could have a dynamic "?ver=" at the end
|
702 |
+
if ( ! (stripos($tagOutput, '<link') !== false || stripos($tagOutput, '<style') !== false || stripos($tagOutput, '<script') !== false) ) {
|
703 |
+
return sha1( $tagOutput ); // default
|
704 |
+
}
|
705 |
+
|
706 |
+
$isLinkWithHref = (stripos($tagOutput, '<link') !== false) && preg_match('#href(\s+|)=(\s+|)(["\'])(.*)(["\'])#Usmi', $tagOutput);
|
707 |
+
$isScriptWithSrc = (stripos($tagOutput, '<script') !== false) && preg_match('#src(\s+|)=(\s+|)(["\'])(.*)(["\'])|src(\s+|)=(\s+|)(.*)(\s+)#Usmi', $tagOutput);
|
708 |
+
|
709 |
+
if ($isLinkWithHref || $isScriptWithSrc) {
|
710 |
+
return self::determineHardcodedAssetSha1ForAssetsWithSource($tagOutput);
|
711 |
+
}
|
712 |
+
|
713 |
+
if (stripos($tagOutput, '<style') !== false || stripos($tagOutput, '<script') !== false) {
|
714 |
+
return self::determineHardcodedAssetSha1ForAssetsWithoutSource($tagOutput);
|
715 |
+
}
|
716 |
+
|
717 |
+
return sha1( $tagOutput ); // default
|
718 |
+
}
|
719 |
+
|
720 |
+
/**
|
721 |
+
// In case there are STYLE tags and SCRIPT tags without any SRC, make sure to consider only the content of the tag as a reference
|
722 |
+
// e.g. if the user updates <style type="text/css"> to <style> the tag should be considered the same if the content is the same
|
723 |
+
// also, do not consider any whitespaces from the beginning and ending of the tag's content
|
724 |
+
*
|
725 |
+
* @param $tagOutput
|
726 |
+
*
|
727 |
+
* @return string
|
728 |
+
*/
|
729 |
+
public static function determineHardcodedAssetSha1ForAssetsWithoutSource($tagOutput)
|
730 |
+
{
|
731 |
+
if (stripos($tagOutput, '<style') !== false) {
|
732 |
+
preg_match_all('@(<style[^>]*?>)(.*?)</style>@si', $tagOutput, $matches);
|
733 |
+
|
734 |
+
if (isset($matches[0][0], $matches[2][0]) && strlen($tagOutput) === strlen($matches[0][0])) {
|
735 |
+
return sha1( trim($matches[2][0]) ); // the hashed content of the tag
|
736 |
+
}
|
737 |
+
}
|
738 |
+
|
739 |
+
if (stripos($tagOutput, '<script') !== false) {
|
740 |
+
preg_match_all('@(<script[^>]*?>)(.*?)</script>@si', $tagOutput, $matches);
|
741 |
+
|
742 |
+
if (isset($matches[0][0], $matches[2][0]) && strlen($tagOutput) === strlen($matches[0][0])) {
|
743 |
+
return sha1( trim($matches[2][0]) ); // the hashed content of the tag
|
744 |
+
}
|
745 |
+
}
|
746 |
+
|
747 |
+
return sha1($tagOutput);
|
748 |
+
}
|
749 |
+
|
750 |
+
/**
|
751 |
+
* Only the LINK tags and SCRIPT tags with the "href" and "src" attributes would be considered
|
752 |
+
*
|
753 |
+
* @param $tagOutput
|
754 |
+
*
|
755 |
+
* @return string
|
756 |
+
*/
|
757 |
+
public static function determineHardcodedAssetSha1ForAssetsWithSource($tagOutput)
|
758 |
+
{
|
759 |
+
if ($finalCleanSource = self::getRelSourceFromTagOutputForReference($tagOutput)) {
|
760 |
+
return sha1($finalCleanSource);
|
761 |
+
}
|
762 |
+
|
763 |
+
return sha1( $tagOutput ); // default
|
764 |
+
}
|
765 |
+
|
766 |
+
/**
|
767 |
+
* @param $tagOutput
|
768 |
+
*
|
769 |
+
* @return array|false|string|string[]
|
770 |
+
*/
|
771 |
+
public static function getRelSourceFromTagOutputForReference($tagOutput)
|
772 |
+
{
|
773 |
+
$sourceValue = false;
|
774 |
+
|
775 |
+
if ( Misc::isDOMDocumentOn() ) {
|
776 |
+
$domDoc = Misc::initDOMDocument();
|
777 |
+
$domDoc->loadHTML( $tagOutput );
|
778 |
+
|
779 |
+
$selector = new \DOMXPath( $domDoc );
|
780 |
+
|
781 |
+
$domTagQuery = $selector->query( '//link[@rel="stylesheet"]|//script[@src]' );
|
782 |
+
$tagFound = isset( $domTagQuery[0] ) ? $domTagQuery[0] : false;
|
783 |
+
|
784 |
+
if ( ! $tagFound ) {
|
785 |
+
return false; // default
|
786 |
+
}
|
787 |
+
|
788 |
+
if ( ! in_array( $tagFound->nodeName, array( 'link', 'script' ) ) ) {
|
789 |
+
return false; // default
|
790 |
+
}
|
791 |
+
|
792 |
+
$attrToCheck = $tagFound->nodeName === 'link' ? 'href' : 'src';
|
793 |
+
$extToCheck = $tagFound->nodeName === 'link' ? 'css' : 'js';
|
794 |
+
|
795 |
+
foreach ( $tagFound->attributes as $attr ) {
|
796 |
+
if ( $attr->nodeName === $attrToCheck ) {
|
797 |
+
$sourceValue = trim( $attr->nodeValue );
|
798 |
+
break; // "href" or "src" was found, stop here
|
799 |
+
}
|
800 |
+
}
|
801 |
+
} else {
|
802 |
+
// RegEx Fallback
|
803 |
+
preg_match_all(
|
804 |
+
'#(?=(?P<link_tag><link[^>]*stylesheet[^>]*(>)))|(?=(?P<script_tag><script[^>]*?>.*</script>))#Umsi',
|
805 |
+
$tagOutput,
|
806 |
+
$matchedTag,
|
807 |
+
PREG_SET_ORDER
|
808 |
+
);
|
809 |
+
|
810 |
+
if ( ! ( isset( $matchedTag[0]['link_tag'] ) || isset( $matchedTag[0]['script_tag'] ) ) ) {
|
811 |
+
return false; // default
|
812 |
+
}
|
813 |
+
|
814 |
+
$attrToCheck = ( isset( $matchedTag[0]['link_tag'] ) && $matchedTag[0]['link_tag'] ) ? 'href' : 'src';
|
815 |
+
$extToCheck = ( isset( $matchedTag[0]['link_tag'] ) && $matchedTag[0]['link_tag'] ) ? 'css' : 'js';
|
816 |
+
|
817 |
+
$sourceValue = Misc::getValueFromTag($tagOutput, $attrToCheck);
|
818 |
+
|
819 |
+
}
|
820 |
+
|
821 |
+
if ( $sourceValue ) {
|
822 |
+
if ( stripos( $sourceValue, '.' . $extToCheck . '?' ) !== false ) {
|
823 |
+
list( $cleanSource ) = explode( '.' . $extToCheck . '?', $sourceValue );
|
824 |
+
$finalCleanSource = $cleanSource . '.' . $extToCheck;
|
825 |
+
} else {
|
826 |
+
$finalCleanSource = $sourceValue;
|
827 |
+
}
|
828 |
+
|
829 |
+
if ( $finalCleanSource ) {
|
830 |
+
$localAssetPath = OptimizeCommon::getLocalAssetPath( $finalCleanSource, $extToCheck );
|
831 |
+
|
832 |
+
if ( $localAssetPath ) {
|
833 |
+
$sourceRelPath = OptimizeCommon::getSourceRelPath( $finalCleanSource );
|
834 |
+
|
835 |
+
if ( $sourceRelPath ) {
|
836 |
+
return $finalCleanSource;
|
837 |
+
}
|
838 |
+
} else {
|
839 |
+
$finalCleanSource = str_ireplace( array( 'http://', 'https://' ), '', $finalCleanSource );
|
840 |
+
$finalCleanSource = ( strpos( $finalCleanSource, '//' ) === 0 ) ? substr( $finalCleanSource, 2 ) : $finalCleanSource; // if the string starts with '//', remove it
|
841 |
+
}
|
842 |
+
}
|
843 |
+
|
844 |
+
return $finalCleanSource;
|
845 |
+
}
|
846 |
+
|
847 |
+
return false;
|
848 |
+
}
|
849 |
+
|
850 |
/**
|
851 |
* @param $data
|
852 |
*
|
classes/Main.php
CHANGED
@@ -3,6 +3,7 @@ namespace WpAssetCleanUp;
|
|
3 |
|
4 |
use WpAssetCleanUp\OptimiseAssets\CombineJs;
|
5 |
use WpAssetCleanUp\OptimiseAssets\DynamicLoadedAssets;
|
|
|
6 |
|
7 |
/**
|
8 |
* Class Main
|
@@ -259,7 +260,7 @@ class Main
|
|
259 |
$noRocketInit = true;
|
260 |
|
261 |
if (strpos($currentTheme, 'uncode') !== false) {
|
262 |
-
$noRocketInit = false; // make exception for the "Uncode" Theme as it doesn't check if get_rocket_option() function exists
|
263 |
}
|
264 |
|
265 |
if ($noRocketInit) {
|
@@ -882,10 +883,8 @@ SQL;
|
|
882 |
// These are LITE rules
|
883 |
$list = ( ! empty($list) ) ? $this->filterAssetsUnloadList($list, 'styles','load_exception') : $list;
|
884 |
|
885 |
-
//
|
886 |
-
// These are PRO rules or rules added via custom coding
|
887 |
$list = ( ! empty($list) ) ? apply_filters('wpacu_filter_styles_list_load_exception', $list) : $list;
|
888 |
-
// [/wpacu_pro]
|
889 |
/*
|
890 |
* [END] Load Exception Check
|
891 |
* */
|
@@ -1234,7 +1233,7 @@ SQL;
|
|
1234 |
wp_dequeue_script($handle);
|
1235 |
}
|
1236 |
|
1237 |
-
|
1238 |
}
|
1239 |
|
1240 |
if (isset($ignoreChildParentList['scripts'], $this->wpAllScripts['registered'][$handle]->src) && is_array($ignoreChildParentList['scripts']) && array_key_exists($handle, $ignoreChildParentList['scripts'])) {
|
@@ -1445,7 +1444,7 @@ SQL;
|
|
1445 |
*
|
1446 |
* @param $postType
|
1447 |
*
|
1448 |
-
* @return \array[][]
|
1449 |
*/
|
1450 |
public function getLoadExceptionsPostType($postType)
|
1451 |
{
|
@@ -2308,7 +2307,7 @@ SQL;
|
|
2308 |
// EITHER the enqueued or hardcoded list of assets HAS TO BE RETRIEVED
|
2309 |
// Print out the 'error' response to make the user aware about it
|
2310 |
if ( ! ($wpacuListE || $wpacuListH) ) {
|
2311 |
-
// 'body' is set and it's not an array
|
2312 |
if ( is_wp_error($wpRemotePost) ) {
|
2313 |
$wpRemotePost['response']['message'] = $wpRemotePost->get_error_message();
|
2314 |
} elseif ( isset( $wpRemotePost['body']) ) {
|
@@ -2946,7 +2945,7 @@ SQL;
|
|
2946 |
}
|
2947 |
|
2948 |
// External file? Use a different approach
|
2949 |
-
// Return
|
2950 |
$isExternalFile = (! $isRelInternalPath &&
|
2951 |
(! (isset($obj->wp) && $obj->wp === 1))
|
2952 |
&& strpos($src, $siteUrl) !== 0);
|
@@ -2961,32 +2960,46 @@ SQL;
|
|
2961 |
'<span style="display: none;"><img style="width: 20px; height: 20px;" alt="" align="top" width="20" height="20" src="'.includes_url('images/spinner-2x.gif').'"></span>';
|
2962 |
}
|
2963 |
|
2964 |
-
|
2965 |
-
if (strpos($obj->src, $siteUrl) !== false) {
|
2966 |
-
// Local Plugin / Theme File
|
2967 |
-
// Could be a Staging site that is having the Live URL in the General Settings
|
2968 |
-
$src = ltrim(str_replace($siteUrl, '', $obj->src), '/');
|
2969 |
-
} elseif ((isset($obj->wp) && $obj->wp === 1) || $isRelInternalPath) {
|
2970 |
-
// Local WordPress Core File
|
2971 |
-
$src = ltrim($obj->src, '/');
|
2972 |
-
}
|
2973 |
|
2974 |
-
|
|
|
|
|
|
|
|
|
2975 |
|
2976 |
-
|
2977 |
-
|
2978 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2979 |
|
2980 |
-
|
2981 |
|
2982 |
-
|
2983 |
-
|
2984 |
-
|
|
|
|
|
2985 |
|
2986 |
-
|
2987 |
-
|
2988 |
-
|
2989 |
-
|
|
|
|
|
|
|
|
|
|
|
2990 |
}
|
2991 |
}
|
2992 |
|
3 |
|
4 |
use WpAssetCleanUp\OptimiseAssets\CombineJs;
|
5 |
use WpAssetCleanUp\OptimiseAssets\DynamicLoadedAssets;
|
6 |
+
use WpAssetCleanUp\OptimiseAssets\OptimizeCommon;
|
7 |
|
8 |
/**
|
9 |
* Class Main
|
260 |
$noRocketInit = true;
|
261 |
|
262 |
if (strpos($currentTheme, 'uncode') !== false) {
|
263 |
+
$noRocketInit = false; // make exception for the "Uncode" Theme as it doesn't check if the get_rocket_option() function exists
|
264 |
}
|
265 |
|
266 |
if ($noRocketInit) {
|
883 |
// These are LITE rules
|
884 |
$list = ( ! empty($list) ) ? $this->filterAssetsUnloadList($list, 'styles','load_exception') : $list;
|
885 |
|
886 |
+
// These are PRO rules or rules added via custom coding
|
|
|
887 |
$list = ( ! empty($list) ) ? apply_filters('wpacu_filter_styles_list_load_exception', $list) : $list;
|
|
|
888 |
/*
|
889 |
* [END] Load Exception Check
|
890 |
* */
|
1233 |
wp_dequeue_script($handle);
|
1234 |
}
|
1235 |
|
1236 |
+
continue;
|
1237 |
}
|
1238 |
|
1239 |
if (isset($ignoreChildParentList['scripts'], $this->wpAllScripts['registered'][$handle]->src) && is_array($ignoreChildParentList['scripts']) && array_key_exists($handle, $ignoreChildParentList['scripts'])) {
|
1444 |
*
|
1445 |
* @param $postType
|
1446 |
*
|
1447 |
+
* @return \array[][]
|
1448 |
*/
|
1449 |
public function getLoadExceptionsPostType($postType)
|
1450 |
{
|
2307 |
// EITHER the enqueued or hardcoded list of assets HAS TO BE RETRIEVED
|
2308 |
// Print out the 'error' response to make the user aware about it
|
2309 |
if ( ! ($wpacuListE || $wpacuListH) ) {
|
2310 |
+
// 'body' is set, and it's not an array
|
2311 |
if ( is_wp_error($wpRemotePost) ) {
|
2312 |
$wpRemotePost['response']['message'] = $wpRemotePost->get_error_message();
|
2313 |
} elseif ( isset( $wpRemotePost['body']) ) {
|
2945 |
}
|
2946 |
|
2947 |
// External file? Use a different approach
|
2948 |
+
// Return an HTML code that will be parsed via AJAX through JavaScript
|
2949 |
$isExternalFile = (! $isRelInternalPath &&
|
2950 |
(! (isset($obj->wp) && $obj->wp === 1))
|
2951 |
&& strpos($src, $siteUrl) !== 0);
|
2960 |
'<span style="display: none;"><img style="width: 20px; height: 20px;" alt="" align="top" width="20" height="20" src="'.includes_url('images/spinner-2x.gif').'"></span>';
|
2961 |
}
|
2962 |
|
2963 |
+
$forAssetType = $pathToFile = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2964 |
|
2965 |
+
if ( stripos( $src, '.css' ) !== false ) {
|
2966 |
+
$forAssetType = 'css';
|
2967 |
+
} elseif ( stripos( $src, '.js' ) !== false ) {
|
2968 |
+
$forAssetType = 'js';
|
2969 |
+
}
|
2970 |
|
2971 |
+
if ($forAssetType) {
|
2972 |
+
$pathToFile = OptimizeCommon::getLocalAssetPath( $src, $forAssetType );
|
2973 |
+
}
|
2974 |
+
|
2975 |
+
if ( ! is_file($pathToFile) ) { // Fallback, old code...
|
2976 |
+
// Local file? Core or from a plugin / theme?
|
2977 |
+
if ( strpos( $obj->src, $siteUrl ) !== false ) {
|
2978 |
+
// Local Plugin / Theme File
|
2979 |
+
// Could be a Staging site that is having the Live URL in the General Settings
|
2980 |
+
$src = ltrim( str_replace( $siteUrl, '', $obj->src ), '/' );
|
2981 |
+
} elseif ( ( isset( $obj->wp ) && $obj->wp === 1 ) || $isRelInternalPath ) {
|
2982 |
+
// Local WordPress Core File
|
2983 |
+
$src = ltrim( $obj->src, '/' );
|
2984 |
+
}
|
2985 |
|
2986 |
+
$srcAlt = $src;
|
2987 |
|
2988 |
+
if ( strpos( $src, '../' ) === 0 ) {
|
2989 |
+
$srcAlt = str_replace( '../', '', $srcAlt );
|
2990 |
+
}
|
2991 |
+
|
2992 |
+
$pathToFile = Misc::getWpRootDirPath() . $srcAlt;
|
2993 |
|
2994 |
+
if ( strpos( $pathToFile, '?ver' ) !== false ) {
|
2995 |
+
list( $pathToFile ) = explode( '?ver', $pathToFile );
|
2996 |
+
}
|
2997 |
+
|
2998 |
+
// It can happen that the CSS/JS has extra parameters (rare cases)
|
2999 |
+
foreach ( array( '.css?', '.js?' ) as $needlePart ) {
|
3000 |
+
if ( strpos( $pathToFile, $needlePart ) !== false ) {
|
3001 |
+
list( $pathToFile ) = explode( '?', $pathToFile );
|
3002 |
+
}
|
3003 |
}
|
3004 |
}
|
3005 |
|
classes/Menu.php
CHANGED
@@ -254,7 +254,7 @@ class Menu
|
|
254 |
), $url
|
255 |
);
|
256 |
|
257 |
-
// Only show it to the user that has "administrator" access and it's in the following list (if a certain list of admins is provided)
|
258 |
// "Settings" -> "Plugin Usage Preferences" -> "Allow managing assets to:"
|
259 |
if (self::userCanManageAssets() && Main::currentUserCanViewAssetsList()) {
|
260 |
/*
|
254 |
), $url
|
255 |
);
|
256 |
|
257 |
+
// Only show it to the user that has "administrator" access, and it's in the following list (if a certain list of admins is provided)
|
258 |
// "Settings" -> "Plugin Usage Preferences" -> "Allow managing assets to:"
|
259 |
if (self::userCanManageAssets() && Main::currentUserCanViewAssetsList()) {
|
260 |
/*
|
classes/MetaBoxes.php
CHANGED
@@ -235,7 +235,7 @@ class MetaBoxes
|
|
235 |
$metaPageOptionsJson = get_post_meta( $postId, '_' . WPACU_PLUGIN_ID . '_page_options', true );
|
236 |
return @json_decode( $metaPageOptionsJson, ARRAY_A );
|
237 |
}
|
238 |
-
} elseif ($type === 'front_page') { // e.g. latest posts, not a chosen page ID (that's when $type as 'post' is used)
|
239 |
$globalPageOptions = get_option(WPACU_PLUGIN_ID . '_global_data');
|
240 |
|
241 |
if ($globalPageOptions) {
|
235 |
$metaPageOptionsJson = get_post_meta( $postId, '_' . WPACU_PLUGIN_ID . '_page_options', true );
|
236 |
return @json_decode( $metaPageOptionsJson, ARRAY_A );
|
237 |
}
|
238 |
+
} elseif ($type === 'front_page') { // e.g. the latest posts, not a chosen page ID (that's when $type as 'post' is used)
|
239 |
$globalPageOptions = get_option(WPACU_PLUGIN_ID . '_global_data');
|
240 |
|
241 |
if ($globalPageOptions) {
|
classes/Misc.php
CHANGED
@@ -192,7 +192,7 @@ class Misc
|
|
192 |
/**
|
193 |
* @param $postId
|
194 |
*
|
195 |
-
* @return
|
196 |
*/
|
197 |
public static function getPageUri($postId)
|
198 |
{
|
@@ -517,7 +517,7 @@ class Misc
|
|
517 |
*/
|
518 |
public static function assetFromHrefToRelativeUri($src, $assetKey)
|
519 |
{
|
520 |
-
// Make the "src" relative in case the information will be imported from Staging to Live, it won't show the handle's link referencing to the staging URL in the "Overview" page and other similar pages as it's confusing
|
521 |
$localAssetPath = OptimizeCommon::getLocalAssetPath($src, (($assetKey === 'styles') ? 'css' : 'js'));
|
522 |
|
523 |
$relSrc = $src;
|
@@ -537,6 +537,136 @@ class Misc
|
|
537 |
return $relSrc;
|
538 |
}
|
539 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
540 |
/**
|
541 |
* @return bool
|
542 |
*/
|
@@ -1427,7 +1557,7 @@ SQL;
|
|
1427 |
}
|
1428 |
|
1429 |
/**
|
1430 |
-
* @return array
|
1431 |
*/
|
1432 |
public static function getAllActivePluginsIcons()
|
1433 |
{
|
192 |
/**
|
193 |
* @param $postId
|
194 |
*
|
195 |
+
* @return string
|
196 |
*/
|
197 |
public static function getPageUri($postId)
|
198 |
{
|
517 |
*/
|
518 |
public static function assetFromHrefToRelativeUri($src, $assetKey)
|
519 |
{
|
520 |
+
// Make the "src" relative in case the information will be imported from Staging to Live, it won't show the handle's link referencing to the staging URL in the "Overview" page and other similar pages, as it's confusing
|
521 |
$localAssetPath = OptimizeCommon::getLocalAssetPath($src, (($assetKey === 'styles') ? 'css' : 'js'));
|
522 |
|
523 |
$relSrc = $src;
|
537 |
return $relSrc;
|
538 |
}
|
539 |
|
540 |
+
/**
|
541 |
+
* @param $tagOutput ('script', 'link')
|
542 |
+
* @param $attribute
|
543 |
+
*
|
544 |
+
* @return false|string
|
545 |
+
*/
|
546 |
+
public static function getValueFromTag($tagOutput, $attribute = '', $method = 'regex')
|
547 |
+
{
|
548 |
+
$tagOutput = trim($tagOutput);
|
549 |
+
|
550 |
+
if ( strpos( $tagOutput, '<script' ) === 0 ) {
|
551 |
+
$tagNameToCheck = 'script';
|
552 |
+
|
553 |
+
if ($attribute === '') {
|
554 |
+
$attribute = 'src';
|
555 |
+
}
|
556 |
+
} elseif ( strpos( $tagOutput, '<link' ) === 0 ) {
|
557 |
+
$tagNameToCheck = 'link';
|
558 |
+
|
559 |
+
if ($attribute === '') {
|
560 |
+
$attribute = 'href';
|
561 |
+
}
|
562 |
+
} elseif ( strpos( $tagOutput, '<style' ) === 0 ) {
|
563 |
+
$tagNameToCheck = 'style';
|
564 |
+
|
565 |
+
if ($attribute === '') {
|
566 |
+
$attribute = 'type';
|
567 |
+
}
|
568 |
+
} else {
|
569 |
+
return false; // the tag it neither 'script' nor 'link'
|
570 |
+
}
|
571 |
+
|
572 |
+
if ($method === 'dom_with_fallback') {
|
573 |
+
if (self::isDOMDocumentOn()) {
|
574 |
+
$domForTag = self::initDOMDocument();
|
575 |
+
|
576 |
+
$domForTag->loadHTML( $tagOutput );
|
577 |
+
|
578 |
+
$scriptTagObj = $domForTag->getElementsByTagName( $tagNameToCheck )->item( 0 );
|
579 |
+
|
580 |
+
if ( $scriptTagObj === null ) {
|
581 |
+
return false;
|
582 |
+
}
|
583 |
+
|
584 |
+
if ( $scriptTagObj->hasAttributes() ) {
|
585 |
+
foreach ( $scriptTagObj->attributes as $attrObj ) {
|
586 |
+
if ( $attrObj->nodeName === $attribute ) {
|
587 |
+
return trim( $attrObj->nodeValue );
|
588 |
+
}
|
589 |
+
}
|
590 |
+
}
|
591 |
+
}
|
592 |
+
|
593 |
+
return self::getValueFromTagViaRegEx($tagOutput, $attribute);
|
594 |
+
}
|
595 |
+
|
596 |
+
if ($method === 'regex') {
|
597 |
+
return self::getValueFromTagViaRegEx($tagOutput, $attribute);
|
598 |
+
}
|
599 |
+
|
600 |
+
return false;
|
601 |
+
}
|
602 |
+
|
603 |
+
/**
|
604 |
+
* @param $tagOutput
|
605 |
+
* @param $attribute
|
606 |
+
*
|
607 |
+
* @return false|string
|
608 |
+
*/
|
609 |
+
public static function getValueFromTagViaRegEx($tagOutput, $attribute = '')
|
610 |
+
{
|
611 |
+
$tagOutput = trim( $tagOutput );
|
612 |
+
|
613 |
+
if ( strpos($tagOutput, '<script') === 0 ) {
|
614 |
+
if ( $attribute === '' ) {
|
615 |
+
$attribute = 'src';
|
616 |
+
}
|
617 |
+
|
618 |
+
preg_match_all( '#<script.*?'.$attribute.'\s*=\s*(.*?)#Usmi', $tagOutput, $outputMatches );
|
619 |
+
}
|
620 |
+
|
621 |
+
if ( strpos($tagOutput, '<link') === 0 ) {
|
622 |
+
if ( $attribute === '' ) {
|
623 |
+
$attribute = 'href';
|
624 |
+
}
|
625 |
+
|
626 |
+
preg_match_all( '#<link.*?'.$attribute.'\s*=\s*(.*?)#Usmi', $tagOutput, $outputMatches );
|
627 |
+
}
|
628 |
+
|
629 |
+
if ( strpos($tagOutput, '<style') === 0 ) {
|
630 |
+
if ( $attribute === '' ) {
|
631 |
+
$attribute = 'type';
|
632 |
+
}
|
633 |
+
|
634 |
+
preg_match_all( '#<style.*?'.$attribute.'\s*=\s*(.*?)#Usmi', $tagOutput, $outputMatches );
|
635 |
+
}
|
636 |
+
|
637 |
+
if ( isset($outputMatches[1][0]) && $outputMatches[1][0] ) {
|
638 |
+
$scriptPart = trim($outputMatches[1][0]);
|
639 |
+
|
640 |
+
foreach ( array('"', "'") as $quoteType ) {
|
641 |
+
if ( $scriptPart[0] === $quoteType ) {
|
642 |
+
$scriptPartTwo = ltrim( $scriptPart, $quoteType );
|
643 |
+
|
644 |
+
$posEndingQuote = strpos( $scriptPartTwo, $quoteType );
|
645 |
+
|
646 |
+
if ( $posEndingQuote === false ) {
|
647 |
+
return false;
|
648 |
+
}
|
649 |
+
|
650 |
+
return substr( $scriptPartTwo, 0, $posEndingQuote );
|
651 |
+
}
|
652 |
+
}
|
653 |
+
|
654 |
+
if ( ! in_array($scriptPart[0], array('"', "'") ) ) { // no quotes, just space or no wrapper
|
655 |
+
$scriptPartTwo = ltrim( $scriptPart );
|
656 |
+
|
657 |
+
$posFirstSpace = strpos( $scriptPartTwo, ' ' );
|
658 |
+
|
659 |
+
if ($posFirstSpace === false ) {
|
660 |
+
return false;
|
661 |
+
}
|
662 |
+
|
663 |
+
return substr( $scriptPartTwo, 0, $posFirstSpace );
|
664 |
+
}
|
665 |
+
}
|
666 |
+
|
667 |
+
return false;
|
668 |
+
}
|
669 |
+
|
670 |
/**
|
671 |
* @return bool
|
672 |
*/
|
1557 |
}
|
1558 |
|
1559 |
/**
|
1560 |
+
* @return array
|
1561 |
*/
|
1562 |
public static function getAllActivePluginsIcons()
|
1563 |
{
|
classes/ObjectCache.php
CHANGED
@@ -665,7 +665,7 @@ class ObjectCache {
|
|
665 |
/**
|
666 |
* Saves the data to the cache.
|
667 |
*
|
668 |
-
* Differs from ObjectCache::wpacu_cache_add) and wp_cache_replace() in that it will always write data.
|
669 |
*
|
670 |
* @since 2.0.0
|
671 |
*
|
665 |
/**
|
666 |
* Saves the data to the cache.
|
667 |
*
|
668 |
+
* Differs from ObjectCache::wpacu_cache_add() and wp_cache_replace() in that it will always write data.
|
669 |
*
|
670 |
* @since 2.0.0
|
671 |
*
|
classes/OptimiseAssets/CombineCssImports.php
CHANGED
@@ -316,7 +316,7 @@ class CombineCssImports extends Minify
|
|
316 |
// loop CSS data (raw data and files)
|
317 |
foreach ($this->data as $source => $css) {
|
318 |
// Some developers might have wrapped @import between comments
|
319 |
-
// No import for those
|
320 |
$css = $this->alterImportsBetweenComments($css);
|
321 |
|
322 |
$source = is_int($source) ? '' : $source;
|
@@ -427,12 +427,12 @@ class CombineCssImports extends Minify
|
|
427 |
|
428 |
// loop all urls
|
429 |
foreach ($matches as $match) {
|
430 |
-
// determine if it's
|
431 |
$type = (strpos($match[0], '@import') === 0 ? 'import' : 'url');
|
432 |
|
433 |
$url = $match['path'];
|
434 |
if ($this->canImportByPath($url)) {
|
435 |
-
// attempting to interpret GET-params makes no sense, so let's discard them for
|
436 |
$params = strrchr($url, '?');
|
437 |
$url = $params ? substr($url, 0, -strlen($params)) : $url;
|
438 |
|
316 |
// loop CSS data (raw data and files)
|
317 |
foreach ($this->data as $source => $css) {
|
318 |
// Some developers might have wrapped @import between comments
|
319 |
+
// No import for those
|
320 |
$css = $this->alterImportsBetweenComments($css);
|
321 |
|
322 |
$source = is_int($source) ? '' : $source;
|
427 |
|
428 |
// loop all urls
|
429 |
foreach ($matches as $match) {
|
430 |
+
// determine if it's an url() or an @import match
|
431 |
$type = (strpos($match[0], '@import') === 0 ? 'import' : 'url');
|
432 |
|
433 |
$url = $match['path'];
|
434 |
if ($this->canImportByPath($url)) {
|
435 |
+
// attempting to interpret GET-params makes no sense, so let's discard them for a while
|
436 |
$params = strrchr($url, '?');
|
437 |
$url = $params ? substr($url, 0, -strlen($params)) : $url;
|
438 |
|
classes/OptimiseAssets/CombineJs.php
CHANGED
@@ -342,7 +342,7 @@ class CombineJs
|
|
342 |
}
|
343 |
}
|
344 |
|
345 |
-
// Apply defer="defer" to combined JS files from the BODY tag (if enabled), except the combined jQuery & jQuery Migrate Group
|
346 |
if ($docLocationScript === 'body' && ! $jQueryIsIncludedInGroup && Main::instance()->settings['combine_loaded_js_defer_body']) {
|
347 |
if ($isDeferAppliedOnBodyCombineGroupNo === false) {
|
348 |
// Only record the first one
|
@@ -434,7 +434,7 @@ class CombineJs
|
|
434 |
}
|
435 |
}
|
436 |
|
437 |
-
// Only relevant if "Defer loading JavaScript combined files from <body>"
|
438 |
// and there is at least one combined deferred tag
|
439 |
|
440 |
if (isset($finalCacheList['body']) && (! empty($finalCacheList['body'])) && Main::instance()->settings['combine_loaded_js_defer_body']) {
|
342 |
}
|
343 |
}
|
344 |
|
345 |
+
// Apply 'defer="defer"' to combined JS files from the BODY tag (if enabled), except the combined jQuery & jQuery Migrate Group
|
346 |
if ($docLocationScript === 'body' && ! $jQueryIsIncludedInGroup && Main::instance()->settings['combine_loaded_js_defer_body']) {
|
347 |
if ($isDeferAppliedOnBodyCombineGroupNo === false) {
|
348 |
// Only record the first one
|
434 |
}
|
435 |
}
|
436 |
|
437 |
+
// Only relevant if "Defer loading JavaScript combined files from <body>" in "Settings" - "Combine CSS & JS Files" - "Combine loaded JS (JavaScript) into fewer files"
|
438 |
// and there is at least one combined deferred tag
|
439 |
|
440 |
if (isset($finalCacheList['body']) && (! empty($finalCacheList['body'])) && Main::instance()->settings['combine_loaded_js_defer_body']) {
|
classes/OptimiseAssets/DynamicLoadedAssets.php
CHANGED
@@ -53,9 +53,9 @@ class DynamicLoadedAssets
|
|
53 |
}
|
54 |
|
55 |
/**
|
56 |
-
* "Simple Custom CSS" (better retrieval, especially for localhost and password
|
57 |
*
|
58 |
-
* @return
|
59 |
*/
|
60 |
public static function getSimpleCustomCss()
|
61 |
{
|
53 |
}
|
54 |
|
55 |
/**
|
56 |
+
* "Simple Custom CSS" (better retrieval, especially for localhost and password-protected sites)
|
57 |
*
|
58 |
+
* @return string
|
59 |
*/
|
60 |
public static function getSimpleCustomCss()
|
61 |
{
|
classes/OptimiseAssets/FontsGoogle.php
CHANGED
@@ -203,8 +203,7 @@ class FontsGoogle
|
|
203 |
continue;
|
204 |
}
|
205 |
|
206 |
-
|
207 |
-
$linkHrefOriginal = $finalLinkHref = trim( $outputMatches[2][0], '"\'' );
|
208 |
|
209 |
// [START] Remove invalid requests with no font family
|
210 |
$urlParse = parse_url( str_replace( '&', '&', $linkHrefOriginal ), PHP_URL_QUERY );
|
@@ -250,7 +249,7 @@ class FontsGoogle
|
|
250 |
$finalCombinableLinks = array_values( $finalCombinableLinks );
|
251 |
|
252 |
// Only proceed with the optimization/combine if there's obviously at least 2 combinable URL requests to Google Fonts
|
253 |
-
// OR the loading type is different
|
254 |
if ( Main::instance()->settings['google_fonts_combine_type'] || count( $finalCombinableLinks ) > 1 ) {
|
255 |
$htmlSource = self::combineGoogleFontLinks( $finalCombinableLinks, $htmlSource );
|
256 |
}
|
@@ -274,8 +273,7 @@ class FontsGoogle
|
|
274 |
continue;
|
275 |
}
|
276 |
|
277 |
-
|
278 |
-
$linkHrefOriginal = trim( $outputMatches[2][0], '"\'' );
|
279 |
|
280 |
// [START] Remove invalid requests with no font family
|
281 |
$urlParse = parse_url( str_replace( '&', '&', $linkHrefOriginal ), PHP_URL_QUERY );
|
@@ -331,7 +329,7 @@ class FontsGoogle
|
|
331 |
$conditionOne = stripos($linkHrefOriginal, self::$containsStr) === false;
|
332 |
}
|
333 |
|
334 |
-
// Do not continue if it doesn't contain the right string or it contains 'display=' or it does not contain 'family=' or there is no value set for "font-display"
|
335 |
if ($conditionOne ||
|
336 |
stripos($linkHrefOriginal, 'display=') !== false ||
|
337 |
stripos($linkHrefOriginal, 'family=') === false ||
|
@@ -349,7 +347,7 @@ class FontsGoogle
|
|
349 |
$urlQuery = parse_url($altLinkHref, PHP_URL_QUERY);
|
350 |
parse_str($urlQuery, $outputStr);
|
351 |
|
352 |
-
// Is there no "display" or there is but it has an empty value? Append the one we have in the "Settings" - "Google Fonts"
|
353 |
if ( ! isset($outputStr['display']) || (isset($outputStr['display']) && $outputStr['display'] === '') ) {
|
354 |
$outputStr['display'] = Main::instance()->settings['google_fonts_display'];
|
355 |
|
203 |
continue;
|
204 |
}
|
205 |
|
206 |
+
$linkHrefOriginal = Misc::getValueFromTag($linkTag);
|
|
|
207 |
|
208 |
// [START] Remove invalid requests with no font family
|
209 |
$urlParse = parse_url( str_replace( '&', '&', $linkHrefOriginal ), PHP_URL_QUERY );
|
249 |
$finalCombinableLinks = array_values( $finalCombinableLinks );
|
250 |
|
251 |
// Only proceed with the optimization/combine if there's obviously at least 2 combinable URL requests to Google Fonts
|
252 |
+
// OR the loading type is different from render-blocking
|
253 |
if ( Main::instance()->settings['google_fonts_combine_type'] || count( $finalCombinableLinks ) > 1 ) {
|
254 |
$htmlSource = self::combineGoogleFontLinks( $finalCombinableLinks, $htmlSource );
|
255 |
}
|
273 |
continue;
|
274 |
}
|
275 |
|
276 |
+
$linkHrefOriginal = Misc::getValueFromTag($linkTag);
|
|
|
277 |
|
278 |
// [START] Remove invalid requests with no font family
|
279 |
$urlParse = parse_url( str_replace( '&', '&', $linkHrefOriginal ), PHP_URL_QUERY );
|
329 |
$conditionOne = stripos($linkHrefOriginal, self::$containsStr) === false;
|
330 |
}
|
331 |
|
332 |
+
// Do not continue if it doesn't contain the right string, or it contains 'display=' or it does not contain 'family=' or there is no value set for "font-display"
|
333 |
if ($conditionOne ||
|
334 |
stripos($linkHrefOriginal, 'display=') !== false ||
|
335 |
stripos($linkHrefOriginal, 'family=') === false ||
|
347 |
$urlQuery = parse_url($altLinkHref, PHP_URL_QUERY);
|
348 |
parse_str($urlQuery, $outputStr);
|
349 |
|
350 |
+
// Is there no "display" or there is, but it has an empty value? Append the one we have in the "Settings" - "Google Fonts"
|
351 |
if ( ! isset($outputStr['display']) || (isset($outputStr['display']) && $outputStr['display'] === '') ) {
|
352 |
$outputStr['display'] = Main::instance()->settings['google_fonts_display'];
|
353 |
|
classes/OptimiseAssets/MinifyCss.php
CHANGED
@@ -16,10 +16,11 @@ class MinifyCss
|
|
16 |
/**
|
17 |
* @param $cssContent
|
18 |
* @param bool $forInlineStyle
|
19 |
-
|
20 |
* @return string
|
21 |
*/
|
22 |
-
public static function applyMinification($cssContent, $forInlineStyle = false
|
|
|
23 |
{
|
24 |
if (class_exists('\MatthiasMullie\Minify\CSS')) {
|
25 |
$sha1OriginalContent = sha1($cssContent);
|
@@ -150,12 +151,12 @@ class MinifyCss
|
|
150 |
'#/wp-includes/css/(.*?).min.css#',
|
151 |
|
152 |
// Files within /wp-content/uploads/ or /wp-content/cache/
|
153 |
-
// Could belong to plugins such as "Elementor, "Oxygen" etc.
|
154 |
'#/wp-content/uploads/elementor/(.*?).css#',
|
155 |
'#/wp-content/uploads/oxygen/css/(.*?)-(.*?).css#',
|
156 |
'#/wp-content/cache/(.*?).css#',
|
157 |
|
158 |
-
// Already minified and it also has a random name making the cache folder make bigger
|
159 |
'#/wp-content/bs-booster-cache/#',
|
160 |
|
161 |
);
|
16 |
/**
|
17 |
* @param $cssContent
|
18 |
* @param bool $forInlineStyle
|
19 |
+
*
|
20 |
* @return string
|
21 |
*/
|
22 |
+
public static function applyMinification($cssContent, $forInlineStyle = false
|
23 |
+
)
|
24 |
{
|
25 |
if (class_exists('\MatthiasMullie\Minify\CSS')) {
|
26 |
$sha1OriginalContent = sha1($cssContent);
|
151 |
'#/wp-includes/css/(.*?).min.css#',
|
152 |
|
153 |
// Files within /wp-content/uploads/ or /wp-content/cache/
|
154 |
+
// Could belong to plugins such as "Elementor", "Oxygen" etc.
|
155 |
'#/wp-content/uploads/elementor/(.*?).css#',
|
156 |
'#/wp-content/uploads/oxygen/css/(.*?)-(.*?).css#',
|
157 |
'#/wp-content/cache/(.*?).css#',
|
158 |
|
159 |
+
// Already minified, and it also has a random name making the cache folder make bigger
|
160 |
'#/wp-content/bs-booster-cache/#',
|
161 |
|
162 |
);
|
classes/OptimiseAssets/MinifyJs.php
CHANGED
@@ -38,7 +38,7 @@ class MinifyJs
|
|
38 |
$minifiedContent = trim($minifier->minify());
|
39 |
|
40 |
if (trim($minifiedContent) === trim(trim($jsContent, ';'))) {
|
41 |
-
$minifiedContent = $jsContent; // consider them the same if only the ; at the end was stripped (it doesn't worth the resources that would be used)
|
42 |
$alreadyMinified = true;
|
43 |
}
|
44 |
|
@@ -175,8 +175,8 @@ class MinifyJs
|
|
175 |
}
|
176 |
|
177 |
// Only 'text/javascript' type is allowed for minification
|
178 |
-
|
179 |
-
|
180 |
if ($scriptType !== 'text/javascript') {
|
181 |
continue;
|
182 |
}
|
38 |
$minifiedContent = trim($minifier->minify());
|
39 |
|
40 |
if (trim($minifiedContent) === trim(trim($jsContent, ';'))) {
|
41 |
+
$minifiedContent = $jsContent; // consider them the same if only the ';' at the end was stripped (it doesn't worth the resources that would be used)
|
42 |
$alreadyMinified = true;
|
43 |
}
|
44 |
|
175 |
}
|
176 |
|
177 |
// Only 'text/javascript' type is allowed for minification
|
178 |
+
$scriptType = Misc::getValueFromTag($originalTag, 'type') ?: 'text/javascript'; // default
|
179 |
+
|
180 |
if ($scriptType !== 'text/javascript') {
|
181 |
continue;
|
182 |
}
|
classes/OptimiseAssets/OptimizeCommon.php
CHANGED
@@ -680,17 +680,12 @@ class OptimizeCommon
|
|
680 |
|
681 |
/**
|
682 |
* @param $sourceTag
|
683 |
-
* @param string $forAttr
|
684 |
*
|
685 |
* @return array|bool
|
686 |
*/
|
687 |
-
public static function getLocalCleanSourceFromTag($sourceTag
|
688 |
{
|
689 |
-
|
690 |
-
|
691 |
-
$sourceFromTag = (isset($outputMatchesSource[2][0]) && $outputMatchesSource[2][0])
|
692 |
-
? trim($outputMatchesSource[2][0], '"\'')
|
693 |
-
: false;
|
694 |
|
695 |
if (! $sourceFromTag) {
|
696 |
return false;
|
@@ -1187,7 +1182,7 @@ class OptimizeCommon
|
|
1187 |
$storageDir.'/item/',
|
1188 |
$assetCleanUpCacheDir.'css/',
|
1189 |
$assetCleanUpCacheDir.'js/',
|
1190 |
-
// Possible common directories with
|
1191 |
$relPathToPossibleDir.'/category/',
|
1192 |
$relPathToPossibleDir.'/author/',
|
1193 |
$relPathToPossibleDir.'/tag/'
|
@@ -1258,7 +1253,7 @@ class OptimizeCommon
|
|
1258 |
// Clear all JSON files separately from the storage directory as it will be rebuilt
|
1259 |
self::rmNonEmptyJsonStorageDir($storageDir);
|
1260 |
|
1261 |
-
// Now go through the JSONs and collect the latest assets so they would be kept
|
1262 |
// Finally, collect the rest of $allAssetsToKeep from the database transients (if any)
|
1263 |
// Do not check if they are expired or not as their assets could still be referenced
|
1264 |
// until those pages will be accessed in a non-cached way
|
@@ -1555,7 +1550,7 @@ SQL;
|
|
1555 |
$parseContentUrl = parse_url($wpContentUrl);
|
1556 |
$parseBaseUrl = parse_url(site_url());
|
1557 |
|
1558 |
-
// Perhaps WPML plugin is used and the content URL is different
|
1559 |
if ( ($parseContentUrl['host'] !== $parseBaseUrl['host']) &&
|
1560 |
(isset($_SERVER['HTTP_HOST'], $parseContentUrl['path']) && $_SERVER['HTTP_HOST'] !== $parseContentUrl['host']) &&
|
1561 |
is_dir(rtrim(ABSPATH, '/') . $parseContentUrl['path']) ) {
|
@@ -1864,7 +1859,7 @@ SQL;
|
|
1864 |
* @param $cdnUrl
|
1865 |
* @param $getType
|
1866 |
*
|
1867 |
-
* @return string
|
1868 |
*/
|
1869 |
public static function cdnToUrlFormat($cdnUrl, $getType)
|
1870 |
{
|
680 |
|
681 |
/**
|
682 |
* @param $sourceTag
|
|
|
683 |
*
|
684 |
* @return array|bool
|
685 |
*/
|
686 |
+
public static function getLocalCleanSourceFromTag($sourceTag)
|
687 |
{
|
688 |
+
$sourceFromTag = Misc::getValueFromTag($sourceTag);
|
|
|
|
|
|
|
|
|
689 |
|
690 |
if (! $sourceFromTag) {
|
691 |
return false;
|
1182 |
$storageDir.'/item/',
|
1183 |
$assetCleanUpCacheDir.'css/',
|
1184 |
$assetCleanUpCacheDir.'js/',
|
1185 |
+
// Possible common directories with fewer files
|
1186 |
$relPathToPossibleDir.'/category/',
|
1187 |
$relPathToPossibleDir.'/author/',
|
1188 |
$relPathToPossibleDir.'/tag/'
|
1253 |
// Clear all JSON files separately from the storage directory as it will be rebuilt
|
1254 |
self::rmNonEmptyJsonStorageDir($storageDir);
|
1255 |
|
1256 |
+
// Now go through the JSONs and collect the latest assets, so they would be kept
|
1257 |
// Finally, collect the rest of $allAssetsToKeep from the database transients (if any)
|
1258 |
// Do not check if they are expired or not as their assets could still be referenced
|
1259 |
// until those pages will be accessed in a non-cached way
|
1550 |
$parseContentUrl = parse_url($wpContentUrl);
|
1551 |
$parseBaseUrl = parse_url(site_url());
|
1552 |
|
1553 |
+
// Perhaps WPML plugin is used and the content URL is different from the current domain which might be for a different language
|
1554 |
if ( ($parseContentUrl['host'] !== $parseBaseUrl['host']) &&
|
1555 |
(isset($_SERVER['HTTP_HOST'], $parseContentUrl['path']) && $_SERVER['HTTP_HOST'] !== $parseContentUrl['host']) &&
|
1556 |
is_dir(rtrim(ABSPATH, '/') . $parseContentUrl['path']) ) {
|
1859 |
* @param $cdnUrl
|
1860 |
* @param $getType
|
1861 |
*
|
1862 |
+
* @return string
|
1863 |
*/
|
1864 |
public static function cdnToUrlFormat($cdnUrl, $getType)
|
1865 |
{
|
classes/OptimiseAssets/OptimizeCss.php
CHANGED
@@ -139,7 +139,7 @@ class OptimizeCss
|
|
139 |
continue;
|
140 |
}
|
141 |
|
142 |
-
$cleanLinkHrefFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag( $linkSourceTag
|
143 |
|
144 |
if ( isset( $cleanLinkHrefFromTagArray['source'] ) && $cleanLinkHrefFromTagArray['source'] ) {
|
145 |
$allEnqueuedCleanLinkHrefs[] = $cleanLinkHrefFromTagArray['source'];
|
@@ -539,7 +539,7 @@ class OptimizeCss
|
|
539 |
$htmlSource = FontsGoogle::alterHtmlSource($htmlSource);
|
540 |
/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
|
541 |
|
542 |
-
// NOSCRIPT fallback: Applies for Google Fonts (async) (Lite and Pro) / Preloads (Async in Pro version) / Critical CSS (as
|
543 |
/* [wpacu_timing] */ $wpacuTimingName = 'alter_html_source_for_add_async_preloads_noscript'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
|
544 |
$htmlSource = apply_filters('wpacu_add_noscript_certain_link_tags', $htmlSource);
|
545 |
/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
|
@@ -672,6 +672,11 @@ class OptimizeCss
|
|
672 |
public static function updateHtmlSourceOriginalToOptimizedCss($htmlSource)
|
673 |
{
|
674 |
$parseSiteUrlPath = parse_url(site_url(), PHP_URL_PATH);
|
|
|
|
|
|
|
|
|
|
|
675 |
$siteUrlNoProtocol = str_replace(array('http://', 'https://'), '//', site_url());
|
676 |
|
677 |
$cssOptimizeList = ObjectCache::wpacu_cache_get('wpacu_css_optimize_list') ?: array();
|
@@ -722,7 +727,7 @@ class OptimizeCss
|
|
722 |
continue;
|
723 |
}
|
724 |
|
725 |
-
$cleanLinkHrefFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag($linkSourceTag
|
726 |
|
727 |
// Skip external links, no point in carrying on
|
728 |
if (! $cleanLinkHrefFromTagArray || ! is_array($cleanLinkHrefFromTagArray)) {
|
@@ -794,11 +799,11 @@ class OptimizeCss
|
|
794 |
$siteUrlNoProtocol . $listValues[0], // without protocol
|
795 |
);
|
796 |
|
797 |
-
if (strpos($listValues[0], $parseSiteUrlPath) === 0 || strpos($cleanLinkHrefFromTag, $parseSiteUrlPath) === 0) {
|
798 |
$sourceUrlList[] = $cleanLinkHrefFromTag;
|
799 |
}
|
800 |
|
801 |
-
if (strpos($cleanLinkHrefFromTag, $parseSiteUrlPath) === 0 && strpos($cleanLinkHrefFromTag, $listValues[0]) !== false) {
|
802 |
$sourceUrlList[] = str_replace('//', '/', $parseSiteUrlPath.'/'.$listValues[0]);
|
803 |
}
|
804 |
elseif ( $cleanLinkHrefFromTag === $listValues[0] ) {
|
@@ -880,25 +885,26 @@ class OptimizeCss
|
|
880 |
$newLinkSourceTag = str_ireplace('<link ', '<link data-wpacu-link-rel-href-before="'.$sourceUrlRel.'" ', $newLinkSourceTag);
|
881 |
}
|
882 |
|
883 |
-
|
884 |
|
885 |
// No space from the matching and ? should be there
|
886 |
-
if (
|
887 |
-
if ( strpos( $
|
888 |
// Strip things like ?ver=
|
889 |
-
list( , $toStrip ) = explode( '?', $
|
890 |
$toStrip = '?' . trim( $toStrip );
|
891 |
$newLinkSourceTag = str_replace( $toStrip, '', $newLinkSourceTag );
|
892 |
}
|
893 |
|
894 |
-
if ( strpos( $
|
895 |
// Replace any .js&ver with .js
|
896 |
-
$toStrip = strrchr($
|
897 |
$newLinkSourceTag = str_replace( $toStrip, '', $newLinkSourceTag );
|
898 |
}
|
899 |
}
|
900 |
|
901 |
global $wp_version;
|
|
|
902 |
$newLinkSourceTag = str_replace('.css&ver='.$wp_version, '.css', $newLinkSourceTag);
|
903 |
$newLinkSourceTag = str_replace('.css&ver=', '.css', $newLinkSourceTag);
|
904 |
|
@@ -939,7 +945,7 @@ class OptimizeCss
|
|
939 |
|
940 |
// Skip any LINK tags within conditional comments (e.g. Internet Explorer ones)
|
941 |
preg_match_all(
|
942 |
-
'#<link[^>]*
|
943 |
OptimizeCommon::cleanerHtmlSource( $htmlSource, array( 'strip_content_between_conditional_comments', 'for_fetching_link_tags' ) ),
|
944 |
$matchesSourcesFromTags,
|
945 |
PREG_SET_ORDER
|
@@ -959,6 +965,10 @@ class OptimizeCss
|
|
959 |
foreach ($matchesSourcesFromTags as $matchList) {
|
960 |
$matchedTag = $matchList[0];
|
961 |
|
|
|
|
|
|
|
|
|
962 |
// Do not inline the admin bar SCRIPT file, saving resources as it's shown for the logged-in user only
|
963 |
if (strpos($matchedTag, '/wp-includes/css/admin-bar') !== false) {
|
964 |
continue;
|
@@ -993,8 +1003,7 @@ class OptimizeCss
|
|
993 |
continue;
|
994 |
}
|
995 |
|
996 |
-
|
997 |
-
$linkHrefOriginal = trim($outputMatchesHref[2][0], '"\'');
|
998 |
$localAssetPath = OptimizeCommon::getLocalAssetPath($linkHrefOriginal, 'css');
|
999 |
|
1000 |
if (! $localAssetPath) {
|
@@ -1012,8 +1021,8 @@ class OptimizeCss
|
|
1012 |
}
|
1013 |
|
1014 |
// Is there a media attribute? Make sure to add it to the STYLE tag
|
1015 |
-
|
1016 |
-
|
1017 |
$mediaAttr = ($mediaAttrValue && $mediaAttrValue !== 'all') ? 'media=\''.$mediaAttrValue.'\'' : '';
|
1018 |
|
1019 |
$appendBeforeAnyRelPath = $cdnUrlForCss ? OptimizeCommon::cdnToUrlFormat($cdnUrlForCss, 'raw') : '';
|
@@ -1523,11 +1532,8 @@ class OptimizeCss
|
|
1523 |
foreach ($matchesSourcesFromTags as $matchedValues) {
|
1524 |
$matchedTag = $matchedValues[0];
|
1525 |
|
1526 |
-
|
1527 |
-
$
|
1528 |
-
|
1529 |
-
preg_match_all('#href=(["\'])' . '(.*)' . '(["\'])#Usmi', $matchedTag, $outputMatchesMedia);
|
1530 |
-
$hrefAttrValue = isset($outputMatchesMedia[2][0]) ? trim($outputMatchesMedia[2][0], '"\'') : '';
|
1531 |
|
1532 |
$noScripts .= '<noscript><link rel="stylesheet" href="'.$hrefAttrValue.'" media="'.$mediaAttrValue.'" /></noscript>'."\n";
|
1533 |
}
|
139 |
continue;
|
140 |
}
|
141 |
|
142 |
+
$cleanLinkHrefFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag( $linkSourceTag );
|
143 |
|
144 |
if ( isset( $cleanLinkHrefFromTagArray['source'] ) && $cleanLinkHrefFromTagArray['source'] ) {
|
145 |
$allEnqueuedCleanLinkHrefs[] = $cleanLinkHrefFromTagArray['source'];
|
539 |
$htmlSource = FontsGoogle::alterHtmlSource($htmlSource);
|
540 |
/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
|
541 |
|
542 |
+
// NOSCRIPT fallback: Applies for Google Fonts (async) (Lite and Pro) / Preloads (Async in Pro version) / Critical CSS (as LINK "stylesheet" tags will be async preloaded)
|
543 |
/* [wpacu_timing] */ $wpacuTimingName = 'alter_html_source_for_add_async_preloads_noscript'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
|
544 |
$htmlSource = apply_filters('wpacu_add_noscript_certain_link_tags', $htmlSource);
|
545 |
/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
|
672 |
public static function updateHtmlSourceOriginalToOptimizedCss($htmlSource)
|
673 |
{
|
674 |
$parseSiteUrlPath = parse_url(site_url(), PHP_URL_PATH);
|
675 |
+
|
676 |
+
if ($parseSiteUrlPath === null) {
|
677 |
+
$parseSiteUrlPath = '';
|
678 |
+
}
|
679 |
+
|
680 |
$siteUrlNoProtocol = str_replace(array('http://', 'https://'), '//', site_url());
|
681 |
|
682 |
$cssOptimizeList = ObjectCache::wpacu_cache_get('wpacu_css_optimize_list') ?: array();
|
727 |
continue;
|
728 |
}
|
729 |
|
730 |
+
$cleanLinkHrefFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag($linkSourceTag);
|
731 |
|
732 |
// Skip external links, no point in carrying on
|
733 |
if (! $cleanLinkHrefFromTagArray || ! is_array($cleanLinkHrefFromTagArray)) {
|
799 |
$siteUrlNoProtocol . $listValues[0], // without protocol
|
800 |
);
|
801 |
|
802 |
+
if ($parseSiteUrlPath && (strpos($listValues[0], $parseSiteUrlPath) === 0 || strpos($cleanLinkHrefFromTag, $parseSiteUrlPath) === 0)) {
|
803 |
$sourceUrlList[] = $cleanLinkHrefFromTag;
|
804 |
}
|
805 |
|
806 |
+
if ($parseSiteUrlPath && (strpos($cleanLinkHrefFromTag, $parseSiteUrlPath) === 0 && strpos($cleanLinkHrefFromTag, $listValues[0]) !== false)) {
|
807 |
$sourceUrlList[] = str_replace('//', '/', $parseSiteUrlPath.'/'.$listValues[0]);
|
808 |
}
|
809 |
elseif ( $cleanLinkHrefFromTag === $listValues[0] ) {
|
885 |
$newLinkSourceTag = str_ireplace('<link ', '<link data-wpacu-link-rel-href-before="'.$sourceUrlRel.'" ', $newLinkSourceTag);
|
886 |
}
|
887 |
|
888 |
+
$hrefValue = Misc::getValueFromTag($newLinkSourceTag);
|
889 |
|
890 |
// No space from the matching and ? should be there
|
891 |
+
if ($hrefValue && ( strpos( $hrefValue, ' ' ) === false )) {
|
892 |
+
if ( strpos( $hrefValue, '?' ) !== false ) {
|
893 |
// Strip things like ?ver=
|
894 |
+
list( , $toStrip ) = explode( '?', $hrefValue );
|
895 |
$toStrip = '?' . trim( $toStrip );
|
896 |
$newLinkSourceTag = str_replace( $toStrip, '', $newLinkSourceTag );
|
897 |
}
|
898 |
|
899 |
+
if ( strpos( $hrefValue, '&ver' ) !== false ) {
|
900 |
// Replace any .js&ver with .js
|
901 |
+
$toStrip = strrchr($hrefValue, '&ver');
|
902 |
$newLinkSourceTag = str_replace( $toStrip, '', $newLinkSourceTag );
|
903 |
}
|
904 |
}
|
905 |
|
906 |
global $wp_version;
|
907 |
+
|
908 |
$newLinkSourceTag = str_replace('.css&ver='.$wp_version, '.css', $newLinkSourceTag);
|
909 |
$newLinkSourceTag = str_replace('.css&ver=', '.css', $newLinkSourceTag);
|
910 |
|
945 |
|
946 |
// Skip any LINK tags within conditional comments (e.g. Internet Explorer ones)
|
947 |
preg_match_all(
|
948 |
+
'#<link[^>]*stylesheet[^>]*>#Umsi',
|
949 |
OptimizeCommon::cleanerHtmlSource( $htmlSource, array( 'strip_content_between_conditional_comments', 'for_fetching_link_tags' ) ),
|
950 |
$matchesSourcesFromTags,
|
951 |
PREG_SET_ORDER
|
965 |
foreach ($matchesSourcesFromTags as $matchList) {
|
966 |
$matchedTag = $matchList[0];
|
967 |
|
968 |
+
if ( stripos( $matchedTag, '<link' ) !== 0 ) {
|
969 |
+
continue;
|
970 |
+
}
|
971 |
+
|
972 |
// Do not inline the admin bar SCRIPT file, saving resources as it's shown for the logged-in user only
|
973 |
if (strpos($matchedTag, '/wp-includes/css/admin-bar') !== false) {
|
974 |
continue;
|
1003 |
continue;
|
1004 |
}
|
1005 |
|
1006 |
+
$linkHrefOriginal = Misc::getValueFromTag($matchedTag);
|
|
|
1007 |
$localAssetPath = OptimizeCommon::getLocalAssetPath($linkHrefOriginal, 'css');
|
1008 |
|
1009 |
if (! $localAssetPath) {
|
1021 |
}
|
1022 |
|
1023 |
// Is there a media attribute? Make sure to add it to the STYLE tag
|
1024 |
+
$mediaAttrValue = Misc::getValueFromTag($matchedTag, 'media');
|
1025 |
+
|
1026 |
$mediaAttr = ($mediaAttrValue && $mediaAttrValue !== 'all') ? 'media=\''.$mediaAttrValue.'\'' : '';
|
1027 |
|
1028 |
$appendBeforeAnyRelPath = $cdnUrlForCss ? OptimizeCommon::cdnToUrlFormat($cdnUrlForCss, 'raw') : '';
|
1532 |
foreach ($matchesSourcesFromTags as $matchedValues) {
|
1533 |
$matchedTag = $matchedValues[0];
|
1534 |
|
1535 |
+
$mediaAttrValue = Misc::getValueFromTag($matchedTag, 'media');
|
1536 |
+
$hrefAttrValue = Misc::getValueFromTag($matchedTag);
|
|
|
|
|
|
|
1537 |
|
1538 |
$noScripts .= '<noscript><link rel="stylesheet" href="'.$hrefAttrValue.'" media="'.$mediaAttrValue.'" /></noscript>'."\n";
|
1539 |
}
|
classes/OptimiseAssets/OptimizeJs.php
CHANGED
@@ -72,7 +72,7 @@ class OptimizeJs
|
|
72 |
continue;
|
73 |
}
|
74 |
|
75 |
-
$cleanScriptSrcFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag( $scriptSourceTag
|
76 |
|
77 |
if ( isset( $cleanScriptSrcFromTagArray['source'] ) && $cleanScriptSrcFromTagArray['source'] ) {
|
78 |
$allEnqueuedCleanScriptSrcs[] = $cleanScriptSrcFromTagArray['source'];
|
@@ -293,6 +293,10 @@ class OptimizeJs
|
|
293 |
* [END] JS Content Optimization
|
294 |
*/
|
295 |
|
|
|
|
|
|
|
|
|
296 |
// Relative path to the new file
|
297 |
// Save it to /wp-content/cache/js/{OptimizeCommon::$optimizedSingleFilesDir}/
|
298 |
$fileVer = sha1($jsContent);
|
@@ -458,6 +462,11 @@ class OptimizeJs
|
|
458 |
public static function updateHtmlSourceOriginalToOptimizedJs($htmlSource)
|
459 |
{
|
460 |
$parseSiteUrlPath = parse_url(site_url(), PHP_URL_PATH);
|
|
|
|
|
|
|
|
|
|
|
461 |
$siteUrlNoProtocol = str_replace(array('http://', 'https://'), '//', site_url());
|
462 |
|
463 |
$jsOptimizeList = ObjectCache::wpacu_cache_get('wpacu_js_optimize_list') ?: array();
|
@@ -503,6 +512,13 @@ class OptimizeJs
|
|
503 |
continue;
|
504 |
}
|
505 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
506 |
$forAttr = 'src';
|
507 |
|
508 |
// Any preloads for the optimized script?
|
@@ -511,13 +527,6 @@ class OptimizeJs
|
|
511 |
$forAttr = 'href';
|
512 |
}
|
513 |
|
514 |
-
$cleanScriptSrcFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag($scriptSourceTag, $forAttr);
|
515 |
-
|
516 |
-
// Skip external links, no point in carrying on
|
517 |
-
if (! $cleanScriptSrcFromTagArray || ! is_array($cleanScriptSrcFromTagArray)) {
|
518 |
-
continue;
|
519 |
-
}
|
520 |
-
|
521 |
// Is it a local JS? Check if it's hardcoded (not enqueued the WordPress way)
|
522 |
$cleanScriptSrcFromTag = $cleanScriptSrcFromTagArray['source'];
|
523 |
$afterQuestionMark = $cleanScriptSrcFromTagArray['after_question_mark'];
|
@@ -583,7 +592,11 @@ class OptimizeJs
|
|
583 |
$siteUrlNoProtocol . $listValues[0], // without protocol
|
584 |
);
|
585 |
|
586 |
-
if (strpos($
|
|
|
|
|
|
|
|
|
587 |
$sourceUrlList[] = str_replace('//', '/', $parseSiteUrlPath.'/'.$listValues[0]);
|
588 |
}
|
589 |
elseif ( $cleanScriptSrcFromTag === $listValues[0] ) {
|
@@ -662,20 +675,20 @@ class OptimizeJs
|
|
662 |
$sourceUrlRel = is_array($sourceUrlList) ? OptimizeCommon::getSourceRelPath($sourceUrlList[0]) : OptimizeCommon::getSourceRelPath($sourceUrlList);
|
663 |
$newScriptSourceTag = str_ireplace('<'.$tagToCheck.' ', '<'.$tagToCheck.' data-wpacu-script-rel-src-before="'.$sourceUrlRel.'" ', $newScriptSourceTag);
|
664 |
|
665 |
-
|
666 |
|
667 |
// No space from the matching and ? should be there
|
668 |
-
if (
|
669 |
-
if ( strpos( $
|
670 |
// Strip things like ?ver=
|
671 |
-
list( , $toStrip ) = explode( '?', $
|
672 |
$toStrip = '?' . trim( $toStrip );
|
673 |
$newScriptSourceTag = str_replace( $toStrip, '', $newScriptSourceTag );
|
674 |
}
|
675 |
|
676 |
-
if ( strpos( $
|
677 |
// Replace any .js&ver with .js
|
678 |
-
$toStrip = strrchr($
|
679 |
$newScriptSourceTag = str_replace( $toStrip, '', $newScriptSourceTag );
|
680 |
}
|
681 |
}
|
72 |
continue;
|
73 |
}
|
74 |
|
75 |
+
$cleanScriptSrcFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag( $scriptSourceTag );
|
76 |
|
77 |
if ( isset( $cleanScriptSrcFromTagArray['source'] ) && $cleanScriptSrcFromTagArray['source'] ) {
|
78 |
$allEnqueuedCleanScriptSrcs[] = $cleanScriptSrcFromTagArray['source'];
|
293 |
* [END] JS Content Optimization
|
294 |
*/
|
295 |
|
296 |
+
if (isset($jsContentBeforeMin) && $jsContent === '/**/' && strpos($jsContentBeforeMin, '/*@cc_on') !== false && strpos($jsContentBeforeMin, '@*/') !== false) {
|
297 |
+
return array(); // Internet Explorer things, leave the file as it is
|
298 |
+
}
|
299 |
+
|
300 |
// Relative path to the new file
|
301 |
// Save it to /wp-content/cache/js/{OptimizeCommon::$optimizedSingleFilesDir}/
|
302 |
$fileVer = sha1($jsContent);
|
462 |
public static function updateHtmlSourceOriginalToOptimizedJs($htmlSource)
|
463 |
{
|
464 |
$parseSiteUrlPath = parse_url(site_url(), PHP_URL_PATH);
|
465 |
+
|
466 |
+
if ($parseSiteUrlPath === null) {
|
467 |
+
$parseSiteUrlPath = '';
|
468 |
+
}
|
469 |
+
|
470 |
$siteUrlNoProtocol = str_replace(array('http://', 'https://'), '//', site_url());
|
471 |
|
472 |
$jsOptimizeList = ObjectCache::wpacu_cache_get('wpacu_js_optimize_list') ?: array();
|
512 |
continue;
|
513 |
}
|
514 |
|
515 |
+
$cleanScriptSrcFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag($scriptSourceTag);
|
516 |
+
|
517 |
+
// Skip external links, no point in carrying on
|
518 |
+
if (! $cleanScriptSrcFromTagArray || ! is_array($cleanScriptSrcFromTagArray)) {
|
519 |
+
continue;
|
520 |
+
}
|
521 |
+
|
522 |
$forAttr = 'src';
|
523 |
|
524 |
// Any preloads for the optimized script?
|
527 |
$forAttr = 'href';
|
528 |
}
|
529 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
530 |
// Is it a local JS? Check if it's hardcoded (not enqueued the WordPress way)
|
531 |
$cleanScriptSrcFromTag = $cleanScriptSrcFromTagArray['source'];
|
532 |
$afterQuestionMark = $cleanScriptSrcFromTagArray['after_question_mark'];
|
592 |
$siteUrlNoProtocol . $listValues[0], // without protocol
|
593 |
);
|
594 |
|
595 |
+
if ($parseSiteUrlPath && (strpos($listValues[0], $parseSiteUrlPath) === 0 || strpos($cleanScriptSrcFromTag, $parseSiteUrlPath) === 0)) {
|
596 |
+
$sourceUrlList[] = $cleanScriptSrcFromTag;
|
597 |
+
}
|
598 |
+
|
599 |
+
if ($parseSiteUrlPath && strpos($cleanScriptSrcFromTag, $parseSiteUrlPath) === 0 && strpos($cleanScriptSrcFromTag, $listValues[0]) !== false) {
|
600 |
$sourceUrlList[] = str_replace('//', '/', $parseSiteUrlPath.'/'.$listValues[0]);
|
601 |
}
|
602 |
elseif ( $cleanScriptSrcFromTag === $listValues[0] ) {
|
675 |
$sourceUrlRel = is_array($sourceUrlList) ? OptimizeCommon::getSourceRelPath($sourceUrlList[0]) : OptimizeCommon::getSourceRelPath($sourceUrlList);
|
676 |
$newScriptSourceTag = str_ireplace('<'.$tagToCheck.' ', '<'.$tagToCheck.' data-wpacu-script-rel-src-before="'.$sourceUrlRel.'" ', $newScriptSourceTag);
|
677 |
|
678 |
+
$sourceValue = Misc::getValueFromTag($scriptSourceTag);
|
679 |
|
680 |
// No space from the matching and ? should be there
|
681 |
+
if ($sourceValue && ( strpos( $sourceValue, ' ' ) === false )) {
|
682 |
+
if ( strpos( $sourceValue, '?' ) !== false ) {
|
683 |
// Strip things like ?ver=
|
684 |
+
list( , $toStrip ) = explode( '?', $sourceValue );
|
685 |
$toStrip = '?' . trim( $toStrip );
|
686 |
$newScriptSourceTag = str_replace( $toStrip, '', $newScriptSourceTag );
|
687 |
}
|
688 |
|
689 |
+
if ( strpos( $sourceValue, '&ver' ) !== false ) {
|
690 |
// Replace any .js&ver with .js
|
691 |
+
$toStrip = strrchr($sourceValue, '&ver');
|
692 |
$newScriptSourceTag = str_replace( $toStrip, '', $newScriptSourceTag );
|
693 |
}
|
694 |
}
|
classes/OwnAssets.php
CHANGED
@@ -766,6 +766,10 @@ HTML;
|
|
766 |
add_action('admin_head', static function() {
|
767 |
?>
|
768 |
<style <?php echo Misc::getStyleTypeAttribute(); ?> data-wpacu-own-inline-style="true">
|
|
|
|
|
|
|
|
|
769 |
.wpacu-swal2-popup {
|
770 |
width: 36em !important;
|
771 |
}
|
766 |
add_action('admin_head', static function() {
|
767 |
?>
|
768 |
<style <?php echo Misc::getStyleTypeAttribute(); ?> data-wpacu-own-inline-style="true">
|
769 |
+
body[class*='asset-cleanup'] .swal2-container {
|
770 |
+
z-index: 1000000;
|
771 |
+
}
|
772 |
+
|
773 |
.wpacu-swal2-popup {
|
774 |
width: 36em !important;
|
775 |
}
|
classes/Plugin.php
CHANGED
@@ -290,7 +290,7 @@ HTACCESS;
|
|
290 |
@mkdir( $storageDir . OptimizeCommon::$optimizedSingleFilesDir, 0755, true );
|
291 |
}
|
292 |
|
293 |
-
// Storage directory for the most recent items (these
|
294 |
$storageDirRecentItems = WP_CONTENT_DIR . OptimiseAssets\OptimizeCommon::getRelPathPluginCacheDir() . '_storage/_recent_items/';
|
295 |
|
296 |
if ( ! is_dir($storageDirRecentItems) ) {
|
@@ -381,7 +381,7 @@ HTACCESS;
|
|
381 |
// Is it an AMP endpoint?
|
382 |
if ( ($isAmpInRequestUri && Misc::isPluginActive('accelerated-mobile-pages/accelerated-mobile-pages.php')) // "AMP for WP – Accelerated Mobile Pages"
|
383 |
|| ($isAmpInRequestUri && Misc::isPluginActive('amp/amp.php')) // "AMP – WordPress plugin"
|
384 |
-
|| (function_exists('is_wp_amp') && Misc::isPluginActive('wp-amp/wp-amp.php') && is_wp_amp()) // "WP AMP — Accelerated Mobile Pages for WordPress and WooCommerce" (Premium plugin)
|
385 |
) {
|
386 |
return true; // do not print anything on an AMP page
|
387 |
}
|
290 |
@mkdir( $storageDir . OptimizeCommon::$optimizedSingleFilesDir, 0755, true );
|
291 |
}
|
292 |
|
293 |
+
// Storage directory for the most recent items (these are never deleted from the cache)
|
294 |
$storageDirRecentItems = WP_CONTENT_DIR . OptimiseAssets\OptimizeCommon::getRelPathPluginCacheDir() . '_storage/_recent_items/';
|
295 |
|
296 |
if ( ! is_dir($storageDirRecentItems) ) {
|
381 |
// Is it an AMP endpoint?
|
382 |
if ( ($isAmpInRequestUri && Misc::isPluginActive('accelerated-mobile-pages/accelerated-mobile-pages.php')) // "AMP for WP – Accelerated Mobile Pages"
|
383 |
|| ($isAmpInRequestUri && Misc::isPluginActive('amp/amp.php')) // "AMP – WordPress plugin"
|
384 |
+
|| ((function_exists('is_wp_amp') && Misc::isPluginActive('wp-amp/wp-amp.php') && is_wp_amp())) // "WP AMP — Accelerated Mobile Pages for WordPress and WooCommerce" (Premium plugin)
|
385 |
) {
|
386 |
return true; // do not print anything on an AMP page
|
387 |
}
|
classes/Preloads.php
CHANGED
@@ -293,28 +293,11 @@ class Preloads
|
|
293 |
return $htmlSource;
|
294 |
}
|
295 |
|
296 |
-
|
297 |
-
|
298 |
-
$strContainsFormat = preg_quote('data-wpacu-to-be-preloaded-basic', '/');
|
299 |
-
preg_match_all('#<link[^>]*'.$strContainsFormat.'[^>]*' . '\shref=(\'|"|)(.*)(\\1?\s)' . '.*(>)#Usmi', $htmlSource, $matchesSourcesFromLinkTags, PREG_SET_ORDER);
|
300 |
-
|
301 |
-
$stickToRegEx = true; // default
|
302 |
-
|
303 |
-
foreach ($matchesSourcesFromLinkTags as $linkTagArray) {
|
304 |
-
$linkTag = $linkTagArray[0];
|
305 |
-
|
306 |
-
preg_match_all('#id=([\'"])(.*?)(\\1)#', $linkTag, $matchId);
|
307 |
-
$matchedCssId = isset($matchId[2][0]) ? $matchId[2][0] : '';
|
308 |
-
$matchedCssHandle = substr($matchedCssId, 0, -4);
|
309 |
-
|
310 |
-
if (! in_array($matchedCssHandle, $preloadedHandles)) {
|
311 |
-
$stickToRegEx = false;
|
312 |
-
break;
|
313 |
-
}
|
314 |
-
}
|
315 |
|
316 |
// Something might not be right with the RegEx; Fallback to DOMDocument, more accurate, but slower
|
317 |
-
if (
|
318 |
$documentForCSS = Misc::initDOMDocument();
|
319 |
|
320 |
$htmlSourceAlt = preg_replace( '@<(noscript|style|script)[^>]*?>.*?</\\1>@si', '', $htmlSource );
|
@@ -322,7 +305,7 @@ class Preloads
|
|
322 |
|
323 |
$linkTags = $documentForCSS->getElementsByTagName( 'link' );
|
324 |
|
325 |
-
|
326 |
$matchesSourcesFromLinkTags = array(); // reset its value; new fetch method was used
|
327 |
|
328 |
foreach ( $linkTags as $tagObject ) {
|
@@ -330,31 +313,49 @@ class Preloads
|
|
330 |
continue;
|
331 |
}
|
332 |
|
|
|
|
|
|
|
|
|
|
|
333 |
$linkAttributes = array();
|
334 |
|
335 |
foreach ( $tagObject->attributes as $attrObj ) {
|
336 |
$linkAttributes[ $attrObj->nodeName ] = trim( $attrObj->nodeValue );
|
337 |
}
|
338 |
|
339 |
-
if ( isset( $linkAttributes['data-wpacu-to-be-preloaded-basic'], $linkAttributes['href'] ) ) {
|
340 |
-
|
341 |
-
|
|
|
|
|
342 |
}
|
343 |
}
|
344 |
|
345 |
libxml_clear_errors();
|
346 |
}
|
347 |
|
348 |
-
|
349 |
-
|
350 |
-
|
|
|
351 |
|
352 |
-
|
353 |
-
|
|
|
|
|
|
|
|
|
|
|
354 |
}
|
|
|
|
|
355 |
|
356 |
-
|
357 |
|
|
|
|
|
|
|
358 |
$htmlSource = str_replace( self::DEL_STYLES_PRELOADS, $linkPreload . self::DEL_STYLES_PRELOADS, $htmlSource );
|
359 |
}
|
360 |
}
|
@@ -393,19 +394,21 @@ class Preloads
|
|
393 |
|
394 |
$strContainsFormat = preg_quote('data-wpacu-to-be-preloaded-basic=\'1\'', '/');
|
395 |
|
396 |
-
preg_match_all('#<script[^>]*'.$strContainsFormat.'[^>]*' . 'src=(
|
397 |
|
398 |
if (empty($matchesSourcesFromScriptTags)) {
|
399 |
return $htmlSource;
|
400 |
}
|
401 |
|
402 |
foreach ($matchesSourcesFromScriptTags as $scriptTagArray) {
|
403 |
-
|
404 |
|
405 |
-
if (! $
|
406 |
continue;
|
407 |
}
|
408 |
|
|
|
|
|
409 |
$linkPreload = '<link rel=\'preload\' as=\'script\' href=\''.esc_attr($scriptSrc).'\' data-wpacu-preload-js=\'1\'>'."\n";
|
410 |
|
411 |
$htmlSource = str_replace(self::DEL_SCRIPTS_PRELOADS, $linkPreload . self::DEL_SCRIPTS_PRELOADS, $htmlSource);
|
293 |
return $htmlSource;
|
294 |
}
|
295 |
|
296 |
+
$allHrefs = array();
|
297 |
+
$stickToRegEx = false; // default
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
|
299 |
// Something might not be right with the RegEx; Fallback to DOMDocument, more accurate, but slower
|
300 |
+
if ( Misc::isDOMDocumentOn() ) {
|
301 |
$documentForCSS = Misc::initDOMDocument();
|
302 |
|
303 |
$htmlSourceAlt = preg_replace( '@<(noscript|style|script)[^>]*?>.*?</\\1>@si', '', $htmlSource );
|
305 |
|
306 |
$linkTags = $documentForCSS->getElementsByTagName( 'link' );
|
307 |
|
308 |
+
if ( count($linkTags) > 0 ) {
|
309 |
$matchesSourcesFromLinkTags = array(); // reset its value; new fetch method was used
|
310 |
|
311 |
foreach ( $linkTags as $tagObject ) {
|
313 |
continue;
|
314 |
}
|
315 |
|
316 |
+
if (strpos($htmlSourceAlt, $tagObject->nodeValue) === false) {
|
317 |
+
$stickToRegEx = true; // the value is not the same as in the HTML source (e.g. altered by the DOM) / fallback to RegEx
|
318 |
+
break;
|
319 |
+
}
|
320 |
+
|
321 |
$linkAttributes = array();
|
322 |
|
323 |
foreach ( $tagObject->attributes as $attrObj ) {
|
324 |
$linkAttributes[ $attrObj->nodeName ] = trim( $attrObj->nodeValue );
|
325 |
}
|
326 |
|
327 |
+
if ( ! isset( $linkAttributes['data-wpacu-to-be-preloaded-basic'], $linkAttributes['href'] ) ) {
|
328 |
+
continue;
|
329 |
+
}
|
330 |
+
|
331 |
+
$allHrefs[] = $linkAttributes['href'];
|
332 |
}
|
333 |
}
|
334 |
|
335 |
libxml_clear_errors();
|
336 |
}
|
337 |
|
338 |
+
if ($stickToRegEx) {
|
339 |
+
// Use the RegEx as it's much faster and very accurate in this situation
|
340 |
+
$strContainsFormat = preg_quote('data-wpacu-to-be-preloaded-basic', '/');
|
341 |
+
preg_match_all('#<link[^>]*'.$strContainsFormat.'[^>]*' . '\shref(\s+|)=(\s+|)(\'|"|)(.*)(\\3)' . '.*(>)#Usmi', $htmlSource, $matchesSourcesFromLinkTags, PREG_SET_ORDER);
|
342 |
|
343 |
+
if ( ! empty($matchesSourcesFromLinkTags) ) {
|
344 |
+
foreach ( $matchesSourcesFromLinkTags as $linkTagArray ) {
|
345 |
+
$linkHref = isset( $linkTagArray[0] ) ? Misc::getValueFromTag( $linkTagArray[0] ) : false;
|
346 |
+
|
347 |
+
if ($linkHref) {
|
348 |
+
$allHrefs[] = $linkHref;
|
349 |
+
}
|
350 |
}
|
351 |
+
}
|
352 |
+
}
|
353 |
|
354 |
+
$allHrefs = array_unique($allHrefs);
|
355 |
|
356 |
+
if ( ! empty($allHrefs) ) {
|
357 |
+
foreach ( $allHrefs as $linkHref ) {
|
358 |
+
$linkPreload = self::linkPreloadCssFormat( $linkHref );
|
359 |
$htmlSource = str_replace( self::DEL_STYLES_PRELOADS, $linkPreload . self::DEL_STYLES_PRELOADS, $htmlSource );
|
360 |
}
|
361 |
}
|
394 |
|
395 |
$strContainsFormat = preg_quote('data-wpacu-to-be-preloaded-basic=\'1\'', '/');
|
396 |
|
397 |
+
preg_match_all('#<script[^>]*'.$strContainsFormat.'[^>]*' . 'src(\s+|)=(\s+|)(\'|"|)(.*)(\\3)' . '.*(>)#Usmi', $htmlSource, $matchesSourcesFromScriptTags, PREG_SET_ORDER);
|
398 |
|
399 |
if (empty($matchesSourcesFromScriptTags)) {
|
400 |
return $htmlSource;
|
401 |
}
|
402 |
|
403 |
foreach ($matchesSourcesFromScriptTags as $scriptTagArray) {
|
404 |
+
$scripTag = isset($scriptTagArray[0]) ? $scriptTagArray[0] : false;
|
405 |
|
406 |
+
if (! $scripTag) {
|
407 |
continue;
|
408 |
}
|
409 |
|
410 |
+
$scriptSrc = Misc::getValueFromTag($scripTag);
|
411 |
+
|
412 |
$linkPreload = '<link rel=\'preload\' as=\'script\' href=\''.esc_attr($scriptSrc).'\' data-wpacu-preload-js=\'1\'>'."\n";
|
413 |
|
414 |
$htmlSource = str_replace(self::DEL_SCRIPTS_PRELOADS, $linkPreload . self::DEL_SCRIPTS_PRELOADS, $htmlSource);
|
classes/Settings.php
CHANGED
@@ -94,7 +94,7 @@ class Settings
|
|
94 |
'combine_loaded_js',
|
95 |
'combine_loaded_js_exceptions',
|
96 |
'combine_loaded_js_for_admin_only',
|
97 |
-
'combine_loaded_js_defer_body', // Applies defer="defer" to the combined file(s) within BODY tag
|
98 |
'combine_loaded_js_try_catch', // try {} catch (e) {} for each individual file within a combined file
|
99 |
|
100 |
// Minify each loaded CSS (remaining ones after unloading the useless ones)
|
@@ -568,7 +568,7 @@ class Settings
|
|
568 |
}
|
569 |
|
570 |
// Oxygen Builder is triggered and some users might want to trigger unload rules there to make the editor faster, especially plugin unload rules
|
571 |
-
// We will prevent minify/combine and other functions that will
|
572 |
if (defined('WPACU_ALLOW_ONLY_UNLOAD_RULES') && WPACU_ALLOW_ONLY_UNLOAD_RULES) {
|
573 |
$settings['minify_loaded_css']
|
574 |
= $settings['minify_loaded_js']
|
@@ -600,7 +600,7 @@ class Settings
|
|
600 |
}
|
601 |
|
602 |
// /?wpacu_manage_front -> "Manage in the Front-end" via query string request
|
603 |
-
// Useful when working for a client and you prefer him to view the pages (while logged-in) without the CSS/JS list at the bottom
|
604 |
if (isset($_GET['wpacu_manage_front'])) {
|
605 |
$settings['frontend_show'] = true;
|
606 |
}
|
@@ -720,7 +720,7 @@ class Settings
|
|
720 |
}
|
721 |
|
722 |
// Apply 'Ignore dependency rule and keep the "children" loaded' for "dashicons" handle if Ninja Forms is active
|
723 |
-
// because "nf-display" handle depends on the Dashicons and it could break the forms' styling
|
724 |
if ($disableDashiconsForGuests && Misc::isPluginActive('ninja-forms/ninja-forms.php')) {
|
725 |
$mainVarToUse = array();
|
726 |
$mainVarToUse['wpacu_ignore_child']['styles']['dashicons'] = 1;
|
94 |
'combine_loaded_js',
|
95 |
'combine_loaded_js_exceptions',
|
96 |
'combine_loaded_js_for_admin_only',
|
97 |
+
'combine_loaded_js_defer_body', // Applies 'defer="defer"' to the combined file(s) within BODY tag
|
98 |
'combine_loaded_js_try_catch', // try {} catch (e) {} for each individual file within a combined file
|
99 |
|
100 |
// Minify each loaded CSS (remaining ones after unloading the useless ones)
|
568 |
}
|
569 |
|
570 |
// Oxygen Builder is triggered and some users might want to trigger unload rules there to make the editor faster, especially plugin unload rules
|
571 |
+
// We will prevent minify/combine and other functions that will require caching any files to avoid any errors
|
572 |
if (defined('WPACU_ALLOW_ONLY_UNLOAD_RULES') && WPACU_ALLOW_ONLY_UNLOAD_RULES) {
|
573 |
$settings['minify_loaded_css']
|
574 |
= $settings['minify_loaded_js']
|
600 |
}
|
601 |
|
602 |
// /?wpacu_manage_front -> "Manage in the Front-end" via query string request
|
603 |
+
// Useful when working for a client, and you prefer him to view the pages (while logged-in) without the CSS/JS list at the bottom
|
604 |
if (isset($_GET['wpacu_manage_front'])) {
|
605 |
$settings['frontend_show'] = true;
|
606 |
}
|
720 |
}
|
721 |
|
722 |
// Apply 'Ignore dependency rule and keep the "children" loaded' for "dashicons" handle if Ninja Forms is active
|
723 |
+
// because "nf-display" handle depends on the Dashicons, and it could break the forms' styling
|
724 |
if ($disableDashiconsForGuests && Misc::isPluginActive('ninja-forms/ninja-forms.php')) {
|
725 |
$mainVarToUse = array();
|
726 |
$mainVarToUse['wpacu_ignore_child']['styles']['dashicons'] = 1;
|
classes/Tips.php
CHANGED
@@ -34,11 +34,11 @@ This CSS file is related to "Contact Form 7" and if you don't load any form on t
|
|
34 |
HTML;
|
35 |
|
36 |
$this->list['css']['duplicate-post'] = <<<HTML
|
37 |
-
This CSS file is meant to style the "Duplicate Post" plugin's menu within the top admin bar and it's loading when the user (with the right privileges) is logged-in. It's NOT meant to load for the guests (non
|
38 |
HTML;
|
39 |
|
40 |
$this->list['css']['dashicons'] = <<<HTML
|
41 |
-
To avoid breaking admin bar's styling which relies on the
|
42 |
HTML;
|
43 |
// JavaScript list
|
44 |
$this->list['js']['wp-embed'] = <<<HTML
|
34 |
HTML;
|
35 |
|
36 |
$this->list['css']['duplicate-post'] = <<<HTML
|
37 |
+
This CSS file is meant to style the "Duplicate Post" plugin's menu within the top admin bar, and it's loading when the user (with the right privileges) is logged-in. It's NOT meant to load for the guests (non-logged-in visitors). You can leave it loaded.
|
38 |
HTML;
|
39 |
|
40 |
$this->list['css']['dashicons'] = <<<HTML
|
41 |
+
To avoid breaking admin bar's styling which relies on the WordPress Dashicons, any unload rule set for this handle will be ignored IF the user is logged-in and the admin bar is showing up.
|
42 |
HTML;
|
43 |
// JavaScript list
|
44 |
$this->list['js']['wp-embed'] = <<<HTML
|
classes/Tools.php
CHANGED
@@ -210,7 +210,7 @@ class Tools
|
|
210 |
$return .= strip_tags($browser)."\n";
|
211 |
}
|
212 |
|
213 |
-
// WordPress configuration.
|
214 |
// Get theme info.
|
215 |
$theme_data = wp_get_theme();
|
216 |
$theme = $theme_data->Name . ' ' . $theme_data->Version;
|
210 |
$return .= strip_tags($browser)."\n";
|
211 |
}
|
212 |
|
213 |
+
// WordPress' configuration.
|
214 |
// Get theme info.
|
215 |
$theme_data = wp_get_theme();
|
216 |
$theme = $theme_data->Name . ' ' . $theme_data->Version;
|
classes/Update.php
CHANGED
@@ -158,7 +158,7 @@ HTML;
|
|
158 |
self::updateAssetListLayoutSettings();
|
159 |
|
160 |
// Form submitted from the homepage
|
161 |
-
// e.g. from a page such as latest blog posts, not a static page that was selected as home page
|
162 |
if (Misc::isHomePage() && Misc::getShowOnFront() !== 'page') {
|
163 |
$wpacuNoLoadAssets = Misc::getVar('post', WPACU_PLUGIN_ID, array());
|
164 |
|
@@ -1244,7 +1244,7 @@ HTML;
|
|
1244 |
// Strip other unused information including the 'handle' (no need to have it twice as it's already in one of the array's keys)
|
1245 |
unset( $assetArray['handle'], $assetArray['textdomain'], $assetArray['translations_path'] );
|
1246 |
|
1247 |
-
// Some handles don't have
|
1248 |
if (isset($assetArray['src']) && $assetArray['src']) {
|
1249 |
$assetArray['src'] = Misc::assetFromHrefToRelativeUri( $assetArray['src'], $assetKey );
|
1250 |
}
|
158 |
self::updateAssetListLayoutSettings();
|
159 |
|
160 |
// Form submitted from the homepage
|
161 |
+
// e.g. from a page such as latest blog posts, not a static page that was selected as home page
|
162 |
if (Misc::isHomePage() && Misc::getShowOnFront() !== 'page') {
|
163 |
$wpacuNoLoadAssets = Misc::getVar('post', WPACU_PLUGIN_ID, array());
|
164 |
|
1244 |
// Strip other unused information including the 'handle' (no need to have it twice as it's already in one of the array's keys)
|
1245 |
unset( $assetArray['handle'], $assetArray['textdomain'], $assetArray['translations_path'] );
|
1246 |
|
1247 |
+
// Some handles don't have a "src" value such as "woocommerce-inline"
|
1248 |
if (isset($assetArray['src']) && $assetArray['src']) {
|
1249 |
$assetArray['src'] = Misc::assetFromHrefToRelativeUri( $assetArray['src'], $assetKey );
|
1250 |
}
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: gabelivan
|
|
3 |
Tags: minify css, minify javascript, defer css javascript, page speed, dequeue, performance
|
4 |
Donate link: https://www.gabelivan.com/items/wp-asset-cleanup-pro/?utm_source=wp_org_lite&utm_medium=donate
|
5 |
Requires at least: 4.6
|
6 |
-
Tested up to: 6.1
|
7 |
-
Stable tag: 1.3.8.
|
8 |
License: GPLv3
|
9 |
License URI: http://www.gnu.org/licenses/gpl.html
|
10 |
|
@@ -191,6 +191,12 @@ With the recently released "Test Mode" feature, you can safely unload assets on
|
|
191 |
4. Homepage CSS & JS Management (List sorted by location)
|
192 |
|
193 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
= 1.3.8.8 =
|
195 |
* "CSS/JS Manager": If a handle has inline code associated with it, mention the size (e.g. bytes, KB) of that inlined LINK or SCRIPT (just like it's mentioned for the LINK tags with the "href" attribute and SCRIPT tags with the "src" attribute)
|
196 |
* Higher accuracy in detecting (for optimization) the LINK tags that are loading CSS/JS files
|
3 |
Tags: minify css, minify javascript, defer css javascript, page speed, dequeue, performance
|
4 |
Donate link: https://www.gabelivan.com/items/wp-asset-cleanup-pro/?utm_source=wp_org_lite&utm_medium=donate
|
5 |
Requires at least: 4.6
|
6 |
+
Tested up to: 6.1.1
|
7 |
+
Stable tag: 1.3.8.9
|
8 |
License: GPLv3
|
9 |
License URI: http://www.gnu.org/licenses/gpl.html
|
10 |
|
191 |
4. Homepage CSS & JS Management (List sorted by location)
|
192 |
|
193 |
== Changelog ==
|
194 |
+
= 1.3.8.9 =
|
195 |
+
* Improvement: Better detection of the tags when the source of a tag (e.g. "src" or "href") is not wrapped around quotes or even has spaces added after or before the equal sign / e.g. <script src=/path/to/file.js></script> OR <link rel=stylesheet href = /path/to/file.css>
|
196 |
+
* Whenever XML-RPC is completely disabled in 'Settings' -- 'Disable XML-RPC', make sure the following option is automatically turned ON: 'Settings" --- 'HTML Source CleanUp' -- 'Remove "Really Simple Discovery (RSD)" link tag?'
|
197 |
+
* Fix: The size of an asset loaded locally was not shown when the path to the file was relative and starting with the URI of the WordPress site URL / Example: The WordPress site URL was "https://yoursite.com/blog" and the tag was "<script src='/blog/wp-content/path/to/file.js'></script>"
|
198 |
+
* Fix: Exclude from optimisation JS files that contain "/*@cc_on" and "@*/" as they are meant to be loaded by Internet Explorer and not stripped if they only contain commented code
|
199 |
+
|
200 |
= 1.3.8.8 =
|
201 |
* "CSS/JS Manager": If a handle has inline code associated with it, mention the size (e.g. bytes, KB) of that inlined LINK or SCRIPT (just like it's mentioned for the LINK tags with the "href" attribute and SCRIPT tags with the "src" attribute)
|
202 |
* Higher accuracy in detecting (for optimization) the LINK tags that are loading CSS/JS files
|
templates/_admin-page-settings-plugin-areas/_html-source-cleanup.php
CHANGED
@@ -20,14 +20,24 @@ $styleTabContent = ($selectedTabArea === $tabIdArea) ? 'style="display: table-ce
|
|
20 |
<label for="wpacu_remove_rsd_link">Remove "Really Simple Discovery (RSD)" link tag?</label>
|
21 |
</th>
|
22 |
<td>
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
<input id="wpacu_remove_rsd_link" type="checkbox"
|
25 |
<?php echo (($data['remove_rsd_link'] == 1) ? 'checked="checked"' : ''); ?>
|
26 |
name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_rsd_link]"
|
27 |
value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
|
28 |
|
29 |
-
<code><link rel="EditURI" type="application/rsd xml" title="RSD" href="http://yourwebsite.com/xmlrpc.php?rsd" /></code>
|
30 |
-
<p style="margin-top: 10px;">XML-RPC clients use this
|
|
|
|
|
|
|
31 |
</td>
|
32 |
</tr>
|
33 |
|
20 |
<label for="wpacu_remove_rsd_link">Remove "Really Simple Discovery (RSD)" link tag?</label>
|
21 |
</th>
|
22 |
<td>
|
23 |
+
<?php
|
24 |
+
$opacityStyle = '';
|
25 |
+
|
26 |
+
if ($data['disable_xmlrpc'] === 'disable_all') {
|
27 |
+
$opacityStyle = 'opacity: 0.4;';
|
28 |
+
}
|
29 |
+
?>
|
30 |
+
<label class="wpacu_switch" style="<?php echo $opacityStyle; ?>">
|
31 |
<input id="wpacu_remove_rsd_link" type="checkbox"
|
32 |
<?php echo (($data['remove_rsd_link'] == 1) ? 'checked="checked"' : ''); ?>
|
33 |
name="<?php echo WPACU_PLUGIN_ID . '_settings'; ?>[remove_rsd_link]"
|
34 |
value="1" /> <span class="wpacu_slider wpacu_round"></span> </label>
|
35 |
|
36 |
+
<code style="<?php echo $opacityStyle; ?>"><link rel="EditURI" type="application/rsd xml" title="RSD" href="http://yourwebsite.com/xmlrpc.php?rsd" /></code>
|
37 |
+
<p style="margin-top: 10px; <?php echo $opacityStyle; ?>">XML-RPC clients use this discovery method. If you do not know what this is and don't use service integrations such as <a href="http://www.flickr.com/services/api/request.xmlrpc.html">Flickr</a> on your WordPress website, you can remove it.</p>
|
38 |
+
<?php if ($data['disable_xmlrpc'] === 'disable_all') { ?>
|
39 |
+
<p style="margin-top: 10px; color: #cc0000;"><strong>Note:</strong> As you already chosen to completely disable "<a data-wpacu-vertical-link-target="wpacu-setting-disable-xml-rpc" href="#wpacu-setting-disable-xml-rpc">Disable XML-RPC</a>", the "Really Simple Discovery (RSD)" link tag is already removed.</p>
|
40 |
+
<?php } ?>
|
41 |
</td>
|
42 |
</tr>
|
43 |
|
templates/admin-page-settings-bulk-changes.php
CHANGED
@@ -107,19 +107,19 @@ $wpacuTabCurrent = isset($_REQUEST['wpacu_bulk_menu_tab']) && array_key_exists(
|
|
107 |
if ($preloadedStatus === 'async') { echo ' (<strong><em>'.$preloadedStatus.'</em></strong>)'; }
|
108 |
// [/wpacu_pro]
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
<div><a <?php if ($isExternalSrc) { ?> data-wpacu-external-source="<?php echo esc_attr($src . $appendAfterSrc); ?>" <?php } ?> href="<?php echo esc_html($src . $appendAfterSrc); ?>" target="_blank"><small><?php echo str_replace( site_url(), '', $src ); ?></small></a> <?php if ($isExternalSrc) { ?><span data-wpacu-external-source-status></span><?php } ?></div>
|
114 |
-
|
115 |
-
|
116 |
|
117 |
-
|
118 |
-
|
119 |
<small><strong>Note:</strong> <span style="color: darkred;">The plugin `<strong><?php echo esc_html($maybeInactiveAsset['name']); ?></strong>` seems to be inactive, thus any rules set are also inactive & irrelevant, unless you re-activate the plugin.</span></small>
|
120 |
-
|
121 |
<small><strong>Note:</strong> <span style="color: darkred;">The theme `<strong><?php echo esc_html($maybeInactiveAsset['name']); ?></strong>` seems to be inactive, thus any rules set are also inactive & irrelevant, unless you re-activate the theme.</span></small>
|
122 |
-
|
123 |
}
|
124 |
}
|
125 |
}
|
107 |
if ($preloadedStatus === 'async') { echo ' (<strong><em>'.$preloadedStatus.'</em></strong>)'; }
|
108 |
// [/wpacu_pro]
|
109 |
|
110 |
+
if ( $src ) {
|
111 |
+
$appendAfterSrc = strpos($src, '?') === false ? '?'.$verToAppend : '&'.$verToAppend;
|
112 |
+
?>
|
113 |
<div><a <?php if ($isExternalSrc) { ?> data-wpacu-external-source="<?php echo esc_attr($src . $appendAfterSrc); ?>" <?php } ?> href="<?php echo esc_html($src . $appendAfterSrc); ?>" target="_blank"><small><?php echo str_replace( site_url(), '', $src ); ?></small></a> <?php if ($isExternalSrc) { ?><span data-wpacu-external-source-status></span><?php } ?></div>
|
114 |
+
<?php
|
115 |
+
$maybeInactiveAsset = \WpAssetCleanUp\Misc::maybeIsInactiveAsset($src);
|
116 |
|
117 |
+
if (is_array($maybeInactiveAsset) && ! empty($maybeInactiveAsset)) {
|
118 |
+
if ($maybeInactiveAsset['from'] === 'plugin') { ?>
|
119 |
<small><strong>Note:</strong> <span style="color: darkred;">The plugin `<strong><?php echo esc_html($maybeInactiveAsset['name']); ?></strong>` seems to be inactive, thus any rules set are also inactive & irrelevant, unless you re-activate the plugin.</span></small>
|
120 |
+
<?php } elseif ($maybeInactiveAsset['from'] === 'theme') { ?>
|
121 |
<small><strong>Note:</strong> <span style="color: darkred;">The theme `<strong><?php echo esc_html($maybeInactiveAsset['name']); ?></strong>` seems to be inactive, thus any rules set are also inactive & irrelevant, unless you re-activate the theme.</span></small>
|
122 |
+
<?php }
|
123 |
}
|
124 |
}
|
125 |
}
|
templates/meta-box-loaded-assets/_assets-hardcoded-list.php
CHANGED
@@ -18,7 +18,7 @@ if ($totalFoundHardcodedTags === 0) {
|
|
18 |
<?php if (isset($data['print_outer_html']) && $data['print_outer_html']) { ?>
|
19 |
<div class="wpacu-assets-collapsible-wrap wpacu-wrap-area wpacu-hardcoded">
|
20 |
<a class="wpacu-assets-collapsible wpacu-assets-collapsible-active" href="#" style="padding: 15px 15px 15px 44px;">
|
21 |
-
<span class="dashicons dashicons-code-standards"></span> Hardcoded (non-enqueued) Styles & Scripts ➝ Total: <?php echo
|
22 |
</a>
|
23 |
<div class="wpacu-assets-collapsible-content" style="max-height: inherit;">
|
24 |
<?php } ?>
|
@@ -32,14 +32,18 @@ if ($totalFoundHardcodedTags === 0) {
|
|
32 |
<a target="_blank" href="https://codex.wordpress.org/Function_Reference/wp_add_inline_style">wp_add_inline_style()</a>,
|
33 |
<a target="_blank" href="https://developer.wordpress.org/reference/functions/wp_enqueue_script/">wp_enqueue_script()</a>
|
34 |
& <a target="_blank"
|
35 |
-
href="https://developer.wordpress.org/reference/functions/wp_add_inline_script/">wp_add_inline_script()</a>. The tags could have been added via editing the PHP code (not using the right standard functions), directly inside posts content, widgets or via plugins such as "Insert Headers and Footers", "Head, Footer and Post Injections", etc. Be careful when unloading any of these tags as they might be related to Google Analytics/
|
36 |
</p>
|
37 |
<!-- [wpacu_lite] -->
|
38 |
<div style="margin: 20px 0; border-left: solid 4px green; background: #f2faf2; padding: 10px;"><img width="20" height="20" src="<?php echo esc_url(WPACU_PLUGIN_URL); ?>/assets/icons/icon-lock.svg" valign="top" alt="" /> Managing hardcoded LINK/STYLE/SCRIPT tags is an option <a target="_blank" href="<?php echo apply_filters('wpacu_go_pro_affiliate_link', WPACU_PLUGIN_GO_PRO_URL.'?utm_source=manage_hardcoded_assets&utm_medium=top_notice'); ?>">available in the Pro version</a>.</div>
|
39 |
<!-- [/wpacu_lite] -->
|
40 |
</div>
|
41 |
<?php
|
|
|
|
|
42 |
foreach (array('link_and_style_tags', 'script_src_and_inline_tags') as $targetKey) {
|
|
|
|
|
43 |
if ( ! empty( $hardcodedTags[ $targetKey ] ) ) {
|
44 |
$totalTagsForTarget = count( $hardcodedTags[ $targetKey ] );
|
45 |
?>
|
@@ -56,7 +60,7 @@ if ($totalFoundHardcodedTags === 0) {
|
|
56 |
$hardcodedTagsOutput = '';
|
57 |
|
58 |
foreach ( $hardcodedTags[ $targetKey ] as $indexNo => $tagOutput ) {
|
59 |
-
$contentUniqueStr =
|
60 |
|
61 |
/*
|
62 |
* 1) Hardcoded LINK (stylesheet) & STYLE tags
|
@@ -66,9 +70,10 @@ if ($totalFoundHardcodedTags === 0) {
|
|
66 |
if ( stripos( $tagOutput, '<link ' ) === 0 ) {
|
67 |
$generatedHandle = 'wpacu_hardcoded_link_' . $contentUniqueStr;
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
72 |
|
73 |
// No room for any mistakes, do not print the cached files
|
74 |
if (strpos($linkHrefOriginal, \WpAssetCleanUp\OptimiseAssets\OptimizeCommon::getRelPathPluginCacheDir()) !== false) {
|
@@ -76,9 +81,9 @@ if ($totalFoundHardcodedTags === 0) {
|
|
76 |
}
|
77 |
|
78 |
$dataRowObj = (object) array(
|
79 |
-
'handle'
|
80 |
-
'src'
|
81 |
-
'tag_output'
|
82 |
);
|
83 |
|
84 |
$dataRowObj->inside_conditional_comment = \WpAssetCleanUp\HardcodedAssets::isWithinConditionalComment($tagOutput, $contentWithinConditionalComments);
|
@@ -108,9 +113,9 @@ if ($totalFoundHardcodedTags === 0) {
|
|
108 |
$generatedHandle = 'wpacu_hardcoded_style_' . $contentUniqueStr;
|
109 |
|
110 |
$dataRowObj = (object) array(
|
111 |
-
'handle'
|
112 |
-
'src'
|
113 |
-
'tag_output'
|
114 |
);
|
115 |
|
116 |
$dataRowObj->inside_conditional_comment = \WpAssetCleanUp\HardcodedAssets::isWithinConditionalComment($tagOutput, $contentWithinConditionalComments);
|
@@ -135,34 +140,8 @@ if ($totalFoundHardcodedTags === 0) {
|
|
135 |
*/
|
136 |
$generatedHandle = $srcHrefOriginal = $isScriptInline = false;
|
137 |
|
138 |
-
if (
|
139 |
-
$srcHrefOriginal =
|
140 |
-
|
141 |
-
if (\WpAssetCleanUp\Misc::isDOMDocumentOn()) {
|
142 |
-
$domForTag = \WpAssetCleanUp\Misc::initDOMDocument();
|
143 |
-
|
144 |
-
$domForTag->loadHTML( $tagOutput );
|
145 |
-
|
146 |
-
$scriptTagObj = $domForTag->getElementsByTagName( 'script' )->item( 0 );
|
147 |
-
|
148 |
-
if ($scriptTagObj->hasAttributes()) {
|
149 |
-
$scriptAttributes = array();
|
150 |
-
|
151 |
-
foreach ( $scriptTagObj->attributes as $attrObj ) {
|
152 |
-
if ( $attrObj->nodeName === 'src' ) {
|
153 |
-
$srcHrefOriginal = trim( $attrObj->nodeValue );
|
154 |
-
break;
|
155 |
-
}
|
156 |
-
}
|
157 |
-
}
|
158 |
-
} else { // Fallback in case DOMDocument is not active for any reason
|
159 |
-
// only look from <script to >
|
160 |
-
preg_match_all( '#<script(.*?)src=(["\'])' . '(.*)' . '(["\'])(>)#Usmi', $tagOutput, $outputMatches );
|
161 |
-
|
162 |
-
if ( isset( $outputMatches[3][0] ) ) {
|
163 |
-
$srcHrefOriginal = trim( $outputMatches[3][0], '"\'' );
|
164 |
-
}
|
165 |
-
}
|
166 |
}
|
167 |
|
168 |
if ($srcHrefOriginal) {
|
@@ -170,18 +149,19 @@ if ($totalFoundHardcodedTags === 0) {
|
|
170 |
if (strpos($srcHrefOriginal, \WpAssetCleanUp\OptimiseAssets\OptimizeCommon::getRelPathPluginCacheDir()) !== false) {
|
171 |
continue;
|
172 |
}
|
173 |
-
|
174 |
-
$generatedHandle
|
175 |
}
|
176 |
|
177 |
// Is it a SCRIPT without "src" attribute? Then it's an inline one
|
178 |
if (! $generatedHandle) {
|
179 |
-
|
|
|
180 |
}
|
181 |
|
182 |
$dataRowObj = (object)array(
|
183 |
-
'handle'
|
184 |
-
'tag_output'
|
185 |
);
|
186 |
|
187 |
if ($srcHrefOriginal) {
|
18 |
<?php if (isset($data['print_outer_html']) && $data['print_outer_html']) { ?>
|
19 |
<div class="wpacu-assets-collapsible-wrap wpacu-wrap-area wpacu-hardcoded">
|
20 |
<a class="wpacu-assets-collapsible wpacu-assets-collapsible-active" href="#" style="padding: 15px 15px 15px 44px;">
|
21 |
+
<span class="dashicons dashicons-code-standards"></span> Hardcoded (non-enqueued) Styles & Scripts ➝ Total: <?php echo $totalFoundHardcodedTags; ?>
|
22 |
</a>
|
23 |
<div class="wpacu-assets-collapsible-content" style="max-height: inherit;">
|
24 |
<?php } ?>
|
32 |
<a target="_blank" href="https://codex.wordpress.org/Function_Reference/wp_add_inline_style">wp_add_inline_style()</a>,
|
33 |
<a target="_blank" href="https://developer.wordpress.org/reference/functions/wp_enqueue_script/">wp_enqueue_script()</a>
|
34 |
& <a target="_blank"
|
35 |
+
href="https://developer.wordpress.org/reference/functions/wp_add_inline_script/">wp_add_inline_script()</a>. The tags could have been added via editing the PHP code (not using the right standard functions), directly inside posts content, widgets or via plugins such as "Insert Headers and Footers", "Head, Footer and Post Injections", etc. Be careful when unloading any of these tags as they might be related to Google Analytics/Google Ads, StatCounter, Facebook Pixel, etc.
|
36 |
</p>
|
37 |
<!-- [wpacu_lite] -->
|
38 |
<div style="margin: 20px 0; border-left: solid 4px green; background: #f2faf2; padding: 10px;"><img width="20" height="20" src="<?php echo esc_url(WPACU_PLUGIN_URL); ?>/assets/icons/icon-lock.svg" valign="top" alt="" /> Managing hardcoded LINK/STYLE/SCRIPT tags is an option <a target="_blank" href="<?php echo apply_filters('wpacu_go_pro_affiliate_link', WPACU_PLUGIN_GO_PRO_URL.'?utm_source=manage_hardcoded_assets&utm_medium=top_notice'); ?>">available in the Pro version</a>.</div>
|
39 |
<!-- [/wpacu_lite] -->
|
40 |
</div>
|
41 |
<?php
|
42 |
+
$handlesInfo = \WpAssetCleanUp\Main::getHandlesInfo();
|
43 |
+
|
44 |
foreach (array('link_and_style_tags', 'script_src_and_inline_tags') as $targetKey) {
|
45 |
+
$hardcodedTags[ $targetKey ] = array_unique( $hardcodedTags[ $targetKey ] );
|
46 |
+
|
47 |
if ( ! empty( $hardcodedTags[ $targetKey ] ) ) {
|
48 |
$totalTagsForTarget = count( $hardcodedTags[ $targetKey ] );
|
49 |
?>
|
60 |
$hardcodedTagsOutput = '';
|
61 |
|
62 |
foreach ( $hardcodedTags[ $targetKey ] as $indexNo => $tagOutput ) {
|
63 |
+
$contentUniqueStr = \WpAssetCleanUp\HardcodedAssets::determineHardcodedAssetSha1($tagOutput);
|
64 |
|
65 |
/*
|
66 |
* 1) Hardcoded LINK (stylesheet) & STYLE tags
|
70 |
if ( stripos( $tagOutput, '<link ' ) === 0 ) {
|
71 |
$generatedHandle = 'wpacu_hardcoded_link_' . $contentUniqueStr;
|
72 |
|
73 |
+
// could be href="value_here" or href = "value_here" (with extra spaces) / make sure it matches
|
74 |
+
if ( preg_match('#href(\s+|)=(\s+|)#Umi', $tagOutput) ) {
|
75 |
+
$linkHrefOriginal = \WpAssetCleanUp\Misc::getValueFromTag($tagOutput);
|
76 |
+
}
|
77 |
|
78 |
// No room for any mistakes, do not print the cached files
|
79 |
if (strpos($linkHrefOriginal, \WpAssetCleanUp\OptimiseAssets\OptimizeCommon::getRelPathPluginCacheDir()) !== false) {
|
81 |
}
|
82 |
|
83 |
$dataRowObj = (object) array(
|
84 |
+
'handle' => $generatedHandle,
|
85 |
+
'src' => $linkHrefOriginal,
|
86 |
+
'tag_output' => $tagOutput
|
87 |
);
|
88 |
|
89 |
$dataRowObj->inside_conditional_comment = \WpAssetCleanUp\HardcodedAssets::isWithinConditionalComment($tagOutput, $contentWithinConditionalComments);
|
113 |
$generatedHandle = 'wpacu_hardcoded_style_' . $contentUniqueStr;
|
114 |
|
115 |
$dataRowObj = (object) array(
|
116 |
+
'handle' => $generatedHandle,
|
117 |
+
'src' => false,
|
118 |
+
'tag_output' => $tagOutput
|
119 |
);
|
120 |
|
121 |
$dataRowObj->inside_conditional_comment = \WpAssetCleanUp\HardcodedAssets::isWithinConditionalComment($tagOutput, $contentWithinConditionalComments);
|
140 |
*/
|
141 |
$generatedHandle = $srcHrefOriginal = $isScriptInline = false;
|
142 |
|
143 |
+
if ( preg_match('#src(\s+|)=(\s+|)#Umi', $tagOutput) ) {
|
144 |
+
$srcHrefOriginal = \WpAssetCleanUp\Misc::getValueFromTag($tagOutput);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
}
|
146 |
|
147 |
if ($srcHrefOriginal) {
|
149 |
if (strpos($srcHrefOriginal, \WpAssetCleanUp\OptimiseAssets\OptimizeCommon::getRelPathPluginCacheDir()) !== false) {
|
150 |
continue;
|
151 |
}
|
152 |
+
$handlePrefix = 'wpacu_hardcoded_script_src_';
|
153 |
+
$generatedHandle = $handlePrefix . $contentUniqueStr;
|
154 |
}
|
155 |
|
156 |
// Is it a SCRIPT without "src" attribute? Then it's an inline one
|
157 |
if (! $generatedHandle) {
|
158 |
+
$handlePrefix = 'wpacu_hardcoded_script_inline_';
|
159 |
+
$generatedHandle = $handlePrefix . $contentUniqueStr;
|
160 |
}
|
161 |
|
162 |
$dataRowObj = (object)array(
|
163 |
+
'handle' => $generatedHandle,
|
164 |
+
'tag_output' => $tagOutput
|
165 |
);
|
166 |
|
167 |
if ($srcHrefOriginal) {
|
templates/meta-box-loaded-assets/_common/_asset-single-row-load-exceptions.php
CHANGED
@@ -25,7 +25,7 @@ if ($anyUnloadRuleSet || $data['row']['is_load_exception_per_page']) {
|
|
25 |
$loadExceptionOptionsAreaCss = '';
|
26 |
|
27 |
if ($data['row']['global_unloaded']) {
|
28 |
-
// Move it to the right side or extend it to avoid so much empty space and a DIV
|
29 |
$loadExceptionOptionsAreaCss = 'display: contents;';
|
30 |
}
|
31 |
?>
|
@@ -45,7 +45,6 @@ if ($data['row']['global_unloaded']) {
|
|
45 |
value="<?php echo htmlentities(esc_attr($data['row']['obj']->handle), ENT_QUOTES); ?>" />
|
46 |
<span>On this page</span></label>
|
47 |
</li>
|
48 |
-
|
49 |
<?php
|
50 |
if ($data['bulk_unloaded_type'] === 'post_type') {
|
51 |
// Only show it on edit post/page/custom post type
|
@@ -72,13 +71,13 @@ if ($data['row']['global_unloaded']) {
|
|
72 |
</li>
|
73 |
<?php
|
74 |
if (isset($data['post_type']) && $data['post_type'] !== 'attachment' && ! empty($data['post_type_has_tax_assoc'])) {
|
75 |
-
include
|
76 |
}
|
77 |
}
|
78 |
?>
|
79 |
<li>
|
80 |
-
<label for="wpacu_load_it_regex_option_<?php echo $assetTypeS; ?>_<?php echo $data['row']['obj']->handle; ?>"
|
81 |
-
|
82 |
id="wpacu_load_it_regex_option_<?php echo $assetTypeS; ?>_<?php echo $data['row']['obj']->handle; ?>"
|
83 |
class="wpacu_load_it_option_two wpacu_<?php echo $assetTypeS; ?> wpacu_load_exception wpacu_lite_locked"
|
84 |
type="checkbox"
|
@@ -95,18 +94,19 @@ if ($data['row']['global_unloaded']) {
|
|
95 |
href="https://assetcleanup.com/docs/?p=21#wpacu-method-2"><span
|
96 |
class="dashicons dashicons-editor-help"></span></a></label>
|
97 |
</li>
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
|
|
104 |
class="wpacu_load_it_option_three wpacu_<?php echo $assetTypeS; ?> wpacu_load_exception"
|
105 |
type="checkbox"
|
106 |
-
|
107 |
-
name="wpacu_load_it_logged_in[<?php echo $assetType; ?>][<?php echo $data['row']['obj']->handle; ?>]"
|
108 |
value="1"/>
|
109 |
-
<span
|
110 |
</li>
|
111 |
</ul>
|
112 |
<div class="wpacu-clearfix"></div>
|
25 |
$loadExceptionOptionsAreaCss = '';
|
26 |
|
27 |
if ($data['row']['global_unloaded']) {
|
28 |
+
// Move it to the right side or extend it to avoid so much empty space and a higher DIV
|
29 |
$loadExceptionOptionsAreaCss = 'display: contents;';
|
30 |
}
|
31 |
?>
|
45 |
value="<?php echo htmlentities(esc_attr($data['row']['obj']->handle), ENT_QUOTES); ?>" />
|
46 |
<span>On this page</span></label>
|
47 |
</li>
|
|
|
48 |
<?php
|
49 |
if ($data['bulk_unloaded_type'] === 'post_type') {
|
50 |
// Only show it on edit post/page/custom post type
|
71 |
</li>
|
72 |
<?php
|
73 |
if (isset($data['post_type']) && $data['post_type'] !== 'attachment' && ! empty($data['post_type_has_tax_assoc'])) {
|
74 |
+
include '_asset-single-row-load-exceptions-taxonomy.php';
|
75 |
}
|
76 |
}
|
77 |
?>
|
78 |
<li>
|
79 |
+
<label for="wpacu_load_it_regex_option_<?php echo $assetTypeS; ?>_<?php echo htmlentities(esc_attr($data['row']['obj']->handle), ENT_QUOTES); ?>">
|
80 |
+
<input data-handle="<?php echo htmlentities(esc_attr($data['row']['obj']->handle), ENT_QUOTES); ?>"
|
81 |
id="wpacu_load_it_regex_option_<?php echo $assetTypeS; ?>_<?php echo $data['row']['obj']->handle; ?>"
|
82 |
class="wpacu_load_it_option_two wpacu_<?php echo $assetTypeS; ?> wpacu_load_exception wpacu_lite_locked"
|
83 |
type="checkbox"
|
94 |
href="https://assetcleanup.com/docs/?p=21#wpacu-method-2"><span
|
95 |
class="dashicons dashicons-editor-help"></span></a></label>
|
96 |
</li>
|
97 |
+
<?php
|
98 |
+
$isLoadItLoggedIn = in_array($data['row']['obj']->handle, $data['handle_load_logged_in'][$assetType]);
|
99 |
+
if ($isLoadItLoggedIn) { $data['row']['at_least_one_rule_set'] = true; }
|
100 |
+
?>
|
101 |
+
<li id="wpacu_load_it_user_logged_in_option_<?php echo $assetTypeS; ?>_<?php echo htmlentities(esc_attr($data['row']['obj']->handle), ENT_QUOTES); ?>">
|
102 |
+
<label><input data-handle="<?php echo htmlentities(esc_attr($data['row']['obj']->handle), ENT_QUOTES); ?>"
|
103 |
+
id="wpacu_load_it_user_logged_in_option_<?php echo $assetTypeS; ?>_<?php echo htmlentities(esc_attr($data['row']['obj']->handle), ENT_QUOTES); ?>"
|
104 |
class="wpacu_load_it_option_three wpacu_<?php echo $assetTypeS; ?> wpacu_load_exception"
|
105 |
type="checkbox"
|
106 |
+
<?php if ($isLoadItLoggedIn) { ?> checked="checked" <?php } ?>
|
107 |
+
name="wpacu_load_it_logged_in[<?php echo $assetType; ?>][<?php echo htmlentities(esc_attr($data['row']['obj']->handle), ENT_QUOTES); ?>]"
|
108 |
value="1"/>
|
109 |
+
<span><?php esc_html_e('If the user is logged-in', 'wp-asset-clean-up'); ?></span></label>
|
110 |
</li>
|
111 |
</ul>
|
112 |
<div class="wpacu-clearfix"></div>
|
wpacu.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/*
|
3 |
* Plugin Name: Asset CleanUp: Page Speed Booster
|
4 |
* Plugin URI: https://wordpress.org/plugins/wp-asset-clean-up/
|
5 |
-
* Version: 1.3.8.
|
6 |
* Requires at least: 4.5
|
7 |
* Requires PHP: 5.6
|
8 |
* Description: Unload Chosen Scripts & Styles from Posts/Pages to reduce HTTP Requests, Combine/Minify CSS/JS files
|
@@ -29,7 +29,7 @@ if ( (defined('WPACU_PRO_NO_LITE_NEEDED') && WPACU_PRO_NO_LITE_NEEDED !== false
|
|
29 |
|
30 |
// Is the Pro version triggered before the Lite one and are both plugins active?
|
31 |
if (! defined('WPACU_PLUGIN_VERSION')) {
|
32 |
-
define('WPACU_PLUGIN_VERSION', '1.3.8.
|
33 |
}
|
34 |
|
35 |
// Exit if accessed directly
|
2 |
/*
|
3 |
* Plugin Name: Asset CleanUp: Page Speed Booster
|
4 |
* Plugin URI: https://wordpress.org/plugins/wp-asset-clean-up/
|
5 |
+
* Version: 1.3.8.9
|
6 |
* Requires at least: 4.5
|
7 |
* Requires PHP: 5.6
|
8 |
* Description: Unload Chosen Scripts & Styles from Posts/Pages to reduce HTTP Requests, Combine/Minify CSS/JS files
|
29 |
|
30 |
// Is the Pro version triggered before the Lite one and are both plugins active?
|
31 |
if (! defined('WPACU_PLUGIN_VERSION')) {
|
32 |
+
define('WPACU_PLUGIN_VERSION', '1.3.8.9');
|
33 |
}
|
34 |
|
35 |
// Exit if accessed directly
|