Version Description
- Oct 18 2018 =
- : Added the ability to Reset All Options.
-
CLI: Added new
lscache-admin reset_options
command. - GUI: Added shortcuts for more of the Settings tabs.
- Media: Updated Lazy Load JS library to the most recent version.
- There is no longer any need to explicitly Save Settings upon Import.
- Remove Query String now will remove all query strings in JS/CSS static files.
- IAPI: Added summary info to debug log.
Download this release
Release Info
Developer | LiteSpeedTech |
Plugin | LiteSpeed Cache |
Version | 2.6.3 |
Comparing to | |
See all releases |
Code changes from version 2.6.2 to 2.6.3
- admin/tpl/import_export.php +10 -0
- admin/tpl/settings.php +29 -2
- cli/litespeed-cache-cli-admin.class.php +20 -0
- css/litespeed.css +6 -0
- inc/const.cls.php +6 -0
- inc/img_optm.class.php +1 -0
- inc/import.class.php +64 -4
- inc/litespeed-cache.class.php +1 -1
- inc/optimize.class.php +3 -3
- includes/litespeed-cache-optimize.class.php +3 -3
- includes/litespeed-cache.class.php +1 -1
- js/lazyload.lib.js +308 -123
- js/lazyload.min.js +1 -1
- languages/litespeed-cache.pot +42 -26
- litespeed-cache.php +1 -1
- readme.txt +11 -2
admin/tpl/import_export.php
CHANGED
@@ -55,5 +55,15 @@ $log = get_option( LiteSpeed_Cache_Import::DB_IMPORT_LOG, array() ) ;
|
|
55 |
<?php echo __( 'This will import settings from a file and override all current LiteSpeed Cache settings.', 'litespeed-cache' ) ; ?>
|
56 |
</div>
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
</div>
|
59 |
</div>
|
55 |
<?php echo __( 'This will import settings from a file and override all current LiteSpeed Cache settings.', 'litespeed-cache' ) ; ?>
|
56 |
</div>
|
57 |
|
58 |
+
<h3 class="litespeed-title"><?php echo __('Reset All Settings', 'litespeed-cache') ; ?></h3>
|
59 |
+
|
60 |
+
<a href="<?php echo LiteSpeed_Cache_Utility::build_url( LiteSpeed_Cache::ACTION_IMPORT, LiteSpeed_Cache_Import::TYPE_RESET ) ; ?>" data-litespeed-cfm="<?php echo __( 'Are you sure to reset all settings to default settings?', 'litespeed-cache' ) ; ?>" class="litespeed-btn-danger">
|
61 |
+
<?php echo __( 'Reset', 'litespeed-cache' ) ; ?>
|
62 |
+
</a>
|
63 |
+
|
64 |
+
<div class="litespeed-desc">
|
65 |
+
<?php echo __( 'This will reset all settings to default settings.', 'litespeed-cache' ) ; ?>
|
66 |
+
</div>
|
67 |
+
|
68 |
</div>
|
69 |
</div>
|
admin/tpl/settings.php
CHANGED
@@ -132,16 +132,40 @@ if ( ! $adv_mode ) {
|
|
132 |
<h2 class="litespeed-header">
|
133 |
<?php
|
134 |
$i = 1 ;
|
|
|
135 |
foreach ($menu_list as $tab => $val){
|
136 |
if ( in_array( $tab, $hide_tabs ) ) {
|
137 |
continue ;
|
138 |
}
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
echo "<a class='litespeed-tab' href='#$tab' data-litespeed-tab='$tab' $accesskey>$val</a>" ;
|
141 |
$i ++ ;
|
142 |
}
|
143 |
foreach ($tp_tabs as $val){
|
144 |
-
$accesskey =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
echo "<a class='litespeed-tab' href='#$val[slug]' data-litespeed-tab='$val[slug]' $accesskey>$val[title]</a>" ;
|
146 |
$i ++ ;
|
147 |
}
|
@@ -190,6 +214,9 @@ if ( ! $adv_mode ) {
|
|
190 |
}
|
191 |
|
192 |
?>
|
|
|
|
|
|
|
193 |
</form>
|
194 |
</div>
|
195 |
</div>
|
132 |
<h2 class="litespeed-header">
|
133 |
<?php
|
134 |
$i = 1 ;
|
135 |
+
$accesskey_set = array() ;
|
136 |
foreach ($menu_list as $tab => $val){
|
137 |
if ( in_array( $tab, $hide_tabs ) ) {
|
138 |
continue ;
|
139 |
}
|
140 |
+
|
141 |
+
$accesskey = '' ;
|
142 |
+
if ( $i <= 9 ) {
|
143 |
+
$accesskey = "litespeed-accesskey='$i'" ;
|
144 |
+
}
|
145 |
+
else {
|
146 |
+
$tmp = strtoupper( substr( $val, 0, 1 ) ) ;
|
147 |
+
if ( ! in_array( $tmp, $accesskey_set ) ) {
|
148 |
+
$accesskey_set[] = $tmp ;
|
149 |
+
$accesskey = "litespeed-accesskey='$tmp'" ;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
echo "<a class='litespeed-tab' href='#$tab' data-litespeed-tab='$tab' $accesskey>$val</a>" ;
|
154 |
$i ++ ;
|
155 |
}
|
156 |
foreach ($tp_tabs as $val){
|
157 |
+
$accesskey = '' ;
|
158 |
+
if ( $i <= 9 ) {
|
159 |
+
$accesskey = "litespeed-accesskey='$i'" ;
|
160 |
+
}
|
161 |
+
else {
|
162 |
+
$tmp = strtoupper( substr( $val[ 'title' ], 0, 1 ) ) ;
|
163 |
+
if ( ! in_array( $tmp, $accesskey_set ) ) {
|
164 |
+
$accesskey_set[] = $tmp ;
|
165 |
+
$accesskey = "litespeed-accesskey='$tmp'" ;
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
echo "<a class='litespeed-tab' href='#$val[slug]' data-litespeed-tab='$val[slug]' $accesskey>$val[title]</a>" ;
|
170 |
$i ++ ;
|
171 |
}
|
214 |
}
|
215 |
|
216 |
?>
|
217 |
+
|
218 |
+
<a href="admin.php?page=lscache-import" class="litespeed-btn-danger litespeed-float-resetbtn"><?php echo __( 'Reset All Settings', 'litespeed-cache' ) ; ?></a>
|
219 |
+
|
220 |
</form>
|
221 |
</div>
|
222 |
</div>
|
cli/litespeed-cache-cli-admin.class.php
CHANGED
@@ -254,6 +254,26 @@ class LiteSpeed_Cache_Cli_Admin
|
|
254 |
WP_CLI::success( 'Options imported. [File] ' . $file ) ;
|
255 |
}
|
256 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
/**
|
258 |
* Update options
|
259 |
*
|
254 |
WP_CLI::success( 'Options imported. [File] ' . $file ) ;
|
255 |
}
|
256 |
|
257 |
+
/**
|
258 |
+
* Reset all options to default.
|
259 |
+
*
|
260 |
+
* ## EXAMPLES
|
261 |
+
*
|
262 |
+
* # Reset all options
|
263 |
+
* $ wp lscache-admin reset_options
|
264 |
+
*
|
265 |
+
*/
|
266 |
+
public function reset_options()
|
267 |
+
{
|
268 |
+
$res = LiteSpeed_Cache_Import::get_instance()->reset( $file ) ;
|
269 |
+
|
270 |
+
if ( ! $res ) {
|
271 |
+
WP_CLI::error( 'Failed to reset options.' ) ;
|
272 |
+
}
|
273 |
+
|
274 |
+
WP_CLI::success( 'Options reset.' ) ;
|
275 |
+
}
|
276 |
+
|
277 |
/**
|
278 |
* Update options
|
279 |
*
|
css/litespeed.css
CHANGED
@@ -1797,6 +1797,12 @@ input.litespeed-input[type="file"]{
|
|
1797 |
margin-top: 0;
|
1798 |
}
|
1799 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1800 |
.litespeed input,
|
1801 |
.litespeed-body input,
|
1802 |
.litespeed-body textarea {
|
1797 |
margin-top: 0;
|
1798 |
}
|
1799 |
|
1800 |
+
.litespeed-wrap .litespeed-float-resetbtn {
|
1801 |
+
position: absolute;
|
1802 |
+
right: 10px;
|
1803 |
+
bottom: 20px;
|
1804 |
+
}
|
1805 |
+
|
1806 |
.litespeed input,
|
1807 |
.litespeed-body input,
|
1808 |
.litespeed-body textarea {
|
inc/const.cls.php
CHANGED
@@ -295,6 +295,12 @@ class LiteSpeed_Cache_Const
|
|
295 |
"div.data-large_image\n" .
|
296 |
"img.retina_logo_url" ;
|
297 |
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
default :
|
299 |
break ;
|
300 |
}
|
295 |
"div.data-large_image\n" .
|
296 |
"img.retina_logo_url" ;
|
297 |
|
298 |
+
case self::ITEM_LOG_IGNORE_FILTERS :
|
299 |
+
return "gettext\ngettext_with_context\nget_the_terms\nget_term" ;
|
300 |
+
|
301 |
+
case self::ITEM_LOG_IGNORE_PART_FILTERS :
|
302 |
+
return "i18n\nlocale\nsettings\noption" ;
|
303 |
+
|
304 |
default :
|
305 |
break ;
|
306 |
}
|
inc/img_optm.class.php
CHANGED
@@ -1234,6 +1234,7 @@ class LiteSpeed_Cache_Img_Optm
|
|
1234 |
$data = array() ;
|
1235 |
|
1236 |
$data[ 'img_count' ] = $this->img_count() ;
|
|
|
1237 |
|
1238 |
$data[ '_wp_attached_file' ] = get_post_meta( $pid, '_wp_attached_file', true ) ;
|
1239 |
$data[ '_wp_attachment_metadata' ] = get_post_meta( $pid, '_wp_attachment_metadata', true ) ;
|
1234 |
$data = array() ;
|
1235 |
|
1236 |
$data[ 'img_count' ] = $this->img_count() ;
|
1237 |
+
$data[ 'optm_summary' ] = $this->summary_info() ;
|
1238 |
|
1239 |
$data[ '_wp_attached_file' ] = get_post_meta( $pid, '_wp_attached_file', true ) ;
|
1240 |
$data[ '_wp_attachment_metadata' ] = get_post_meta( $pid, '_wp_attachment_metadata', true ) ;
|
inc/import.class.php
CHANGED
@@ -17,9 +17,11 @@ class LiteSpeed_Cache_Import
|
|
17 |
private static $_instance ;
|
18 |
|
19 |
private $_cfg_items ;
|
|
|
20 |
|
21 |
const TYPE_IMPORT = 'import' ;
|
22 |
const TYPE_EXPORT = 'export' ;
|
|
|
23 |
|
24 |
const DB_IMPORT_LOG = 'litespeed_import_log' ;
|
25 |
|
@@ -33,7 +35,9 @@ class LiteSpeed_Cache_Import
|
|
33 |
{
|
34 |
LiteSpeed_Cache_Log::debug( 'Import init' ) ;
|
35 |
|
36 |
-
$this->
|
|
|
|
|
37 |
}
|
38 |
|
39 |
/**
|
@@ -57,6 +61,10 @@ class LiteSpeed_Cache_Import
|
|
57 |
$instance->_export() ;
|
58 |
break ;
|
59 |
|
|
|
|
|
|
|
|
|
60 |
default:
|
61 |
break ;
|
62 |
}
|
@@ -171,12 +179,23 @@ class LiteSpeed_Cache_Import
|
|
171 |
return false ;
|
172 |
}
|
173 |
|
|
|
174 |
foreach ( $this->_cfg_items as $v ) {
|
175 |
-
|
176 |
-
update_option( $v, $data[ $v ] ) ;
|
177 |
-
}
|
178 |
}
|
179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
|
181 |
if ( ! $file ) {
|
182 |
LiteSpeed_Cache_Log::debug( 'Import: Imported ' . $_FILES[ 'ls_file' ][ 'name' ] ) ;
|
@@ -188,10 +207,51 @@ class LiteSpeed_Cache_Import
|
|
188 |
LiteSpeed_Cache_Log::debug( 'Import: Imported ' . $file ) ;
|
189 |
}
|
190 |
|
|
|
|
|
191 |
return true ;
|
192 |
|
193 |
}
|
194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
/**
|
196 |
* Generate the filename to export
|
197 |
*
|
17 |
private static $_instance ;
|
18 |
|
19 |
private $_cfg_items ;
|
20 |
+
private $__cfg ;
|
21 |
|
22 |
const TYPE_IMPORT = 'import' ;
|
23 |
const TYPE_EXPORT = 'export' ;
|
24 |
+
const TYPE_RESET = 'reset' ;
|
25 |
|
26 |
const DB_IMPORT_LOG = 'litespeed_import_log' ;
|
27 |
|
35 |
{
|
36 |
LiteSpeed_Cache_Log::debug( 'Import init' ) ;
|
37 |
|
38 |
+
$this->__cfg = LiteSpeed_Cache_Config::get_instance() ;
|
39 |
+
|
40 |
+
$this->_cfg_items = $this->__cfg->stored_items() ;
|
41 |
}
|
42 |
|
43 |
/**
|
61 |
$instance->_export() ;
|
62 |
break ;
|
63 |
|
64 |
+
case self::TYPE_RESET :
|
65 |
+
$instance->_reset() ;
|
66 |
+
break ;
|
67 |
+
|
68 |
default:
|
69 |
break ;
|
70 |
}
|
179 |
return false ;
|
180 |
}
|
181 |
|
182 |
+
$options = $data[ LiteSpeed_Cache_Config::OPTION_NAME ] ;
|
183 |
foreach ( $this->_cfg_items as $v ) {
|
184 |
+
$options[ $v ] = $data[ $v ] ;
|
|
|
|
|
185 |
}
|
186 |
|
187 |
+
$options = LiteSpeed_Cache_Config::convert_options_to_input( $options ) ;
|
188 |
+
|
189 |
+
$output = LiteSpeed_Cache_Admin_Settings::get_instance()->validate_plugin_settings( $options ) ;
|
190 |
+
|
191 |
+
global $wp_settings_errors ;
|
192 |
+
if ( ! empty( $wp_settings_errors ) ) {
|
193 |
+
foreach ( $wp_settings_errors as $err ) {
|
194 |
+
LiteSpeed_Cache_Admin_Display::error( $err[ 'message' ] ) ;
|
195 |
+
LiteSpeed_Cache_Log::debug( '[Import] err ' . $err[ 'message' ] ) ;
|
196 |
+
}
|
197 |
+
return false ;
|
198 |
+
}
|
199 |
|
200 |
if ( ! $file ) {
|
201 |
LiteSpeed_Cache_Log::debug( 'Import: Imported ' . $_FILES[ 'ls_file' ][ 'name' ] ) ;
|
207 |
LiteSpeed_Cache_Log::debug( 'Import: Imported ' . $file ) ;
|
208 |
}
|
209 |
|
210 |
+
$ret = $this->__cfg->update_options( $output ) ;
|
211 |
+
|
212 |
return true ;
|
213 |
|
214 |
}
|
215 |
|
216 |
+
/**
|
217 |
+
* Reset all settings
|
218 |
+
*
|
219 |
+
* @since 2.6.3
|
220 |
+
*/
|
221 |
+
public function reset()
|
222 |
+
{
|
223 |
+
return $this->_reset() ;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Reset all configs to default values.
|
228 |
+
*
|
229 |
+
* @since 2.6.3
|
230 |
+
* @access private
|
231 |
+
*/
|
232 |
+
private function _reset()
|
233 |
+
{
|
234 |
+
$options = $this->__cfg->get_default_options() ;
|
235 |
+
// Get items
|
236 |
+
$cfg_items = $this->__cfg->stored_items() ;
|
237 |
+
foreach ( $cfg_items as $v ) {
|
238 |
+
$options[ $v ] = $this->__cfg->default_item( $v ) ;
|
239 |
+
}
|
240 |
+
|
241 |
+
$options = LiteSpeed_Cache_Config::convert_options_to_input( $options ) ;
|
242 |
+
|
243 |
+
$output = LiteSpeed_Cache_Admin_Settings::get_instance()->validate_plugin_settings( $options ) ;
|
244 |
+
|
245 |
+
$ret = $this->__cfg->update_options( $output ) ;
|
246 |
+
|
247 |
+
LiteSpeed_Cache_Log::debug( '[Import] Reset successfully.' ) ;
|
248 |
+
|
249 |
+
$msg = __( 'Reset successfully.', 'litespeed-cache' ) ;
|
250 |
+
LiteSpeed_Cache_Admin_Display::succeed( $msg ) ;
|
251 |
+
|
252 |
+
return true ;
|
253 |
+
}
|
254 |
+
|
255 |
/**
|
256 |
* Generate the filename to export
|
257 |
*
|
inc/litespeed-cache.class.php
CHANGED
@@ -25,7 +25,7 @@ class LiteSpeed_Cache
|
|
25 |
|
26 |
const NAME = 'LiteSpeed Cache' ;
|
27 |
const PLUGIN_NAME = 'litespeed-cache' ;
|
28 |
-
const PLUGIN_VERSION = '2.6.
|
29 |
|
30 |
const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
|
31 |
|
25 |
|
26 |
const NAME = 'LiteSpeed Cache' ;
|
27 |
const PLUGIN_NAME = 'litespeed-cache' ;
|
28 |
+
const PLUGIN_VERSION = '2.6.3' ;
|
29 |
|
30 |
const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
|
31 |
|
inc/optimize.class.php
CHANGED
@@ -290,9 +290,9 @@ class LiteSpeed_Cache_Optimize
|
|
290 |
*/
|
291 |
public function remove_query_strings( $src )
|
292 |
{
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
return $src ;
|
297 |
}
|
298 |
|
290 |
*/
|
291 |
public function remove_query_strings( $src )
|
292 |
{
|
293 |
+
if ( strpos( $src, '.js?' ) !== false || strpos( $src, '.css?' ) !== false ) {
|
294 |
+
$src = preg_replace( '/\?.*/', '', $src ) ;
|
295 |
+
}
|
296 |
return $src ;
|
297 |
}
|
298 |
|
includes/litespeed-cache-optimize.class.php
CHANGED
@@ -290,9 +290,9 @@ class LiteSpeed_Cache_Optimize
|
|
290 |
*/
|
291 |
public function remove_query_strings( $src )
|
292 |
{
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
return $src ;
|
297 |
}
|
298 |
|
290 |
*/
|
291 |
public function remove_query_strings( $src )
|
292 |
{
|
293 |
+
if ( strpos( $src, '.js?' ) !== false || strpos( $src, '.css?' ) !== false ) {
|
294 |
+
$src = preg_replace( '/\?.*/', '', $src ) ;
|
295 |
+
}
|
296 |
return $src ;
|
297 |
}
|
298 |
|
includes/litespeed-cache.class.php
CHANGED
@@ -25,7 +25,7 @@ class LiteSpeed_Cache
|
|
25 |
|
26 |
const NAME = 'LiteSpeed Cache' ;
|
27 |
const PLUGIN_NAME = 'litespeed-cache' ;
|
28 |
-
const PLUGIN_VERSION = '2.6.
|
29 |
|
30 |
const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
|
31 |
|
25 |
|
26 |
const NAME = 'LiteSpeed Cache' ;
|
27 |
const PLUGIN_NAME = 'litespeed-cache' ;
|
28 |
+
const PLUGIN_VERSION = '2.6.3' ;
|
29 |
|
30 |
const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
|
31 |
|
js/lazyload.lib.js
CHANGED
@@ -11,43 +11,95 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol
|
|
11 |
elements_selector: "img",
|
12 |
container: document,
|
13 |
threshold: 300,
|
|
|
14 |
data_src: "src",
|
15 |
data_srcset: "srcset",
|
16 |
data_sizes: "sizes",
|
|
|
17 |
class_loading: "loading",
|
18 |
class_loaded: "loaded",
|
19 |
class_error: "error",
|
|
|
20 |
callback_load: null,
|
21 |
callback_error: null,
|
22 |
-
callback_set: null
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
};
|
24 |
|
25 |
var dataPrefix = "data-";
|
|
|
|
|
|
|
26 |
|
27 |
var getData = function getData(element, attribute) {
|
28 |
return element.getAttribute(dataPrefix + attribute);
|
29 |
};
|
30 |
|
31 |
var setData = function setData(element, attribute, value) {
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
};
|
34 |
|
35 |
-
var
|
36 |
return elements.filter(function (element) {
|
37 |
-
return
|
38 |
});
|
39 |
};
|
40 |
|
41 |
/* Creates instance and notifies it through the window element */
|
42 |
var createInstance = function createInstance(classObj, options) {
|
|
|
|
|
43 |
var instance = new classObj(options);
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
window.dispatchEvent(event);
|
46 |
};
|
47 |
|
48 |
/* Auto initialization of one or more instances of lazyload, depending on the
|
49 |
-
|
50 |
-
|
|
|
|
|
|
|
51 |
if (!options.length) {
|
52 |
// Plain object
|
53 |
createInstance(classObj, options);
|
@@ -57,74 +109,114 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol
|
|
57 |
createInstance(classObj, optionsItem);
|
58 |
}
|
59 |
}
|
|
|
|
|
|
|
|
|
60 |
};
|
61 |
|
62 |
-
var
|
63 |
-
var
|
64 |
-
var
|
65 |
|
66 |
-
|
67 |
-
|
68 |
-
return;
|
69 |
}
|
70 |
-
for (var i = 0, pictureChild; pictureChild = parent.children[i]; i += 1) {
|
71 |
-
if (pictureChild.tagName === "SOURCE") {
|
72 |
-
var sourceSrcset = getData(pictureChild, dataSrcSet);
|
73 |
-
if (sourceSrcset) {
|
74 |
-
pictureChild.setAttribute("srcset", sourceSrcset);
|
75 |
-
}
|
76 |
|
77 |
-
|
78 |
-
* Add data-sizes attr
|
79 |
-
* @since 1.5
|
80 |
-
*/
|
81 |
-
var source_data_sizes = getData( pictureChild, data_sizes ) ;
|
82 |
-
if ( source_data_sizes ) {
|
83 |
-
pictureChild.setAttribute( "sizes", source_data_sizes ) ;
|
84 |
-
}
|
85 |
-
}
|
86 |
-
}
|
87 |
};
|
88 |
|
89 |
-
var
|
90 |
-
var dataSrc = settings.data_src,
|
91 |
-
dataSrcSet = settings.data_srcset;
|
92 |
-
var data_sizes = settings.data_sizes ;
|
93 |
|
94 |
-
|
95 |
-
var elementSrc = getData(element, dataSrc);
|
96 |
-
if (tagName === "IMG") {
|
97 |
-
setSourcesForPicture(element, settings);
|
98 |
-
var imgSrcset = getData(element, dataSrcSet);
|
99 |
-
if (imgSrcset) {
|
100 |
-
element.setAttribute("srcset", imgSrcset);
|
101 |
-
}
|
102 |
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
if (
|
112 |
-
|
|
|
113 |
}
|
114 |
-
return;
|
115 |
}
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
return;
|
121 |
}
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
};
|
126 |
|
127 |
-
var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
|
129 |
var addClass = function addClass(element, className) {
|
130 |
if (supportsClassList) {
|
@@ -142,121 +234,214 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol
|
|
142 |
element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " ").replace(/^\s+/, "").replace(/\s+$/, "");
|
143 |
};
|
144 |
|
145 |
-
var
|
146 |
if (callback) {
|
147 |
callback(argument);
|
148 |
}
|
149 |
};
|
150 |
|
151 |
-
var
|
152 |
-
var
|
|
|
153 |
|
154 |
-
var
|
155 |
-
element.
|
156 |
-
element.removeEventListener(errorString, errorHandler);
|
157 |
};
|
158 |
|
159 |
-
var
|
160 |
-
|
161 |
-
onEvent(event, true, settings);
|
162 |
-
removeListeners(element, onLoad, onError);
|
163 |
-
};
|
164 |
-
var onError = function onError(event) {
|
165 |
-
onEvent(event, false, settings);
|
166 |
-
removeListeners(element, onLoad, onError);
|
167 |
-
};
|
168 |
-
element.addEventListener(loadString, onLoad);
|
169 |
-
element.addEventListener(errorString, onError);
|
170 |
};
|
171 |
|
172 |
-
var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
var element = event.target;
|
|
|
174 |
removeClass(element, settings.class_loading);
|
175 |
-
addClass(element,
|
176 |
-
|
|
|
|
|
177 |
};
|
178 |
|
179 |
-
var
|
180 |
-
|
181 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
addClass(element, settings.class_loading);
|
183 |
}
|
184 |
-
setSources(element,
|
185 |
-
|
186 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
};
|
188 |
|
189 |
-
var
|
190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
this._setObserver();
|
|
|
192 |
this.update(elements);
|
193 |
};
|
194 |
|
195 |
LazyLoad.prototype = {
|
196 |
-
|
197 |
-
var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
200 |
return;
|
201 |
}
|
|
|
|
|
202 |
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
if (entry.isIntersecting || entry.intersectionRatio > 0) {
|
209 |
-
var element = entry.target;
|
210 |
-
revealElement(element, settings);
|
211 |
-
_this._observer.unobserve(element);
|
212 |
-
}
|
213 |
-
});
|
214 |
-
_this._elements = purgeElements(_this._elements);
|
215 |
-
};
|
216 |
-
this._observer = new IntersectionObserver(onIntersection, {
|
217 |
-
root: settings.container === document ? null : settings.container,
|
218 |
-
rootMargin: settings.threshold + "px"
|
219 |
-
});
|
220 |
},
|
221 |
|
222 |
update: function update(elements) {
|
223 |
-
var
|
224 |
|
225 |
var settings = this._settings;
|
226 |
var nodeSet = elements || settings.container.querySelectorAll(settings.elements_selector);
|
227 |
|
228 |
-
this._elements =
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
return;
|
234 |
}
|
235 |
-
|
236 |
this._elements.forEach(function (element) {
|
237 |
-
|
238 |
});
|
239 |
-
this._elements = purgeElements(this._elements);
|
240 |
},
|
241 |
|
242 |
destroy: function destroy() {
|
243 |
-
var
|
244 |
|
245 |
if (this._observer) {
|
246 |
-
|
247 |
-
|
248 |
});
|
249 |
this._observer = null;
|
250 |
}
|
251 |
this._elements = null;
|
252 |
this._settings = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
}
|
254 |
};
|
255 |
|
256 |
-
/* Automatic instances creation if required (useful for async script loading
|
257 |
-
|
258 |
-
|
259 |
-
autoInitialize(LazyLoad, autoInitOptions);
|
260 |
}
|
261 |
|
262 |
return LazyLoad;
|
11 |
elements_selector: "img",
|
12 |
container: document,
|
13 |
threshold: 300,
|
14 |
+
thresholds: null,
|
15 |
data_src: "src",
|
16 |
data_srcset: "srcset",
|
17 |
data_sizes: "sizes",
|
18 |
+
data_bg: "bg",
|
19 |
class_loading: "loading",
|
20 |
class_loaded: "loaded",
|
21 |
class_error: "error",
|
22 |
+
load_delay: 0,
|
23 |
callback_load: null,
|
24 |
callback_error: null,
|
25 |
+
callback_set: null,
|
26 |
+
callback_enter: null,
|
27 |
+
callback_finish: null,
|
28 |
+
to_webp: false
|
29 |
+
};
|
30 |
+
|
31 |
+
var getInstanceSettings = function getInstanceSettings(customSettings) {
|
32 |
+
return _extends({}, defaultSettings, customSettings);
|
33 |
};
|
34 |
|
35 |
var dataPrefix = "data-";
|
36 |
+
var processedDataName = "was-processed";
|
37 |
+
var timeoutDataName = "ll-timeout";
|
38 |
+
var trueString = "true";
|
39 |
|
40 |
var getData = function getData(element, attribute) {
|
41 |
return element.getAttribute(dataPrefix + attribute);
|
42 |
};
|
43 |
|
44 |
var setData = function setData(element, attribute, value) {
|
45 |
+
var attrName = dataPrefix + attribute;
|
46 |
+
if (value === null) {
|
47 |
+
element.removeAttribute(attrName);
|
48 |
+
return;
|
49 |
+
}
|
50 |
+
element.setAttribute(attrName, value);
|
51 |
+
};
|
52 |
+
|
53 |
+
var setWasProcessedData = function setWasProcessedData(element) {
|
54 |
+
return setData(element, processedDataName, trueString);
|
55 |
+
};
|
56 |
+
|
57 |
+
var getWasProcessedData = function getWasProcessedData(element) {
|
58 |
+
return getData(element, processedDataName) === trueString;
|
59 |
+
};
|
60 |
+
|
61 |
+
var setTimeoutData = function setTimeoutData(element, value) {
|
62 |
+
return setData(element, timeoutDataName, value);
|
63 |
+
};
|
64 |
+
|
65 |
+
var getTimeoutData = function getTimeoutData(element) {
|
66 |
+
return getData(element, timeoutDataName);
|
67 |
+
};
|
68 |
+
|
69 |
+
var purgeProcessedElements = function purgeProcessedElements(elements) {
|
70 |
+
return elements.filter(function (element) {
|
71 |
+
return !getWasProcessedData(element);
|
72 |
+
});
|
73 |
};
|
74 |
|
75 |
+
var purgeOneElement = function purgeOneElement(elements, elementToPurge) {
|
76 |
return elements.filter(function (element) {
|
77 |
+
return element !== elementToPurge;
|
78 |
});
|
79 |
};
|
80 |
|
81 |
/* Creates instance and notifies it through the window element */
|
82 |
var createInstance = function createInstance(classObj, options) {
|
83 |
+
var event;
|
84 |
+
var eventString = "LazyLoad::Initialized";
|
85 |
var instance = new classObj(options);
|
86 |
+
try {
|
87 |
+
// Works in modern browsers
|
88 |
+
event = new CustomEvent(eventString, { detail: { instance: instance } });
|
89 |
+
} catch (err) {
|
90 |
+
// Works in Internet Explorer (all versions)
|
91 |
+
event = document.createEvent("CustomEvent");
|
92 |
+
event.initCustomEvent(eventString, false, false, { instance: instance });
|
93 |
+
}
|
94 |
window.dispatchEvent(event);
|
95 |
};
|
96 |
|
97 |
/* Auto initialization of one or more instances of lazyload, depending on the
|
98 |
+
options passed in (plain object or an array) */
|
99 |
+
function autoInitialize(classObj, options) {
|
100 |
+
if (!options) {
|
101 |
+
return;
|
102 |
+
}
|
103 |
if (!options.length) {
|
104 |
// Plain object
|
105 |
createInstance(classObj, options);
|
109 |
createInstance(classObj, optionsItem);
|
110 |
}
|
111 |
}
|
112 |
+
}
|
113 |
+
|
114 |
+
var replaceExtToWebp = function replaceExtToWebp(value, condition) {
|
115 |
+
return condition ? value.replace(/\.(jpe?g|png)/gi, ".webp") : value;
|
116 |
};
|
117 |
|
118 |
+
var detectWebp = function detectWebp() {
|
119 |
+
var webpString = "image/webp";
|
120 |
+
var canvas = document.createElement("canvas");
|
121 |
|
122 |
+
if (canvas.getContext && canvas.getContext("2d")) {
|
123 |
+
return canvas.toDataURL(webpString).indexOf('data:' + webpString) === 0;
|
|
|
124 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
|
126 |
+
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
};
|
128 |
|
129 |
+
var runningOnBrowser = typeof window !== "undefined";
|
|
|
|
|
|
|
130 |
|
131 |
+
var isBot = runningOnBrowser && !("onscroll" in window) || /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
|
133 |
+
var supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window;
|
134 |
+
|
135 |
+
var supportsClassList = runningOnBrowser && "classList" in document.createElement("p");
|
136 |
+
|
137 |
+
var supportsWebp = runningOnBrowser && detectWebp();
|
138 |
+
|
139 |
+
var setSourcesInChildren = function setSourcesInChildren(parentTag, attrName, dataAttrName, toWebpFlag) {
|
140 |
+
for (var i = 0, childTag; childTag = parentTag.children[i]; i += 1) {
|
141 |
+
if (childTag.tagName === "SOURCE") {
|
142 |
+
var attrValue = getData(childTag, dataAttrName);
|
143 |
+
setAttributeIfValue(childTag, attrName, attrValue, toWebpFlag);
|
144 |
}
|
|
|
145 |
}
|
146 |
+
};
|
147 |
+
|
148 |
+
var setAttributeIfValue = function setAttributeIfValue(element, attrName, value, toWebpFlag) {
|
149 |
+
if (!value) {
|
150 |
return;
|
151 |
}
|
152 |
+
element.setAttribute(attrName, replaceExtToWebp(value, toWebpFlag));
|
153 |
+
};
|
154 |
+
|
155 |
+
var setSourcesImg = function setSourcesImg(element, settings) {
|
156 |
+
var toWebpFlag = supportsWebp && settings.to_webp;
|
157 |
+
var srcsetDataName = settings.data_srcset;
|
158 |
+
var parent = element.parentNode;
|
159 |
+
|
160 |
+
if (parent && parent.tagName === "PICTURE") {
|
161 |
+
setSourcesInChildren(parent, "srcset", srcsetDataName, toWebpFlag);
|
162 |
}
|
163 |
+
var sizesDataValue = getData(element, settings.data_sizes);
|
164 |
+
setAttributeIfValue(element, "sizes", sizesDataValue);
|
165 |
+
var srcsetDataValue = getData(element, srcsetDataName);
|
166 |
+
setAttributeIfValue(element, "srcset", srcsetDataValue, toWebpFlag);
|
167 |
+
var srcDataValue = getData(element, settings.data_src);
|
168 |
+
setAttributeIfValue(element, "src", srcDataValue, toWebpFlag);
|
169 |
+
};
|
170 |
+
|
171 |
+
var setSourcesIframe = function setSourcesIframe(element, settings) {
|
172 |
+
var srcDataValue = getData(element, settings.data_src);
|
173 |
+
|
174 |
+
setAttributeIfValue(element, "src", srcDataValue);
|
175 |
+
};
|
176 |
+
|
177 |
+
var setSourcesVideo = function setSourcesVideo(element, settings) {
|
178 |
+
var srcDataName = settings.data_src;
|
179 |
+
var srcDataValue = getData(element, srcDataName);
|
180 |
+
|
181 |
+
setSourcesInChildren(element, "src", srcDataName);
|
182 |
+
setAttributeIfValue(element, "src", srcDataValue);
|
183 |
+
element.load();
|
184 |
};
|
185 |
|
186 |
+
var setSourcesBgImage = function setSourcesBgImage(element, settings) {
|
187 |
+
var toWebpFlag = supportsWebp && settings.to_webp;
|
188 |
+
var srcDataValue = getData(element, settings.data_src);
|
189 |
+
var bgDataValue = getData(element, settings.data_bg);
|
190 |
+
|
191 |
+
if (srcDataValue) {
|
192 |
+
var setValue = replaceExtToWebp(srcDataValue, toWebpFlag);
|
193 |
+
element.style.backgroundImage = 'url("' + setValue + '")';
|
194 |
+
}
|
195 |
+
|
196 |
+
if (bgDataValue) {
|
197 |
+
var _setValue = replaceExtToWebp(bgDataValue, toWebpFlag);
|
198 |
+
element.style.backgroundImage = _setValue;
|
199 |
+
}
|
200 |
+
};
|
201 |
+
|
202 |
+
var setSourcesFunctions = {
|
203 |
+
IMG: setSourcesImg,
|
204 |
+
IFRAME: setSourcesIframe,
|
205 |
+
VIDEO: setSourcesVideo
|
206 |
+
};
|
207 |
+
|
208 |
+
var setSources = function setSources(element, instance) {
|
209 |
+
var settings = instance._settings;
|
210 |
+
var tagName = element.tagName;
|
211 |
+
var setSourcesFunction = setSourcesFunctions[tagName];
|
212 |
+
if (setSourcesFunction) {
|
213 |
+
setSourcesFunction(element, settings);
|
214 |
+
instance._updateLoadingCount(1);
|
215 |
+
instance._elements = purgeOneElement(instance._elements, element);
|
216 |
+
return;
|
217 |
+
}
|
218 |
+
setSourcesBgImage(element, settings);
|
219 |
+
};
|
220 |
|
221 |
var addClass = function addClass(element, className) {
|
222 |
if (supportsClassList) {
|
234 |
element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " ").replace(/^\s+/, "").replace(/\s+$/, "");
|
235 |
};
|
236 |
|
237 |
+
var callbackIfSet = function callbackIfSet(callback, argument) {
|
238 |
if (callback) {
|
239 |
callback(argument);
|
240 |
}
|
241 |
};
|
242 |
|
243 |
+
var genericLoadEventName = "load";
|
244 |
+
var mediaLoadEventName = "loadeddata";
|
245 |
+
var errorEventName = "error";
|
246 |
|
247 |
+
var addEventListener = function addEventListener(element, eventName, handler) {
|
248 |
+
element.addEventListener(eventName, handler);
|
|
|
249 |
};
|
250 |
|
251 |
+
var removeEventListener = function removeEventListener(element, eventName, handler) {
|
252 |
+
element.removeEventListener(eventName, handler);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
};
|
254 |
|
255 |
+
var addEventListeners = function addEventListeners(element, loadHandler, errorHandler) {
|
256 |
+
addEventListener(element, genericLoadEventName, loadHandler);
|
257 |
+
addEventListener(element, mediaLoadEventName, loadHandler);
|
258 |
+
addEventListener(element, errorEventName, errorHandler);
|
259 |
+
};
|
260 |
+
|
261 |
+
var removeEventListeners = function removeEventListeners(element, loadHandler, errorHandler) {
|
262 |
+
removeEventListener(element, genericLoadEventName, loadHandler);
|
263 |
+
removeEventListener(element, mediaLoadEventName, loadHandler);
|
264 |
+
removeEventListener(element, errorEventName, errorHandler);
|
265 |
+
};
|
266 |
+
|
267 |
+
var eventHandler = function eventHandler(event, success, instance) {
|
268 |
+
var settings = instance._settings;
|
269 |
+
var className = success ? settings.class_loaded : settings.class_error;
|
270 |
+
var callback = success ? settings.callback_load : settings.callback_error;
|
271 |
var element = event.target;
|
272 |
+
|
273 |
removeClass(element, settings.class_loading);
|
274 |
+
addClass(element, className);
|
275 |
+
callbackIfSet(callback, element);
|
276 |
+
|
277 |
+
instance._updateLoadingCount(-1);
|
278 |
};
|
279 |
|
280 |
+
var addOneShotEventListeners = function addOneShotEventListeners(element, instance) {
|
281 |
+
var loadHandler = function loadHandler(event) {
|
282 |
+
eventHandler(event, true, instance);
|
283 |
+
removeEventListeners(element, loadHandler, errorHandler);
|
284 |
+
};
|
285 |
+
var errorHandler = function errorHandler(event) {
|
286 |
+
eventHandler(event, false, instance);
|
287 |
+
removeEventListeners(element, loadHandler, errorHandler);
|
288 |
+
};
|
289 |
+
addEventListeners(element, loadHandler, errorHandler);
|
290 |
+
};
|
291 |
+
|
292 |
+
var managedTags = ["IMG", "IFRAME", "VIDEO"];
|
293 |
+
|
294 |
+
var loadAndUnobserve = function loadAndUnobserve(element, observer, instance) {
|
295 |
+
revealElement(element, instance);
|
296 |
+
observer.unobserve(element);
|
297 |
+
};
|
298 |
+
|
299 |
+
var cancelDelayLoad = function cancelDelayLoad(element) {
|
300 |
+
var timeoutId = getTimeoutData(element);
|
301 |
+
if (!timeoutId) {
|
302 |
+
return; // do nothing if timeout doesn't exist
|
303 |
+
}
|
304 |
+
clearTimeout(timeoutId);
|
305 |
+
setTimeoutData(element, null);
|
306 |
+
};
|
307 |
+
|
308 |
+
var delayLoad = function delayLoad(element, observer, instance) {
|
309 |
+
var loadDelay = instance._settings.load_delay;
|
310 |
+
var timeoutId = getTimeoutData(element);
|
311 |
+
if (timeoutId) {
|
312 |
+
return; // do nothing if timeout already set
|
313 |
+
}
|
314 |
+
timeoutId = setTimeout(function () {
|
315 |
+
loadAndUnobserve(element, observer, instance);
|
316 |
+
cancelDelayLoad(element);
|
317 |
+
}, loadDelay);
|
318 |
+
setTimeoutData(element, timeoutId);
|
319 |
+
};
|
320 |
+
|
321 |
+
function revealElement(element, instance, force) {
|
322 |
+
var settings = instance._settings;
|
323 |
+
if (!force && getWasProcessedData(element)) {
|
324 |
+
return; // element has already been processed and force wasn't true
|
325 |
+
}
|
326 |
+
callbackIfSet(settings.callback_enter, element);
|
327 |
+
if (managedTags.indexOf(element.tagName) > -1) {
|
328 |
+
addOneShotEventListeners(element, instance);
|
329 |
addClass(element, settings.class_loading);
|
330 |
}
|
331 |
+
setSources(element, instance);
|
332 |
+
setWasProcessedData(element);
|
333 |
+
callbackIfSet(settings.callback_set, element);
|
334 |
+
}
|
335 |
+
|
336 |
+
/* entry.isIntersecting needs fallback because is null on some versions of MS Edge, and
|
337 |
+
entry.intersectionRatio is not enough alone because it could be 0 on some intersecting elements */
|
338 |
+
var isIntersecting = function isIntersecting(entry) {
|
339 |
+
return entry.isIntersecting || entry.intersectionRatio > 0;
|
340 |
};
|
341 |
|
342 |
+
var getObserverSettings = function getObserverSettings(settings) {
|
343 |
+
return {
|
344 |
+
root: settings.container === document ? null : settings.container,
|
345 |
+
rootMargin: settings.thresholds || settings.threshold + "px"
|
346 |
+
};
|
347 |
+
};
|
348 |
+
|
349 |
+
var LazyLoad = function LazyLoad(customSettings, elements) {
|
350 |
+
this._settings = getInstanceSettings(customSettings);
|
351 |
this._setObserver();
|
352 |
+
this._loadingCount = 0;
|
353 |
this.update(elements);
|
354 |
};
|
355 |
|
356 |
LazyLoad.prototype = {
|
357 |
+
_manageIntersection: function _manageIntersection(entry) {
|
358 |
+
var observer = this._observer;
|
359 |
+
var loadDelay = this._settings.load_delay;
|
360 |
+
var element = entry.target;
|
361 |
+
|
362 |
+
// WITHOUT LOAD DELAY
|
363 |
+
if (!loadDelay) {
|
364 |
+
if (isIntersecting(entry)) {
|
365 |
+
loadAndUnobserve(element, observer, this);
|
366 |
+
}
|
367 |
+
return;
|
368 |
+
}
|
369 |
+
|
370 |
+
// WITH LOAD DELAY
|
371 |
+
if (isIntersecting(entry)) {
|
372 |
+
delayLoad(element, observer, this);
|
373 |
+
} else {
|
374 |
+
cancelDelayLoad(element);
|
375 |
+
}
|
376 |
+
},
|
377 |
|
378 |
+
_onIntersection: function _onIntersection(entries) {
|
379 |
+
entries.forEach(this._manageIntersection.bind(this));
|
380 |
+
},
|
381 |
+
|
382 |
+
_setObserver: function _setObserver() {
|
383 |
+
if (!supportsIntersectionObserver) {
|
384 |
return;
|
385 |
}
|
386 |
+
this._observer = new IntersectionObserver(this._onIntersection.bind(this), getObserverSettings(this._settings));
|
387 |
+
},
|
388 |
|
389 |
+
_updateLoadingCount: function _updateLoadingCount(plusMinus) {
|
390 |
+
this._loadingCount += plusMinus;
|
391 |
+
if (this._elements.length === 0 && this._loadingCount === 0) {
|
392 |
+
callbackIfSet(this._settings.callback_finish);
|
393 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
394 |
},
|
395 |
|
396 |
update: function update(elements) {
|
397 |
+
var _this = this;
|
398 |
|
399 |
var settings = this._settings;
|
400 |
var nodeSet = elements || settings.container.querySelectorAll(settings.elements_selector);
|
401 |
|
402 |
+
this._elements = purgeProcessedElements(Array.prototype.slice.call(nodeSet) // NOTE: nodeset to array for IE compatibility
|
403 |
+
);
|
404 |
+
|
405 |
+
if (isBot || !this._observer) {
|
406 |
+
this.loadAll();
|
407 |
return;
|
408 |
}
|
409 |
+
|
410 |
this._elements.forEach(function (element) {
|
411 |
+
_this._observer.observe(element);
|
412 |
});
|
|
|
413 |
},
|
414 |
|
415 |
destroy: function destroy() {
|
416 |
+
var _this2 = this;
|
417 |
|
418 |
if (this._observer) {
|
419 |
+
this._elements.forEach(function (element) {
|
420 |
+
_this2._observer.unobserve(element);
|
421 |
});
|
422 |
this._observer = null;
|
423 |
}
|
424 |
this._elements = null;
|
425 |
this._settings = null;
|
426 |
+
},
|
427 |
+
|
428 |
+
load: function load(element, force) {
|
429 |
+
revealElement(element, this, force);
|
430 |
+
},
|
431 |
+
|
432 |
+
loadAll: function loadAll() {
|
433 |
+
var _this3 = this;
|
434 |
+
|
435 |
+
var elements = this._elements;
|
436 |
+
elements.forEach(function (element) {
|
437 |
+
_this3.load(element);
|
438 |
+
});
|
439 |
}
|
440 |
};
|
441 |
|
442 |
+
/* Automatic instances creation if required (useful for async script loading) */
|
443 |
+
if (runningOnBrowser) {
|
444 |
+
autoInitialize(LazyLoad, window.lazyLoadOptions);
|
|
|
445 |
}
|
446 |
|
447 |
return LazyLoad;
|
js/lazyload.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
var _extends=Object.assign||function(
|
1 |
+
var _extends=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(t[o]=n[o])}return t},_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(t,e){"object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.LazyLoad=e()}(this,function(){"use strict";var n={elements_selector:"img",container:document,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",class_loading:"loading",class_loaded:"loaded",class_error:"error",load_delay:0,callback_load:null,callback_error:null,callback_set:null,callback_enter:null,callback_finish:null,to_webp:!1},a="data-",s="was-processed",o="ll-timeout",r="true",c=function(t,e){return t.getAttribute(a+e)},i=function(t,e,n){var o=a+e;null!==n?t.setAttribute(o,n):t.removeAttribute(o)},l=function(t){return c(t,s)===r},u=function(t,e){return i(t,o,e)},d=function(t){return c(t,o)},f=function(t,e){var n,o="LazyLoad::Initialized",a=new t(e);try{n=new CustomEvent(o,{detail:{instance:a}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent(o,!1,!1,{instance:a})}window.dispatchEvent(n)};var t,e,_=function(t,e){return e?t.replace(/\.(jpe?g|png)/gi,".webp"):t},v="undefined"!=typeof window,h=v&&!("onscroll"in window)||/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),b=v&&"IntersectionObserver"in window,g=v&&"classList"in document.createElement("p"),m=v&&(t="image/webp",!(!(e=document.createElement("canvas")).getContext||!e.getContext("2d"))&&0===e.toDataURL(t).indexOf("data:"+t)),p=function(t,e,n,o){for(var a,s=0;a=t.children[s];s+=1)if("SOURCE"===a.tagName){var r=c(a,n);y(a,e,r,o)}},y=function(t,e,n,o){n&&t.setAttribute(e,_(n,o))},w={IMG:function(t,e){var n=m&&e.to_webp,o=e.data_srcset,a=t.parentNode;a&&"PICTURE"===a.tagName&&p(a,"srcset",o,n);var s=c(t,e.data_sizes);y(t,"sizes",s);var r=c(t,o);y(t,"srcset",r,n);var i=c(t,e.data_src);y(t,"src",i,n)},IFRAME:function(t,e){var n=c(t,e.data_src);y(t,"src",n)},VIDEO:function(t,e){var n=e.data_src,o=c(t,n);p(t,"src",n),y(t,"src",o),t.load()}},E=function(t,e){var n,o,a=e._settings,s=t.tagName,r=w[s];if(r)return r(t,a),e._updateLoadingCount(1),void(e._elements=(n=e._elements,o=t,n.filter(function(t){return t!==o})));!function(t,e){var n=m&&e.to_webp,o=c(t,e.data_src),a=c(t,e.data_bg);if(o){var s=_(o,n);t.style.backgroundImage='url("'+s+'")'}if(a){var r=_(a,n);t.style.backgroundImage=r}}(t,a)},L=function(t,e){g?t.classList.add(e):t.className+=(t.className?" ":"")+e},I=function(t,e){t&&t(e)},O="load",C="loadeddata",k="error",x=function(t,e,n){t.addEventListener(e,n)},A=function(t,e,n){t.removeEventListener(e,n)},z=function(t,e,n){A(t,O,e),A(t,C,e),A(t,k,n)},N=function(t,e,n){var o,a,s=n._settings,r=e?s.class_loaded:s.class_error,i=e?s.callback_load:s.callback_error,c=t.target;o=c,a=s.class_loading,g?o.classList.remove(a):o.className=o.className.replace(new RegExp("(^|\\s+)"+a+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,""),L(c,r),I(i,c),n._updateLoadingCount(-1)},M=function(n,o){var t,e,a,s=function t(e){N(e,!0,o),z(n,t,r)},r=function t(e){N(e,!1,o),z(n,s,t)};a=r,x(t=n,O,e=s),x(t,C,e),x(t,k,a)},R=["IMG","IFRAME","VIDEO"],S=function(t,e,n){D(t,n),e.unobserve(t)},j=function(t){var e=d(t);e&&(clearTimeout(e),u(t,null))};function D(t,e,n){var o=e._settings;!n&&l(t)||(I(o.callback_enter,t),-1<R.indexOf(t.tagName)&&(M(t,e),L(t,o.class_loading)),E(t,e),i(t,s,r),I(o.callback_set,t))}var T=function(t){return t.isIntersecting||0<t.intersectionRatio},U=function(t,e){this._settings=_extends({},n,t),this._setObserver(),this._loadingCount=0,this.update(e)};return U.prototype={_manageIntersection:function(t){var e,n,o,a,s,r=this._observer,i=this._settings.load_delay,c=t.target;i?T(t)?(e=c,n=r,a=(o=this)._settings.load_delay,(s=d(e))||(s=setTimeout(function(){S(e,n,o),j(e)},a),u(e,s))):j(c):T(t)&&S(c,r,this)},_onIntersection:function(t){t.forEach(this._manageIntersection.bind(this))},_setObserver:function(){var t;b&&(this._observer=new IntersectionObserver(this._onIntersection.bind(this),{root:(t=this._settings).container===document?null:t.container,rootMargin:t.thresholds||t.threshold+"px"}))},_updateLoadingCount:function(t){this._loadingCount+=t,0===this._elements.length&&0===this._loadingCount&&I(this._settings.callback_finish)},update:function(t){var e=this,n=this._settings,o=t||n.container.querySelectorAll(n.elements_selector);this._elements=Array.prototype.slice.call(o).filter(function(t){return!l(t)}),!h&&this._observer?this._elements.forEach(function(t){e._observer.observe(t)}):this.loadAll()},destroy:function(){var e=this;this._observer&&(this._elements.forEach(function(t){e._observer.unobserve(t)}),this._observer=null),this._elements=null,this._settings=null},load:function(t,e){D(t,this,e)},loadAll:function(){var e=this;this._elements.forEach(function(t){e.load(t)})}},v&&function(t,e){if(e)if(e.length)for(var n,o=0;n=e[o];o+=1)f(t,n);else f(t,e)}(U,window.lazyLoadOptions),U}),function(t,e){"use strict";var n,o,a=function(){n=new LazyLoad({elements_selector:"[data-lazyloaded]"}),o=function(){n.update()},t.MutationObserver&&new MutationObserver(o).observe(e.documentElement,{childList:!0,subtree:!0,attributes:!0})};t.addEventListener?t.addEventListener("load",a,!1):t.attachEvent("onload",a)}(window,document);
|
languages/litespeed-cache.pot
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
# This file is distributed under the same license as the LiteSpeed Cache package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: LiteSpeed Cache 2.6.
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/litespeed-cache\n"
|
7 |
-
"POT-Creation-Date: 2018-10-
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -606,7 +606,7 @@ msgstr ""
|
|
606 |
#: admin/tpl/setting/settings_debug.php:105
|
607 |
#: admin/tpl/setting/settings_debug.php:138
|
608 |
#: admin/tpl/setting/settings_media.php:182
|
609 |
-
#: admin/tpl/setting/settings_optimize.php:15 admin/tpl/settings.php:
|
610 |
msgid "WARNING"
|
611 |
msgstr ""
|
612 |
|
@@ -854,11 +854,27 @@ msgid ""
|
|
854 |
"Cache settings."
|
855 |
msgstr ""
|
856 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
857 |
#: admin/tpl/inc/admin_footer.php:6
|
858 |
msgid "Rate %s on %s"
|
859 |
msgstr ""
|
860 |
|
861 |
-
#. #-#-#-#-# litespeed-cache.pot (LiteSpeed Cache 2.6.
|
862 |
#. Plugin Name of the plugin/theme
|
863 |
#: admin/tpl/inc/admin_footer.php:6 inc/gui.class.php:353
|
864 |
#: includes/litespeed-cache-gui.class.php:353
|
@@ -3890,25 +3906,25 @@ msgstr ""
|
|
3890 |
msgid "LiteSpeed Cache Settings"
|
3891 |
msgstr ""
|
3892 |
|
3893 |
-
#: admin/tpl/settings.php:
|
3894 |
msgid "Hide Advanced Options"
|
3895 |
msgstr ""
|
3896 |
|
3897 |
-
#: admin/tpl/settings.php:
|
3898 |
msgid "Show Advanced Options"
|
3899 |
msgstr ""
|
3900 |
|
3901 |
-
#: admin/tpl/settings.php:
|
3902 |
msgid "The network admin selected use primary site configs for all subsites."
|
3903 |
msgstr ""
|
3904 |
|
3905 |
-
#: admin/tpl/settings.php:
|
3906 |
msgid ""
|
3907 |
"The following options are selected, but are not editable in this settings "
|
3908 |
"page."
|
3909 |
msgstr ""
|
3910 |
|
3911 |
-
#: admin/tpl/settings.php:
|
3912 |
msgid "Save Changes"
|
3913 |
msgstr ""
|
3914 |
|
@@ -4066,8 +4082,8 @@ msgstr ""
|
|
4066 |
msgid "Communicated with LiteSpeed Image Optimization Server successfully."
|
4067 |
msgstr ""
|
4068 |
|
4069 |
-
#: inc/img_optm.class.php:166 inc/img_optm.class.php:
|
4070 |
-
#: inc/img_optm.class.php:
|
4071 |
msgid "No image found."
|
4072 |
msgstr ""
|
4073 |
|
@@ -4098,52 +4114,56 @@ msgid ""
|
|
4098 |
"automated."
|
4099 |
msgstr ""
|
4100 |
|
4101 |
-
#: inc/img_optm.class.php:
|
4102 |
msgid "Destroy unfinished data successfully."
|
4103 |
msgstr ""
|
4104 |
|
4105 |
-
#: inc/img_optm.class.php:
|
4106 |
msgid ""
|
4107 |
"Pushed %1$s groups with %2$s images to LiteSpeed optimization server, "
|
4108 |
"accepted %3$s groups with %4$s images."
|
4109 |
msgstr ""
|
4110 |
|
4111 |
-
#: inc/img_optm.class.php:
|
4112 |
msgid "Removed %1$s images and saved %2$s successfully."
|
4113 |
msgstr ""
|
4114 |
|
4115 |
-
#: inc/img_optm.class.php:
|
4116 |
msgid "Switched images successfully."
|
4117 |
msgstr ""
|
4118 |
|
4119 |
-
#: inc/img_optm.class.php:
|
4120 |
msgid "Disabled WebP file successfully."
|
4121 |
msgstr ""
|
4122 |
|
4123 |
-
#: inc/img_optm.class.php:
|
4124 |
msgid "Enabled WebP file successfully."
|
4125 |
msgstr ""
|
4126 |
|
4127 |
-
#: inc/img_optm.class.php:
|
4128 |
msgid "Restored original file successfully."
|
4129 |
msgstr ""
|
4130 |
|
4131 |
-
#: inc/img_optm.class.php:
|
4132 |
msgid "Switched to optimized file successfully."
|
4133 |
msgstr ""
|
4134 |
|
4135 |
-
#: inc/img_optm.class.php:
|
4136 |
msgid "Reset the optimized data successfully."
|
4137 |
msgstr ""
|
4138 |
|
4139 |
-
#: inc/import.class.php:
|
4140 |
msgid "Import failed due to file error."
|
4141 |
msgstr ""
|
4142 |
|
4143 |
-
#: inc/import.class.php:
|
4144 |
msgid "Imported setting file %s successfully."
|
4145 |
msgstr ""
|
4146 |
|
|
|
|
|
|
|
|
|
4147 |
#: inc/litespeed-cache.class.php:270 includes/litespeed-cache.class.php:270
|
4148 |
msgid "Crawler blacklist is saved."
|
4149 |
msgstr ""
|
@@ -4184,10 +4204,6 @@ msgstr ""
|
|
4184 |
msgid "Click to Switch To Optimized File"
|
4185 |
msgstr ""
|
4186 |
|
4187 |
-
#: inc/media.class.php:243
|
4188 |
-
msgid "Reset"
|
4189 |
-
msgstr ""
|
4190 |
-
|
4191 |
#: inc/purge.class.php:163 includes/litespeed-cache-purge.class.php:163
|
4192 |
msgid "Purged all caches successfully."
|
4193 |
msgstr ""
|
2 |
# This file is distributed under the same license as the LiteSpeed Cache package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: LiteSpeed Cache 2.6.3\n"
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/litespeed-cache\n"
|
7 |
+
"POT-Creation-Date: 2018-10-18 15:29:31+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
606 |
#: admin/tpl/setting/settings_debug.php:105
|
607 |
#: admin/tpl/setting/settings_debug.php:138
|
608 |
#: admin/tpl/setting/settings_media.php:182
|
609 |
+
#: admin/tpl/setting/settings_optimize.php:15 admin/tpl/settings.php:185
|
610 |
msgid "WARNING"
|
611 |
msgstr ""
|
612 |
|
854 |
"Cache settings."
|
855 |
msgstr ""
|
856 |
|
857 |
+
#: admin/tpl/import_export.php:58 admin/tpl/settings.php:218
|
858 |
+
msgid "Reset All Settings"
|
859 |
+
msgstr ""
|
860 |
+
|
861 |
+
#: admin/tpl/import_export.php:60
|
862 |
+
msgid "Are you sure to reset all settings to default settings?"
|
863 |
+
msgstr ""
|
864 |
+
|
865 |
+
#: admin/tpl/import_export.php:61 inc/media.class.php:243
|
866 |
+
msgid "Reset"
|
867 |
+
msgstr ""
|
868 |
+
|
869 |
+
#: admin/tpl/import_export.php:65
|
870 |
+
msgid "This will reset all settings to default settings."
|
871 |
+
msgstr ""
|
872 |
+
|
873 |
#: admin/tpl/inc/admin_footer.php:6
|
874 |
msgid "Rate %s on %s"
|
875 |
msgstr ""
|
876 |
|
877 |
+
#. #-#-#-#-# litespeed-cache.pot (LiteSpeed Cache 2.6.3) #-#-#-#-#
|
878 |
#. Plugin Name of the plugin/theme
|
879 |
#: admin/tpl/inc/admin_footer.php:6 inc/gui.class.php:353
|
880 |
#: includes/litespeed-cache-gui.class.php:353
|
3906 |
msgid "LiteSpeed Cache Settings"
|
3907 |
msgstr ""
|
3908 |
|
3909 |
+
#: admin/tpl/settings.php:174
|
3910 |
msgid "Hide Advanced Options"
|
3911 |
msgstr ""
|
3912 |
|
3913 |
+
#: admin/tpl/settings.php:176
|
3914 |
msgid "Show Advanced Options"
|
3915 |
msgstr ""
|
3916 |
|
3917 |
+
#: admin/tpl/settings.php:187
|
3918 |
msgid "The network admin selected use primary site configs for all subsites."
|
3919 |
msgstr ""
|
3920 |
|
3921 |
+
#: admin/tpl/settings.php:188
|
3922 |
msgid ""
|
3923 |
"The following options are selected, but are not editable in this settings "
|
3924 |
"page."
|
3925 |
msgstr ""
|
3926 |
|
3927 |
+
#: admin/tpl/settings.php:210 admin/tpl/settings.php:213
|
3928 |
msgid "Save Changes"
|
3929 |
msgstr ""
|
3930 |
|
4082 |
msgid "Communicated with LiteSpeed Image Optimization Server successfully."
|
4083 |
msgstr ""
|
4084 |
|
4085 |
+
#: inc/img_optm.class.php:166 inc/img_optm.class.php:1468
|
4086 |
+
#: inc/img_optm.class.php:1533
|
4087 |
msgid "No image found."
|
4088 |
msgstr ""
|
4089 |
|
4114 |
"automated."
|
4115 |
msgstr ""
|
4116 |
|
4117 |
+
#: inc/img_optm.class.php:1358
|
4118 |
msgid "Destroy unfinished data successfully."
|
4119 |
msgstr ""
|
4120 |
|
4121 |
+
#: inc/img_optm.class.php:1571
|
4122 |
msgid ""
|
4123 |
"Pushed %1$s groups with %2$s images to LiteSpeed optimization server, "
|
4124 |
"accepted %3$s groups with %4$s images."
|
4125 |
msgstr ""
|
4126 |
|
4127 |
+
#: inc/img_optm.class.php:1747
|
4128 |
msgid "Removed %1$s images and saved %2$s successfully."
|
4129 |
msgstr ""
|
4130 |
|
4131 |
+
#: inc/img_optm.class.php:1942
|
4132 |
msgid "Switched images successfully."
|
4133 |
msgstr ""
|
4134 |
|
4135 |
+
#: inc/img_optm.class.php:1973
|
4136 |
msgid "Disabled WebP file successfully."
|
4137 |
msgstr ""
|
4138 |
|
4139 |
+
#: inc/img_optm.class.php:1979
|
4140 |
msgid "Enabled WebP file successfully."
|
4141 |
msgstr ""
|
4142 |
|
4143 |
+
#: inc/img_optm.class.php:1995
|
4144 |
msgid "Restored original file successfully."
|
4145 |
msgstr ""
|
4146 |
|
4147 |
+
#: inc/img_optm.class.php:2002
|
4148 |
msgid "Switched to optimized file successfully."
|
4149 |
msgstr ""
|
4150 |
|
4151 |
+
#: inc/img_optm.class.php:2062
|
4152 |
msgid "Reset the optimized data successfully."
|
4153 |
msgstr ""
|
4154 |
|
4155 |
+
#: inc/import.class.php:148
|
4156 |
msgid "Import failed due to file error."
|
4157 |
msgstr ""
|
4158 |
|
4159 |
+
#: inc/import.class.php:203
|
4160 |
msgid "Imported setting file %s successfully."
|
4161 |
msgstr ""
|
4162 |
|
4163 |
+
#: inc/import.class.php:249
|
4164 |
+
msgid "Reset successfully."
|
4165 |
+
msgstr ""
|
4166 |
+
|
4167 |
#: inc/litespeed-cache.class.php:270 includes/litespeed-cache.class.php:270
|
4168 |
msgid "Crawler blacklist is saved."
|
4169 |
msgstr ""
|
4204 |
msgid "Click to Switch To Optimized File"
|
4205 |
msgstr ""
|
4206 |
|
|
|
|
|
|
|
|
|
4207 |
#: inc/purge.class.php:163 includes/litespeed-cache-purge.class.php:163
|
4208 |
msgid "Purged all caches successfully."
|
4209 |
msgstr ""
|
litespeed-cache.php
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
* Plugin Name: LiteSpeed Cache
|
16 |
* Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
|
17 |
* Description: High-performance page caching and site optimization from LiteSpeed
|
18 |
-
* Version: 2.6.
|
19 |
* Author: LiteSpeed Technologies
|
20 |
* Author URI: https://www.litespeedtech.com
|
21 |
* License: GPLv3
|
15 |
* Plugin Name: LiteSpeed Cache
|
16 |
* Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
|
17 |
* Description: High-performance page caching and site optimization from LiteSpeed
|
18 |
+
* Version: 2.6.3
|
19 |
* Author: LiteSpeed Technologies
|
20 |
* Author URI: https://www.litespeedtech.com
|
21 |
* License: GPLv3
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: LiteSpeedTech
|
|
3 |
Tags: caching, optimize, performance, pagespeed, seo, speed, image optimize, compress, object cache, redis, memcached, database cleaner
|
4 |
Requires at least: 4.0
|
5 |
Tested up to: 4.9.8
|
6 |
-
Stable tag: 2.6.
|
7 |
License: GPLv3
|
8 |
License URI: http://www.gnu.org/licenses/gpl.html
|
9 |
|
@@ -275,13 +275,22 @@ Click on the `Advanced View` link at the top of the page, and several more tabs
|
|
275 |
|
276 |
== Changelog ==
|
277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
= 2.6.2 - Oct 11 2018 =
|
279 |
* <strong>Setting</strong>: Automatically correct invalid numeric values in configuration settings upon submit.
|
280 |
* 🐞<strong>Media</strong>: Fixed the issue where iframe lazy load was broken by latest Chrome release. (@ofmarconi)
|
281 |
* 🐞: Fixed an issue with Multisite where subsites failed to purge when only primary site has WooCommerce . (@kierancalv)
|
282 |
|
283 |
= 2.6.1 - Oct 4 2018 =
|
284 |
-
*
|
285 |
* <strong>API</strong>: Filter `litespeed_frontend_htaccess` for frontend htaccess path.
|
286 |
* <strong>Media</strong>: Removed responsive placeholder generation history to save space.
|
287 |
|
3 |
Tags: caching, optimize, performance, pagespeed, seo, speed, image optimize, compress, object cache, redis, memcached, database cleaner
|
4 |
Requires at least: 4.0
|
5 |
Tested up to: 4.9.8
|
6 |
+
Stable tag: 2.6.3
|
7 |
License: GPLv3
|
8 |
License URI: http://www.gnu.org/licenses/gpl.html
|
9 |
|
275 |
|
276 |
== Changelog ==
|
277 |
|
278 |
+
= 2.6.3 - Oct 18 2018 =
|
279 |
+
* 🌱: Added the ability to Reset All Options.
|
280 |
+
* 🌱<strong>CLI</strong>: Added new `lscache-admin reset_options` command.
|
281 |
+
* <strong>GUI</strong>: Added shortcuts for more of the Settings tabs.
|
282 |
+
* <strong>Media</strong>: Updated Lazy Load JS library to the most recent version.
|
283 |
+
* There is no longer any need to explicitly Save Settings upon Import.
|
284 |
+
* Remove Query String now will remove *all* query strings in JS/CSS static files.
|
285 |
+
* <strong>IAPI</strong>: Added summary info to debug log.
|
286 |
+
|
287 |
= 2.6.2 - Oct 11 2018 =
|
288 |
* <strong>Setting</strong>: Automatically correct invalid numeric values in configuration settings upon submit.
|
289 |
* 🐞<strong>Media</strong>: Fixed the issue where iframe lazy load was broken by latest Chrome release. (@ofmarconi)
|
290 |
* 🐞: Fixed an issue with Multisite where subsites failed to purge when only primary site has WooCommerce . (@kierancalv)
|
291 |
|
292 |
= 2.6.1 - Oct 4 2018 =
|
293 |
+
* 🌱: Ability to generate separate Critical CSS Cache for Post Types & URIs.
|
294 |
* <strong>API</strong>: Filter `litespeed_frontend_htaccess` for frontend htaccess path.
|
295 |
* <strong>Media</strong>: Removed responsive placeholder generation history to save space.
|
296 |
|