Lazy Load by WP Rocket - Version 1.1

Version Description

  • 12 feb. 2017
  • New
    • JS library updated
    • Support for iFrame
    • Support for srcset and sizes
    • New options page
Download this release

Release Info

Developer wp_media
Plugin Icon 128x128 Lazy Load by WP Rocket
Version 1.1
Comparing to
See all releases

Code changes from version 1.0.4 to 1.1

admin/admin.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ defined( 'ABSPATH' ) or die( 'Cheatin\' uh?' );
3
+
4
+ /**
5
+ * Add Rocket LazyLoad settings page to Settings menu.
6
+ *
7
+ * @since 1.1
8
+ * @return void
9
+ */
10
+ function rocket_lazyload_add_menu() {
11
+ add_options_page( __( 'Rocket LazyLoad', 'rocket-lazy-load' ), __( 'Rocket LazyLoad', 'rocket-lazy-load' ), 'manage_options', 'rocket-lazyload', 'rocket_lazyload_options_output' );
12
+ }
13
+ add_action( 'admin_menu', 'rocket_lazyload_add_menu' );
14
+
15
+ /**
16
+ * Enqueue the css for the option page
17
+ *
18
+ * @since 1.1
19
+ * @author Remy Perona
20
+ *
21
+ * @param string $hook Current page hook.
22
+ */
23
+ function rocket_lazyload_enqueue_scripts( $hook ) {
24
+ if ( 'settings_page_rocket-lazyload' !== $hook ) {
25
+ return;
26
+ }
27
+
28
+ wp_enqueue_style( 'rocket-lazyload', ROCKET_LL_ASSETS_URL . 'css/admin.css', null, ROCKET_LL_VERSION );
29
+ }
30
+ add_action( 'admin_enqueue_scripts', 'rocket_lazyload_enqueue_scripts' );
31
+
32
+
33
+ /**
34
+ * Register Rocket LazyLoad settings.
35
+ *
36
+ * @since 1.1
37
+ * @return void
38
+ */
39
+ function rocket_lazyload_settings_init() {
40
+ register_setting( 'rocket_lazyload', 'rocket_lazyload_options' );
41
+ }
42
+ add_action( 'admin_init', 'rocket_lazyload_settings_init' );
43
+
44
+
45
+ /**
46
+ * Display Rocket LazyLoad settings.
47
+ *
48
+ * @since 1.1
49
+ * @return void
50
+ */
51
+ function rocket_lazyload_options_output() {
52
+ global $wp_version;
53
+
54
+ // check user capabilities.
55
+ if ( ! current_user_can( 'manage_options' ) ) {
56
+ return;
57
+ }
58
+
59
+ ?>
60
+ <div class="wrap rocket-lazyload-settings">
61
+ <?php $heading_tag = version_compare( $wp_version, '4.3' ) >= 0 ? 'h1' : 'h2'; ?>
62
+ <<?php echo $heading_tag; ?> class="screen-reader-text"><?php echo esc_html( get_admin_page_title() ); ?></<?php echo $heading_tag; ?>>
63
+ <div class="rocket-lazyload-header">
64
+ <div>
65
+ <p class="rocket-lazyload-title"><?php echo esc_html( get_admin_page_title() ); ?></p>
66
+ <p class="rocket-lazyload-subtitle"><?php _e( 'Settings', 'rocket-lazyload' ); ?></p>
67
+ </div>
68
+ <?php $rocket_lazyload_rate_url = 'https://wordpress.org/support/plugin/rocket-lazy-load/reviews/?rate=5#postform'; ?>
69
+ <p class="rocket-lazyload-rate-us">
70
+ <?php printf( __( '%1$sDo you like this plugin?%2$s Please take a few seconds to %3$srate it on WordPress.org%4$s!', 'rocket-lazyload' ), '<strong>', '</strong><br>', '<a href="' . $rocket_lazyload_rate_url . '">', '</a>' ); ?>
71
+ <br>
72
+ <a class="stars" href="<?php echo $rocket_lazyload_rate_url; ?>"><?php echo str_repeat( '<span class="dashicons dashicons-star-filled"></span>', 5 ); ?></a>
73
+ </p>
74
+ </div>
75
+ <div class="rocket-lazyload-body">
76
+ <form action="options.php" class="rocket-lazyload-form" method="post">
77
+ <fieldset>
78
+ <legend><?php _e( 'Lazyload', 'rocket-lazyload' ); ?></legend>
79
+ <p><?php _e( 'LazyLoad displays images, iframes and videos on a page only when they are visible to the user.', 'rocket-lazyload' ); ?></p>
80
+ <p><?php _e( 'This mechanism reduces the number of HTTP requests and improves the loading time.', 'rocket-lazyload' ); ?></p>
81
+ <ul>
82
+ <li class="rocket-lazyload-option">
83
+ <input type="checkbox" value="1" id="lazyload-images" name="rocket_lazyload_options[images]" <?php checked( rocket_lazyload_get_option( 'images', 0 ), 1 ); ?> aria-describedby="describe-lazyload-images">
84
+ <label for="lazyload-images"><span class="screen-reader-text"><?php _e( 'Images', 'rocket-lazyload' ); ?></span></label>
85
+ <span id="describe-lazyload-images" class="rocket-lazyload-label-description"><?php _e( 'Images', 'rocket-lazyload' ); ?></span>
86
+ </li>
87
+ <li class="rocket-lazyload-option">
88
+ <input type="checkbox" value="1" id="lazyload-iframes" name="rocket_lazyload_options[iframes]" <?php checked( rocket_lazyload_get_option( 'iframes', 0 ), 1 ); ?> aria-describedby="describe-lazyload-iframes">
89
+ <label for="lazyload-iframes"><span class="screen-reader-text"><?php _e( 'Iframes & Videos', 'rocket-lazyload' ); ?></span></label>
90
+ <span id="describe-lazyload-images" class="rocket-lazyload-label-description"><?php _e( 'Iframes & Videos', 'rocket-lazyload' ); ?></span>
91
+ </li>
92
+ </ul>
93
+ </fieldset>
94
+ <?php
95
+ settings_fields( 'rocket_lazyload' );
96
+ submit_button( __( '✓ Save changes', 'rocket-lazyload' ) );
97
+ ?>
98
+ </form>
99
+ <div class="rocket-lazyload-cross-sell">
100
+ <h2 class="rocket-lazyload-cross-sell-title"><?php _e( 'Need To Boost Your Speed Even More?', 'rocket-lazyload' ); ?></h2>
101
+ <div class="rocket-lazyload-ads">
102
+ <a href="https://wp-rocket.me?utm_source=wp_plugin&utm_medium=rocket_lazyload"><img src="<?php echo ROCKET_LL_ASSETS_URL ?>img/wp-rocket@2x.jpg" alt="WP Rocket" width="393" height="180"></a>
103
+ <?php if ( ! is_plugin_active( 'imagify/imagify.php' ) ) : ?>
104
+ <a href="https://imagify.io?utm_source=wp_plugin&utm_medium=rocket_lazyload"><img src="<?php echo ROCKET_LL_ASSETS_URL ?>img/imagify@2x.jpg" alt="Imagify" width="393" height="180"></a>
105
+ <? endif; ?>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </div>
110
+ <?php }
assets/css/admin.css ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .rocket-lazyload-settings {
2
+ max-width: 880px;
3
+ }
4
+
5
+ .rocket-lazyload-settings a {
6
+ color: #F7A933;
7
+ }
8
+
9
+ .rocket-lazyload-settings a:hover {
10
+ color: #FEE102;
11
+ }
12
+
13
+ .rocket-lazyload-header.rocket-lazyload-header {
14
+ display: flex;
15
+ flex-wrap: wrap;
16
+ align-items: center;
17
+ justify-content: space-between;
18
+ padding: 28px 25px 26px;
19
+ font-size: 23px;
20
+ background: #3A214B;
21
+ color: #FFF;
22
+ }
23
+
24
+ .rocket-lazyload-title {
25
+ margin: 0 0 18px;
26
+ color: #EAEAEA;
27
+ font-size: 23px;
28
+ font-weight: bold;
29
+ text-transform: uppercase;
30
+ }
31
+
32
+ .rocket-lazyload-subtitle {
33
+ color: #F7A933;
34
+ font-weight: 600;
35
+ letter-spacing: 3px;
36
+ text-transform: uppercase;
37
+ }
38
+
39
+ .rocket-lazyload-rate-us {
40
+ text-align: right;
41
+ }
42
+
43
+ .rocket-lazyload-rate-us .stars {
44
+ text-decoration: none;
45
+ }
46
+
47
+ .rocket-lazyload-body {
48
+ background-color: #FFFFFF;
49
+ border: 1px solid #D9D9D9;
50
+ }
51
+
52
+ .rocket-lazyload-form fieldset {
53
+ padding: 0 35px 35px 25px;
54
+ }
55
+
56
+ .rocket-lazyload-form legend {
57
+ display: block;
58
+ width: 100%;
59
+ padding: 19px 0 14px;
60
+ border-bottom: 1px solid #EEEEEE;
61
+ font-weight: 600;
62
+ color: #23282D;
63
+ }
64
+
65
+ .rocket-lazyload-option {
66
+ height: 32px;
67
+ margin: 0 0 12px 20px;
68
+ }
69
+
70
+ /* Custom checkboxes in CSS */
71
+ .rocket-lazyload-form [type="checkbox"]:not(:checked),
72
+ .rocket-lazyload-form [type="checkbox"]:checked {
73
+ opacity: 0.01;
74
+ }
75
+ .rocket-lazyload-form [type="checkbox"]:not(:checked):focus,
76
+ .rocket-lazyload-form [type="checkbox"]:checked:focus {
77
+ box-shadow: none!important; /* system value to override */
78
+ outline: none!important;
79
+ border: 0 none!important;
80
+ }
81
+
82
+ .rocket-lazyload-form [type="checkbox"]:not(:checked) + label,
83
+ .rocket-lazyload-form [type="checkbox"]:checked + label {
84
+ position: relative;
85
+ padding-left: 6px;
86
+ cursor: pointer;
87
+ vertical-align: top;
88
+ }
89
+
90
+ /* checkbox aspect */
91
+ .rocket-lazyload-form [type="checkbox"]:not(:checked) + label:before,
92
+ .rocket-lazyload-form [type="checkbox"]:checked + label:before {
93
+ content: '';
94
+ position: absolute;
95
+ left: 0; top: 0;
96
+ width: 28px; height: 28px;
97
+ margin: 0 0 0 -24px;
98
+ border: 2px solid #8BA6B4;
99
+ background: #FFFFFF;
100
+ border-radius: 4px;
101
+ }
102
+ /* checked mark aspect */
103
+ .rocket-lazyload-form [type="checkbox"]:not(:checked) + label:after,
104
+ .rocket-lazyload-form [type="checkbox"]:checked + label:after {
105
+ content: "✓";
106
+ position: absolute;
107
+ font-size: 1.6em;
108
+ color: #8BA6B4;
109
+ top: 6px; left: -16px;
110
+ -webkit-transition: all .2s;
111
+ -moz-transition: all .2s;
112
+ -ms-transition: all .2s;
113
+ transition: all .2s;
114
+ }
115
+ /* checked mark aspect changes */
116
+ .rocket-lazyload-form [type="checkbox"]:not(:checked) + label:after {
117
+ opacity: 0;
118
+ -webkit-transform: scale(0);
119
+ -moz-transform: scale(0);
120
+ -ms-transform: scale(0);
121
+ transform: scale(0);
122
+ }
123
+ .rocket-lazyload-form [type="checkbox"]:checked + label:after {
124
+ opacity: 1;
125
+ -webkit-transform: scale(1);
126
+ -moz-transform: scale(1);
127
+ -ms-transform: scale(1);
128
+ transform: scale(1);
129
+ }
130
+ /* focus aspect */
131
+ .rocket-lazyload-form [type="checkbox"]:not(:checked):focus + label:before,
132
+ .rocket-lazyload-form [type="checkbox"]:checked:focus + label:before {
133
+ border-style: dotted;
134
+ border-color: #40b1d0;
135
+ }
136
+
137
+ .rocket-lazyload-label-description {
138
+ display: inline-block;
139
+ margin: 8px 0 0 20px;
140
+ color: #666666;
141
+ font-weight: 600;
142
+ }
143
+
144
+ .rocket-lazyload-form .submit {
145
+ padding: 28px 0 32px 24px;
146
+ background-color: #FCFBF0;
147
+ }
148
+
149
+ .rocket-lazyload-form .submit .button-primary {
150
+ height: 40px;
151
+ background-color: #F7A933;
152
+ box-shadow: 0 4px 0 0 #D69626;
153
+ border: none;
154
+ border-radius: 3px;
155
+ font-weight: bold;
156
+ text-shadow: none;
157
+ }
158
+
159
+ .rocket-lazyload-cross-sell {
160
+ padding: 35px 35px 35px 25px;
161
+ }
162
+
163
+ .rocket-lazyload-cross-sell-title {
164
+ margin-top: 0;
165
+ font-size: 23px;
166
+ }
167
+
168
+ .rocket-lazyload-ads {
169
+ display: flex;
170
+ flex-wrap: wrap;
171
+ justify-content: space-between;
172
+ }
assets/img/imagify@2x.jpg ADDED
Binary file
assets/img/wp-rocket@2x.jpg ADDED
Binary file
assets/js/lazyload-3.0.js ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(root, factory) {
2
+ if (typeof define === 'function' && define.amd) {
3
+ define([], factory);
4
+ } else if (typeof exports === 'object') {
5
+ module.exports = factory();
6
+ } else {
7
+ root.LazyLoad = factory();
8
+ }
9
+ }(this, function() {
10
+
11
+ var _defaultSettings,
12
+ _supportsAddEventListener,
13
+ _supportsAttachEvent,
14
+ _supportsClassList,
15
+ _isInitialized = false;
16
+
17
+
18
+ /*
19
+ * PRIVATE FUNCTIONS *NOT RELATED* TO A SPECIFIC INSTANCE OF LAZY LOAD
20
+ * -------------------------------------------------------------------
21
+ */
22
+
23
+ function _init() {
24
+ if (!_isInitialized) {
25
+ _defaultSettings = {
26
+ elements_selector: "img",
27
+ container: window,
28
+ threshold: 300,
29
+ throttle: 50,
30
+ data_src: "original",
31
+ data_srcset: "original-set",
32
+ class_loading: "loading",
33
+ class_loaded: "loaded",
34
+ skip_invisible: true,
35
+ callback_load: null,
36
+ callback_error: null,
37
+ callback_set: null,
38
+ callback_processed: null
39
+ };
40
+ _supportsAddEventListener = !!window.addEventListener;
41
+ _supportsAttachEvent = !!window.attachEvent;
42
+ _supportsClassList = !!document.body.classList;
43
+
44
+ _isInitialized = true;
45
+ }
46
+ }
47
+
48
+ function _addEventListener(element, eventName, callback) {
49
+ // Use addEventListener if available
50
+ if (_supportsAddEventListener) {
51
+ element.addEventListener(eventName, callback);
52
+ return;
53
+ }
54
+ // Otherwise use attachEvent, set this and event
55
+ if (_supportsAttachEvent) {
56
+ element.attachEvent('on' + eventName, (function(el) {
57
+ return function() {
58
+ callback.call(el, window.event);
59
+ };
60
+ }(element)));
61
+ // Break closure and primary circular reference to element
62
+ element = null;
63
+ }
64
+ }
65
+
66
+ function _removeEventListener(element, eventName, callback) {
67
+ // Use removeEventListener if available
68
+ if (_supportsAddEventListener) {
69
+ element.removeEventListener(eventName, callback);
70
+ return;
71
+ }
72
+ // Otherwise use detachEvent
73
+ if (_supportsAttachEvent) {
74
+ element.detachEvent('on' + eventName, callback);
75
+ }
76
+ }
77
+
78
+ function _isInsideViewport(element, container, threshold) {
79
+
80
+ var ownerDocument, documentTop, documentLeft;
81
+
82
+ function _getDocumentWidth() {
83
+ return window.innerWidth || (ownerDocument.documentElement.clientWidth || document.body.clientWidth);
84
+ }
85
+
86
+ function _getDocumentHeight() {
87
+ return window.innerHeight || (ownerDocument.documentElement.clientHeight || document.body.clientHeight);
88
+ }
89
+
90
+ function _getTopOffset(element) {
91
+ return element.getBoundingClientRect().top + documentTop - ownerDocument.documentElement.clientTop;
92
+ }
93
+
94
+ function _getLeftOffset(element) {
95
+ return element.getBoundingClientRect().left + documentLeft - ownerDocument.documentElement.clientLeft;
96
+ }
97
+
98
+ function _isBelowViewport() {
99
+ var fold;
100
+ if (container === window) {
101
+ fold = _getDocumentHeight() + documentTop;
102
+ } else {
103
+ fold = _getTopOffset(container) + container.offsetHeight;
104
+ }
105
+ return fold <= _getTopOffset(element) - threshold;
106
+ }
107
+
108
+ function _isAtRightOfViewport() {
109
+ var fold;
110
+ if (container === window) {
111
+ fold = _getDocumentWidth() + window.pageXOffset;
112
+ } else {
113
+ fold = _getLeftOffset(container) + _getDocumentWidth();
114
+ }
115
+ return fold <= _getLeftOffset(element) - threshold;
116
+ }
117
+
118
+ function _isAboveViewport() {
119
+ var fold;
120
+ if (container === window) {
121
+ fold = documentTop;
122
+ } else {
123
+ fold = _getTopOffset(container);
124
+ }
125
+ return fold >= _getTopOffset(element) + threshold + element.offsetHeight;
126
+ }
127
+
128
+ function _isAtLeftOfViewport() {
129
+ var fold;
130
+ if (container === window) {
131
+ fold = documentLeft;
132
+ } else {
133
+ fold = _getLeftOffset(container);
134
+ }
135
+ return fold >= _getLeftOffset(element) + threshold + element.offsetWidth;
136
+ }
137
+
138
+ ownerDocument = element.ownerDocument;
139
+ documentTop = window.pageYOffset || ownerDocument.body.scrollTop;
140
+ documentLeft = window.pageXOffset || ownerDocument.body.scrollLeft;
141
+
142
+ return !_isBelowViewport() && !_isAboveViewport() && !_isAtRightOfViewport() && !_isAtLeftOfViewport();
143
+ }
144
+
145
+ function _now() {
146
+ var d = new Date();
147
+ return d.getTime();
148
+ }
149
+
150
+ function _merge_objects(obj1, obj2) {
151
+ var obj3 = {},
152
+ propertyName;
153
+ for (propertyName in obj1) {
154
+ if (obj1.hasOwnProperty(propertyName)) {
155
+ obj3[propertyName] = obj1[propertyName];
156
+ }
157
+ }
158
+ for (propertyName in obj2) {
159
+ if (obj2.hasOwnProperty(propertyName)) {
160
+ obj3[propertyName] = obj2[propertyName];
161
+ }
162
+ }
163
+ return obj3;
164
+ }
165
+
166
+ function _convertToArray(nodeSet) {
167
+ try {
168
+ return Array.prototype.slice.call(nodeSet);
169
+ } catch (e) {
170
+ var array = [],
171
+ i, l = nodeSet.length;
172
+
173
+ for (i = 0; i < l; i++) {
174
+ array.push(nodeSet[i]);
175
+ }
176
+ return array;
177
+ }
178
+ }
179
+
180
+ function _addClass(element, className) {
181
+ /* HTML 5 compliant browsers. */
182
+ if (_supportsClassList) {
183
+ element.classList.add(className);
184
+ return;
185
+ }
186
+ /* Legacy browsers (IE<10) support. */
187
+ element.className += (element.className ? ' ' : '') + className;
188
+ }
189
+
190
+ function _removeClass(element, className) {
191
+ /* HTML 5 compliant browsers. */
192
+ if (_supportsClassList) {
193
+ element.classList.remove(className);
194
+ return;
195
+ }
196
+ /* Legacy browsers (IE<10) support. */
197
+ element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').replace(/^\s+/, '').replace(/\s+$/, '');
198
+ }
199
+
200
+ function _setSourcesForPicture(element, srcsetDataAttribute) {
201
+ var parent = element.parentElement;
202
+ if (parent.tagName !== 'PICTURE') {
203
+ return;
204
+ }
205
+ for (var i = 0; i < parent.children.length; i++) {
206
+ var pictureChild = parent.children[i];
207
+ if (pictureChild.tagName === 'SOURCE') {
208
+ var sourceSrcset = pictureChild.getAttribute('data-' + srcsetDataAttribute);
209
+ if (sourceSrcset) {
210
+ pictureChild.setAttribute('srcset', sourceSrcset);
211
+ }
212
+ }
213
+ }
214
+ }
215
+
216
+ function _setSources(element, srcsetDataAttribute, srcDataAttribute) {
217
+ var tagName = element.tagName;
218
+ var elementSrc = element.getAttribute('data-' + srcDataAttribute);
219
+ if (tagName === "IMG") {
220
+ _setSourcesForPicture(element, srcsetDataAttribute);
221
+ var imgSrcset = element.getAttribute('data-' + srcsetDataAttribute);
222
+ if (imgSrcset) element.setAttribute("srcset", imgSrcset);
223
+ if (elementSrc) element.setAttribute("src", elementSrc);
224
+ return;
225
+ }
226
+ if (tagName === "IFRAME") {
227
+ if (elementSrc) element.setAttribute("src", elementSrc);
228
+ return;
229
+ }
230
+ element.style.backgroundImage = "url(" + elementSrc + ")";
231
+ }
232
+
233
+ function _bind(fn, obj) {
234
+ return function() {
235
+ return fn.apply(obj, arguments);
236
+ };
237
+ }
238
+
239
+
240
+ /*
241
+ * INITIALIZER
242
+ * -----------
243
+ */
244
+
245
+ function LazyLoad(instanceSettings) {
246
+ _init();
247
+
248
+ this._settings = _merge_objects(_defaultSettings, instanceSettings);
249
+ this._queryOriginNode = this._settings.container === window ? document : this._settings.container;
250
+
251
+ this._previousLoopTime = 0;
252
+ this._loopTimeout = null;
253
+
254
+ this._handleScrollFn = _bind(this.handleScroll, this);
255
+
256
+ _addEventListener(window, "resize", this._handleScrollFn);
257
+ this.update();
258
+ }
259
+
260
+
261
+ /*
262
+ * PRIVATE FUNCTIONS *RELATED* TO A SPECIFIC INSTANCE OF LAZY LOAD
263
+ * ---------------------------------------------------------------
264
+ */
265
+
266
+ LazyLoad.prototype._showOnAppear = function(element) {
267
+ var settings = this._settings;
268
+
269
+ function loadCallback() {
270
+ /* As this method is asynchronous, it must be protected against external destroy() calls */
271
+ if (settings === null) {
272
+ return;
273
+ }
274
+ /* Calling LOAD callback */
275
+ if (settings.callback_load) {
276
+ settings.callback_load(element);
277
+ }
278
+ _removeClass(element, settings.class_loading);
279
+ _addClass(element, settings.class_loaded);
280
+ _removeEventListener(element, "load", loadCallback);
281
+ }
282
+
283
+ if (element.tagName === "IMG" || element.tagName === "IFRAME") {
284
+ _addEventListener(element, "load", loadCallback);
285
+ _addEventListener(element, "error", function () {
286
+ _removeEventListener(element, "load", loadCallback);
287
+ _removeClass(element, settings.class_loading);
288
+ if (settings.callback_error) {
289
+ settings.callback_error(element);
290
+ }
291
+ });
292
+ _addClass(element, settings.class_loading);
293
+ }
294
+
295
+ _setSources(element, settings.data_srcset, settings.data_src);
296
+ /* Calling SET callback */
297
+ if (settings.callback_set) {
298
+ settings.callback_set(element);
299
+ }
300
+ };
301
+
302
+ LazyLoad.prototype._loopThroughElements = function() {
303
+ var i, element,
304
+ settings = this._settings,
305
+ elements = this._elements,
306
+ elementsLength = (!elements) ? 0 : elements.length,
307
+ processedIndexes = [];
308
+
309
+ for (i = 0; i < elementsLength; i++) {
310
+ element = elements[i];
311
+ /* If must skip_invisible and element is invisible, skip it */
312
+ if (settings.skip_invisible && (element.offsetParent === null)) {
313
+ continue;
314
+ }
315
+ if (_isInsideViewport(element, settings.container, settings.threshold)) {
316
+ this._showOnAppear(element);
317
+
318
+ /* Marking the element as processed. */
319
+ processedIndexes.push(i);
320
+ element.wasProcessed = true;
321
+ }
322
+ }
323
+ /* Removing processed elements from this._elements. */
324
+ while (processedIndexes.length > 0) {
325
+ elements.splice(processedIndexes.pop(), 1);
326
+ /* Calling the end loop callback */
327
+ if (settings.callback_processed) {
328
+ settings.callback_processed(elements.length);
329
+ }
330
+ }
331
+ /* Stop listening to scroll event when 0 elements remains */
332
+ if (elementsLength === 0) {
333
+ this._stopScrollHandler();
334
+ }
335
+ };
336
+
337
+ LazyLoad.prototype._purgeElements = function() {
338
+ var i, element,
339
+ elements = this._elements,
340
+ elementsLength = elements.length,
341
+ elementsToPurge = [];
342
+
343
+ for (i = 0; i < elementsLength; i++) {
344
+ element = elements[i];
345
+ /* If the element has already been processed, skip it */
346
+ if (element.wasProcessed) {
347
+ elementsToPurge.push(i);
348
+ }
349
+ }
350
+ /* Removing elements to purge from this._elements. */
351
+ while (elementsToPurge.length > 0) {
352
+ elements.splice(elementsToPurge.pop(), 1);
353
+ }
354
+ };
355
+
356
+ LazyLoad.prototype._startScrollHandler = function() {
357
+ if (!this._isHandlingScroll) {
358
+ this._isHandlingScroll = true;
359
+ _addEventListener(this._settings.container, "scroll", this._handleScrollFn);
360
+ }
361
+ };
362
+
363
+ LazyLoad.prototype._stopScrollHandler = function() {
364
+ if (this._isHandlingScroll) {
365
+ this._isHandlingScroll = false;
366
+ _removeEventListener(this._settings.container, "scroll", this._handleScrollFn);
367
+ }
368
+ };
369
+
370
+
371
+ /*
372
+ * PUBLIC FUNCTIONS
373
+ * ----------------
374
+ */
375
+
376
+ LazyLoad.prototype.handleScroll = function() {
377
+ var remainingTime,
378
+ now,
379
+ throttle;
380
+
381
+ // IE8 fix for destroy() malfunctioning
382
+ if (!this._settings) {
383
+ return;
384
+ }
385
+
386
+ now = _now();
387
+ throttle = this._settings.throttle;
388
+
389
+ if (throttle !== 0) {
390
+ remainingTime = throttle - (now - this._previousLoopTime);
391
+ if (remainingTime <= 0 || remainingTime > throttle) {
392
+ if (this._loopTimeout) {
393
+ clearTimeout(this._loopTimeout);
394
+ this._loopTimeout = null;
395
+ }
396
+ this._previousLoopTime = now;
397
+ this._loopThroughElements();
398
+ } else if (!this._loopTimeout) {
399
+ this._loopTimeout = setTimeout(_bind(function() {
400
+ this._previousLoopTime = _now();
401
+ this._loopTimeout = null;
402
+ this._loopThroughElements();
403
+ }, this), remainingTime);
404
+ }
405
+ } else {
406
+ this._loopThroughElements();
407
+ }
408
+ };
409
+
410
+ LazyLoad.prototype.update = function() {
411
+ this._elements = _convertToArray(this._queryOriginNode.querySelectorAll(this._settings.elements_selector));
412
+ this._purgeElements();
413
+ this._loopThroughElements();
414
+ this._startScrollHandler();
415
+ };
416
+
417
+ LazyLoad.prototype.destroy = function() {
418
+ _removeEventListener(window, "resize", this._handleScrollFn);
419
+ if (this._loopTimeout) {
420
+ clearTimeout(this._loopTimeout);
421
+ this._loopTimeout = null;
422
+ }
423
+ this._stopScrollHandler();
424
+ this._elements = null;
425
+ this._queryOriginNode = null;
426
+ this._settings = null;
427
+ };
428
+
429
+
430
+ return LazyLoad;
431
+
432
+
433
+ }));
assets/js/lazyload-3.0.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ !function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.LazyLoad=b()}(this,function(){function a(){r||(n={elements_selector:"img",container:window,threshold:300,throttle:50,data_src:"original",data_srcset:"original-set",class_loading:"loading",class_loaded:"loaded",skip_invisible:!0,callback_load:null,callback_error:null,callback_set:null,callback_processed:null},o=!!window.addEventListener,p=!!window.attachEvent,q=!!document.body.classList,r=!0)}function b(a,b,c){return o?void a.addEventListener(b,c):void(p&&(a.attachEvent("on"+b,function(a){return function(){c.call(a,window.event)}}(a)),a=null))}function c(a,b,c){return o?void a.removeEventListener(b,c):void(p&&a.detachEvent("on"+b,c))}function d(a,b,c){function d(){return window.innerWidth||l.documentElement.clientWidth||document.body.clientWidth}function e(){return window.innerHeight||l.documentElement.clientHeight||document.body.clientHeight}function f(a){return a.getBoundingClientRect().top+m-l.documentElement.clientTop}function g(a){return a.getBoundingClientRect().left+n-l.documentElement.clientLeft}function h(){var d;return d=b===window?e()+m:f(b)+b.offsetHeight,d<=f(a)-c}function i(){var e;return e=b===window?d()+window.pageXOffset:g(b)+d(),e<=g(a)-c}function j(){var d;return d=b===window?m:f(b),d>=f(a)+c+a.offsetHeight}function k(){var d;return d=b===window?n:g(b),d>=g(a)+c+a.offsetWidth}var l,m,n;return l=a.ownerDocument,m=window.pageYOffset||l.body.scrollTop,n=window.pageXOffset||l.body.scrollLeft,!(h()||j()||i()||k())}function e(){var a=new Date;return a.getTime()}function f(a,b){var c,d={};for(c in a)a.hasOwnProperty(c)&&(d[c]=a[c]);for(c in b)b.hasOwnProperty(c)&&(d[c]=b[c]);return d}function g(a){try{return Array.prototype.slice.call(a)}catch(b){var c,d=[],e=a.length;for(c=0;e>c;c++)d.push(a[c]);return d}}function h(a,b){return q?void a.classList.add(b):void(a.className+=(a.className?" ":"")+b)}function i(a,b){return q?void a.classList.remove(b):void(a.className=a.className.replace(new RegExp("(^|\\s+)"+b+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,""))}function j(a,b){var c=a.parentElement;if("PICTURE"===c.tagName)for(var d=0;d<c.children.length;d++){var e=c.children[d];if("SOURCE"===e.tagName){var f=e.getAttribute("data-"+b);f&&e.setAttribute("srcset",f)}}}function k(a,b,c){var d=a.tagName,e=a.getAttribute("data-"+c);if("IMG"===d){j(a,b);var f=a.getAttribute("data-"+b);return f&&a.setAttribute("srcset",f),void(e&&a.setAttribute("src",e))}return"IFRAME"===d?void(e&&a.setAttribute("src",e)):void(a.style.backgroundImage="url("+e+")")}function l(a,b){return function(){return a.apply(b,arguments)}}function m(c){a(),this._settings=f(n,c),this._queryOriginNode=this._settings.container===window?document:this._settings.container,this._previousLoopTime=0,this._loopTimeout=null,this._handleScrollFn=l(this.handleScroll,this),b(window,"resize",this._handleScrollFn),this.update()}var n,o,p,q,r=!1;return m.prototype._showOnAppear=function(a){function d(){null!==e&&(e.callback_load&&e.callback_load(a),i(a,e.class_loading),h(a,e.class_loaded),c(a,"load",d))}var e=this._settings;("IMG"===a.tagName||"IFRAME"===a.tagName)&&(b(a,"load",d),b(a,"error",function(){c(a,"load",d),i(a,e.class_loading),e.callback_error&&e.callback_error(a)}),h(a,e.class_loading)),k(a,e.data_srcset,e.data_src),e.callback_set&&e.callback_set(a)},m.prototype._loopThroughElements=function(){var a,b,c=this._settings,e=this._elements,f=e?e.length:0,g=[];for(a=0;f>a;a++)b=e[a],c.skip_invisible&&null===b.offsetParent||d(b,c.container,c.threshold)&&(this._showOnAppear(b),g.push(a),b.wasProcessed=!0);for(;g.length>0;)e.splice(g.pop(),1),c.callback_processed&&c.callback_processed(e.length);0===f&&this._stopScrollHandler()},m.prototype._purgeElements=function(){var a,b,c=this._elements,d=c.length,e=[];for(a=0;d>a;a++)b=c[a],b.wasProcessed&&e.push(a);for(;e.length>0;)c.splice(e.pop(),1)},m.prototype._startScrollHandler=function(){this._isHandlingScroll||(this._isHandlingScroll=!0,b(this._settings.container,"scroll",this._handleScrollFn))},m.prototype._stopScrollHandler=function(){this._isHandlingScroll&&(this._isHandlingScroll=!1,c(this._settings.container,"scroll",this._handleScrollFn))},m.prototype.handleScroll=function(){var a,b,c;this._settings&&(b=e(),c=this._settings.throttle,0!==c?(a=c-(b-this._previousLoopTime),0>=a||a>c?(this._loopTimeout&&(clearTimeout(this._loopTimeout),this._loopTimeout=null),this._previousLoopTime=b,this._loopThroughElements()):this._loopTimeout||(this._loopTimeout=setTimeout(l(function(){this._previousLoopTime=e(),this._loopTimeout=null,this._loopThroughElements()},this),a))):this._loopThroughElements())},m.prototype.update=function(){this._elements=g(this._queryOriginNode.querySelectorAll(this._settings.elements_selector)),this._purgeElements(),this._loopThroughElements(),this._startScrollHandler()},m.prototype.destroy=function(){c(window,"resize",this._handleScrollFn),this._loopTimeout&&(clearTimeout(this._loopTimeout),this._loopTimeout=null),this._stopScrollHandler(),this._elements=null,this._queryOriginNode=null,this._settings=null},m});
2
+ //# sourceMappingURL=lazyload.min.js.map
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: juliobox, geekpress, wp_media
3
  Tags: lazyload, lazy load, images, thumbnail, thumbnails, smiley, smilies, avatar, gravatar
4
  Requires at least: 3.0
5
- Tested up to: 4.5
6
- Stable tag: 1.0.4
7
 
8
  The tiny Lazy Load script for WordPress without jQuery or others libraries.
9
 
@@ -11,9 +11,9 @@ The tiny Lazy Load script for WordPress without jQuery or others libraries.
11
 
12
  Lazy Load displays images on a page only when they are visible to the user. This reduces the number of HTTP requests mechanism and improves the loading time.
13
 
14
- This plugin works on thumbnails, all images in a post content or in a widget text, avatars and smilies. No JavaScript library such as jQuery is used and the script weighs less than 2kb.
15
 
16
- Simply install the plugin to enjoy a faster website. No options are available : you install it and the plugin takes care of everything.
17
 
18
  = Related Plugins =
19
  * <a href="https://wordpress.org/plugins/imagify/">Imagify</a>: Best Image Optimizer to speed up your website with lighter images.
@@ -46,6 +46,14 @@ Simply add a 'data-no-lazy="1"' property in you IMG tag.
46
 
47
  == Changelog ==
48
 
 
 
 
 
 
 
 
 
49
  = 1.0.4 =
50
  * 28 apr. 2015
51
  * Bug Fix: Resolved a conflict between LazyLoad & Emoji since WordPress 4.2
2
  Contributors: juliobox, geekpress, wp_media
3
  Tags: lazyload, lazy load, images, thumbnail, thumbnails, smiley, smilies, avatar, gravatar
4
  Requires at least: 3.0
5
+ Tested up to: 4.7.1
6
+ Stable tag: 1.1
7
 
8
  The tiny Lazy Load script for WordPress without jQuery or others libraries.
9
 
11
 
12
  Lazy Load displays images on a page only when they are visible to the user. This reduces the number of HTTP requests mechanism and improves the loading time.
13
 
14
+ This plugin works on thumbnails, all images in a post content or in a widget text, avatars and smilies. No JavaScript library such as jQuery is used and the script weight is less than 6kb.
15
 
16
+ Simply install the plugin to enjoy a faster website. No options are available: you install it and the plugin takes care of everything.
17
 
18
  = Related Plugins =
19
  * <a href="https://wordpress.org/plugins/imagify/">Imagify</a>: Best Image Optimizer to speed up your website with lighter images.
46
 
47
  == Changelog ==
48
 
49
+ = 1.1 =
50
+ * 12 feb. 2017
51
+ * *New*
52
+ * JS library updated
53
+ * Support for iFrame
54
+ * Support for srcset and sizes
55
+ * New options page
56
+
57
  = 1.0.4 =
58
  * 28 apr. 2015
59
  * Bug Fix: Resolved a conflict between LazyLoad & Emoji since WordPress 4.2
rocket-lazy-load.php CHANGED
@@ -1,97 +1,231 @@
1
  <?php
2
  defined( 'ABSPATH' ) or die( 'Cheatin\' uh?' );
3
 
4
- /*
5
- Plugin Name: Rocket Lazy Load
6
- Plugin URI: http://wordpress.org/plugins/rocket-lazy-load/
7
- Description: The tiny Lazy Load script for WordPress without jQuery or others libraries.
8
- Version: 1.0.4
9
- Author: WP Media
10
- Author URI: http://wp-rocket.me
11
-
12
- Copyright 2015 WP Media
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- This program is free software; you can redistribute it and/or modify
15
- it under the terms of the GNU General Public License as published by
16
- the Free Software Foundation; either version 2 of the License, or
17
- (at your option) any later version.
18
 
19
- This program is distributed in the hope that it will be useful,
20
- but WITHOUT ANY WARRANTY; without even the implied warranty of
21
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
- GNU General Public License for more details.
 
 
 
 
23
 
24
- You should have received a copy of the GNU General Public License
25
- along with this program. If not, see <http://www.gnu.org/licenses/>.
 
 
 
26
 
27
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  /**
30
  * Add Lazy Load JavaScript in the header
31
- * No jQuery or other library is required !!
32
  *
33
  * @since 1.0
34
  */
35
- add_action( 'wp_head', 'rocket_lazyload_script', PHP_INT_MAX );
36
  function rocket_lazyload_script() {
37
- if ( ! apply_filters( 'do_rocket_lazyload', true ) ) {
38
  return;
39
  }
40
 
41
- echo '<script type="text/javascript">(function(a,e){function f(){var d=0;if(e.body&&e.body.offsetWidth){d=e.body.offsetHeight}if(e.compatMode=="CSS1Compat"&&e.documentElement&&e.documentElement.offsetWidth){d=e.documentElement.offsetHeight}if(a.innerWidth&&a.innerHeight){d=a.innerHeight}return d}function b(g){var d=ot=0;if(g.offsetParent){do{d+=g.offsetLeft;ot+=g.offsetTop}while(g=g.offsetParent)}return{left:d,top:ot}}function c(){var l=e.querySelectorAll("[data-lazy-original]");var j=a.pageYOffset||e.documentElement.scrollTop||e.body.scrollTop;var d=f();for(var k=0;k<l.length;k++){var h=l[k];var g=b(h).top;if(g<(d+j)){h.src=h.getAttribute("data-lazy-original");h.removeAttribute("data-lazy-original")}}}if(a.addEventListener){a.addEventListener("DOMContentLoaded",c,false);a.addEventListener("scroll",c,false)}else{a.attachEvent("onload",c);a.attachEvent("onscroll",c)}})(window,document);</script>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
-
44
-
45
 
46
  /**
47
  * Replace Gravatar, thumbnails, images in post content and in widget text by LazyLoad
48
  *
 
49
  * @since 1.0
 
 
 
50
  */
51
- add_filter( 'get_avatar', 'rocket_lazyload_images', PHP_INT_MAX );
52
- add_filter( 'the_content', 'rocket_lazyload_images', PHP_INT_MAX );
53
- add_filter( 'widget_text', 'rocket_lazyload_images', PHP_INT_MAX );
54
- add_filter( 'post_thumbnail_html', 'rocket_lazyload_images', PHP_INT_MAX );
55
  function rocket_lazyload_images( $html ) {
56
- // Don't LazyLoad if the thumbnail is in admin, a feed or a post preview
57
- if( is_admin() || is_feed() || is_preview() || empty( $html ) ) {
58
  return $html;
59
  }
60
 
61
- // You can stop the LalyLoad process with a hook
62
  if ( ! apply_filters( 'do_rocket_lazyload', true ) ) {
63
  return $html;
64
  }
65
 
66
- $html = preg_replace_callback( '#<img([^>]*) src=("(?:[^"]+)"|\'(?:[^\']+)\'|(?:[^ >]+))([^>]*)>#', '__rocket_lazyload_replace_callback', $html );
67
 
68
  return $html;
69
  }
70
-
 
 
 
 
71
 
72
  /**
73
  * Used to check if we have to LazyLoad this or not
74
  *
 
75
  * @since 1.0.1
 
 
 
76
  */
77
- function __rocket_lazyload_replace_callback( $matches ) {
78
- if ( strpos( $matches[1] . $matches[3], 'data-no-lazy=' ) === false && strpos( $matches[1] . $matches[3], 'data-lazy-original=' ) === false && strpos( $matches[2], '/wpcf7_captcha/' ) === false ) {
79
- $html = sprintf( '<img%1$s src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-lazy-original=%2$s%3$s><noscript><img%1$s src=%2$s%3$s></noscript>',
80
- $matches[1], $matches[2], $matches[3] );
81
 
82
- /**
83
- * Filter the LazyLoad HTML output
84
- *
85
- * @since 1.0.2
86
- *
87
- * @param array $html Output that will be printed
88
- */
89
- $html = apply_filters( 'rocket_lazyload_html', $html, true );
90
 
91
- return $html;
92
- } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  return $matches[0];
94
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
 
97
  /**
@@ -99,19 +233,29 @@ function __rocket_lazyload_replace_callback( $matches ) {
99
  *
100
  * @since 1.0
101
  */
102
- remove_filter( 'the_content', 'convert_smilies' );
103
- remove_filter( 'the_excerpt', 'convert_smilies' );
104
- remove_filter( 'comment_text', 'convert_smilies' );
 
105
 
106
- add_filter( 'the_content', 'rocket_convert_smilies' );
107
- add_filter( 'the_excerpt', 'rocket_convert_smilies' );
108
- add_filter( 'comment_text', 'rocket_convert_smilies' );
 
 
 
 
 
 
109
 
110
  /**
111
  * Convert text equivalent of smilies to images.
112
  *
113
  * @source convert_smilies() in /wp-includes/formattings.php
114
  * @since 1.0
 
 
 
115
  */
116
  function rocket_convert_smilies( $text ) {
117
 
@@ -119,29 +263,29 @@ function rocket_convert_smilies( $text ) {
119
  $output = '';
120
 
121
  if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) {
122
- // HTML loop taken from texturize function, could possible be consolidated
123
- $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between
124
- $stop = count( $textarr );// loop stuff
125
 
126
- // Ignore proessing of specific tags
127
  $tags_to_ignore = 'code|pre|style|script|textarea';
128
  $ignore_block_element = '';
129
 
130
  for ( $i = 0; $i < $stop; $i++ ) {
131
  $content = $textarr[ $i ];
132
 
133
- // If we're in an ignore block, wait until we find its closing tag
134
- if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) {
135
  $ignore_block_element = $matches[1];
136
  }
137
 
138
- // If it's not a tag and not in ignore block
139
- if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) {
140
  $content = preg_replace_callback( $wp_smiliessearch, 'rocket_translate_smiley', $content );
141
  }
142
 
143
- // did we exit ignore block
144
- if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) {
145
  $ignore_block_element = '';
146
  }
147
 
@@ -159,12 +303,16 @@ function rocket_convert_smilies( $text ) {
159
  *
160
  * @source translate_smiley() in /wp-includes/formattings.php
161
  * @since 1.0
 
 
 
162
  */
163
  function rocket_translate_smiley( $matches ) {
164
  global $wpsmiliestrans;
165
 
166
- if ( count( $matches ) == 0 )
167
  return '';
 
168
 
169
  $smiley = trim( reset( $matches ) );
170
  $img = $wpsmiliestrans[ $smiley ];
@@ -174,7 +322,7 @@ function rocket_translate_smiley( $matches ) {
174
  $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
175
 
176
  // Don't convert smilies that aren't images - they're probably emoji.
177
- if ( ! in_array( $ext, $image_exts ) ) {
178
  return $img;
179
  }
180
 
@@ -189,11 +337,92 @@ function rocket_translate_smiley( $matches ) {
189
  */
190
  $src_url = apply_filters( 'smilies_src', includes_url( "images/smilies/$img" ), $img, site_url() );
191
 
192
- // Don't lazy-load if process is stopped with a hook
193
  if ( apply_filters( 'do_rocket_lazyload', true ) ) {
194
  return sprintf( ' <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-lazy-original="%s" alt="%s" class="wp-smiley" /> ', esc_url( $src_url ), esc_attr( $smiley ) );
195
  } else {
196
  return sprintf( ' <img src="%s" alt="%s" class="wp-smiley" /> ', esc_url( $src_url ), esc_attr( $smiley ) );
197
  }
198
 
199
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
  defined( 'ABSPATH' ) or die( 'Cheatin\' uh?' );
3
 
4
+ /**
5
+ * Plugin Name: Rocket Lazy Load
6
+ * Plugin URI: http://wordpress.org/plugins/rocket-lazy-load/
7
+ * Description: The tiny Lazy Load script for WordPress without jQuery or others libraries.
8
+ * Version: 1.1
9
+ * Author: WP Media
10
+ * Author URI: https://wp-rocket.me
11
+ * Text Domain: rocket-lazy-load
12
+ * Domain Path: /languages
13
+ *
14
+ * Copyright 2015 WP Media
15
+ *
16
+ * This program is free software; you can redistribute it and/or modify
17
+ * it under the terms of the GNU General Public License as published by
18
+ * the Free Software Foundation; either version 2 of the License, or
19
+ * (at your option) any later version.
20
+ *
21
+ * This program is distributed in the hope that it will be useful,
22
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ * GNU General Public License for more details.
25
+ *
26
+ * You should have received a copy of the GNU General Public License
27
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28
+ */
29
+ define( 'ROCKET_LL_VERSION', '1.1' );
30
+ define( 'ROCKET_LL_PATH', realpath( plugin_dir_path( __FILE__ ) ) . '/' );
31
+ define( 'ROCKET_LL_ASSETS_URL', plugin_dir_url( __FILE__ ) . 'assets/' );
32
+ define( 'ROCKET_LL_FRONT_JS_URL', ROCKET_LL_ASSETS_URL . 'js/' );
33
+ define( 'ROCKET_LL_JS_VERSION' , '3.0' );
34
 
 
 
 
 
35
 
36
+ /**
37
+ * Initialize the plugin.
38
+ *
39
+ * @since 1.1
40
+ * @return void
41
+ */
42
+ function rocket_lazyload_init() {
43
+ load_plugin_textdomain( 'rocket-lazy-load', false, basename( dirname( __FILE__ ) ) . '/languages/' );
44
 
45
+ if ( is_admin() ) {
46
+ require( ROCKET_LL_PATH . 'admin/admin.php' );
47
+ }
48
+ }
49
+ add_action( 'plugins_loaded', 'rocket_lazyload_init' );
50
 
51
+ /**
52
+ * A wrapper to easily get rocket lazyload option
53
+ *
54
+ * @since 1.1
55
+ * @author Remy Perona
56
+ *
57
+ * @param string $option The option name.
58
+ * @param bool $default (default: false) The default value of option.
59
+ * @return mixed The option value
60
+ */
61
+ function rocket_lazyload_get_option( $option, $default = false ) {
62
+ $options = get_option( 'rocket_lazyload_options' );
63
+ return isset( $options[ $option ] ) && '' !== $options[ $option ] ? $options[ $option ] : $default;
64
+ }
65
 
66
  /**
67
  * Add Lazy Load JavaScript in the header
68
+ * No jQuery or other library is required
69
  *
70
  * @since 1.0
71
  */
 
72
  function rocket_lazyload_script() {
73
+ if ( ! rocket_lazyload_get_option( 'images' ) && ! rocket_lazyload_get_option( 'iframes' ) || ! apply_filters( 'do_rocket_lazyload', true ) ) {
74
  return;
75
  }
76
 
77
+ $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
78
+ $ll_url = ROCKET_LL_FRONT_JS_URL . 'lazyload-' . ROCKET_LL_JS_VERSION . $suffix . '.js';
79
+
80
+ echo <<<HTML
81
+ <script data-cfasync="false">(function(w,d){function loadScript(c,b){var a=d.createElement("script");a.async=!0;a.readyState?a.onreadystatechange=function(){if("loaded"===a.readyState||"complete"===a.readyState)a.onreadystatechange=null,b()}:a.onload=function(){b()};a.src=c;d.getElementsByTagName("head")[0].appendChild(a)}loadScript("$ll_url",function(){
82
+ var rocket_ll = new LazyLoad({
83
+ elements_selector: "img, iframe",
84
+ data_src: "lazy-src",
85
+ data_srcset: "lazy-srcset",
86
+ class_loading: "lazyloading",
87
+ class_loaded: "lazyloaded",
88
+ callback_set: function(element) {
89
+ //todo: check fitvids compatibility (class or data-attribute)
90
+ if ( element.tagName === "IFRAME" && element.classList.contains("fitvidscompatible") ) {
91
+ if ( element.classList.contains("lazyloaded") ) {
92
+ //todo: check if $.fn.fitvids() is available
93
+ if ( typeof $ === "function" ) {
94
+ $( element ).parent().fitVids();
95
+ }
96
+ } else {
97
+ var temp = setInterval( function() {
98
+ //todo: check if $.fn.fitvids() is available
99
+ if ( element.classList.contains("lazyloaded") && typeof $ === "function" ) {
100
+ $( element ).parent().fitVids();
101
+ clearInterval( temp );
102
+ } else {
103
+ clearInterval( temp );
104
+ }
105
+ }, 50 );
106
+ }
107
+ } // if element is an iframe
108
+ }
109
+ });
110
+ });})(window,document);</script>
111
+ HTML;
112
  }
113
+ add_action( 'wp_head', 'rocket_lazyload_script', PHP_INT_MAX );
 
114
 
115
  /**
116
  * Replace Gravatar, thumbnails, images in post content and in widget text by LazyLoad
117
  *
118
+ * @since 1.1 Support for get_image_tag filter.
119
  * @since 1.0
120
+ *
121
+ * @param string $html HTML code to parse.
122
+ * @return string Updated HTML code
123
  */
 
 
 
 
124
  function rocket_lazyload_images( $html ) {
125
+ // Don't LazyLoad if the thumbnail is in admin, a feed or a post preview.
126
+ if ( ! rocket_lazyload_get_option( 'images' ) || is_admin() || is_feed() || is_preview() || empty( $html ) || ( defined( 'DONOTLAZYLOAD' ) && DONOTLAZYLOAD ) || wp_script_is( 'twentytwenty-twentytwenty', 'enqueued' ) ) {
127
  return $html;
128
  }
129
 
130
+ // You can stop the LalyLoad process with a hook.
131
  if ( ! apply_filters( 'do_rocket_lazyload', true ) ) {
132
  return $html;
133
  }
134
 
135
+ $html = preg_replace_callback( '#<img([^>]*) src=("(?:[^"]+)"|\'(?:[^\']+)\'|(?:[^ >]+))([^>]*)>#', 'rocket_lazyload_replace_callback', $html );
136
 
137
  return $html;
138
  }
139
+ add_filter( 'get_avatar' , 'rocket_lazyload_images', PHP_INT_MAX );
140
+ add_filter( 'the_content' , 'rocket_lazyload_images', PHP_INT_MAX );
141
+ add_filter( 'widget_text' , 'rocket_lazyload_images', PHP_INT_MAX );
142
+ add_filter( 'get_image_tag' , 'rocket_lazyload_images', PHP_INT_MAX );
143
+ add_filter( 'post_thumbnail_html', 'rocket_lazyload_images', PHP_INT_MAX );
144
 
145
  /**
146
  * Used to check if we have to LazyLoad this or not
147
  *
148
+ * @since 1.1 Don't apply LazyLoad on images from WP Retina x2
149
  * @since 1.0.1
150
+ *
151
+ * @param string $matches a string matching the pattern to find images in HTML code.
152
+ * @return string Updated string with lazyload data
153
  */
154
+ function rocket_lazyload_replace_callback( $matches ) {
 
 
 
155
 
156
+ if ( function_exists( 'wr2x_picture_rewrite' ) ) {
157
+ if ( wr2x_get_retina( trailingslashit( ABSPATH ) . wr2x_get_pathinfo_from_image_src( trim( $matches[2], '"' ) ) ) ) {
158
+ return $matches[0];
159
+ }
160
+ }
 
 
 
161
 
162
+ $excluded_attributes = apply_filters( 'rocket_lazyload_excluded_attributes', array(
163
+ 'data-no-lazy=',
164
+ 'data-lazy-original=',
165
+ 'data-lazy-src=',
166
+ 'data-lazysrc=',
167
+ 'data-lazyload=',
168
+ 'data-bgposition=',
169
+ 'data-envira-src=',
170
+ 'fullurl=',
171
+ 'lazy-slider-img=',
172
+ 'data-srcset=',
173
+ 'class="ls-l',
174
+ 'class="ls-bg',
175
+ ) );
176
+
177
+ $excluded_src = apply_filters( 'rocket_lazyload_excluded_src', array(
178
+ '/wpcf7_captcha/',
179
+ 'timthumb.php?src',
180
+ ) );
181
+
182
+ if ( rocket_is_excluded_lazyload( $matches[1] . $matches[3], $excluded_attributes ) || rocket_is_excluded_lazyload( $matches[2], $excluded_src ) ) {
183
  return $matches[0];
184
  }
185
+
186
+ /**
187
+ * Filter the LazyLoad placeholder on src attribute
188
+ *
189
+ * @since 1.1
190
+ *
191
+ * @param string $placeholder Placeholder that will be printed.
192
+ */
193
+ $placeholder = apply_filters( 'rocket_lazyload_placeholder', 'data:image/gif;base64,R0lGODdhAQABAPAAAP///wAAACwAAAAAAQABAEACAkQBADs=' );
194
+
195
+ $html = sprintf( '<img%1$s src="%4$s" data-lazy-src=%2$s%3$s>', $matches[1], $matches[2], $matches[3], $placeholder );
196
+
197
+ $html_noscript = sprintf( '<noscript><img%1$s src=%2$s%3$s></noscript>', $matches[1], $matches[2], $matches[3] );
198
+
199
+ /**
200
+ * Filter the LazyLoad HTML output
201
+ *
202
+ * @since 1.0.2
203
+ *
204
+ * @param array $html Output that will be printed
205
+ */
206
+ $html = apply_filters( 'rocket_lazyload_html', $html, true );
207
+
208
+ return $html . $html_noscript;
209
+ }
210
+
211
+ /**
212
+ * Determine if the current image should be excluded from lazyload
213
+ *
214
+ * @since 1.1
215
+ * @author Remy Perona
216
+ *
217
+ * @param string $string String to search.
218
+ * @param array $excluded_values Array of excluded values to search in the string.
219
+ * @return bool True if one of the excluded values was found, false otherwise
220
+ */
221
+ function rocket_is_excluded_lazyload( $string, $excluded_values ) {
222
+ foreach ( $excluded_values as $excluded_value ) {
223
+ if ( strpos( $string, $excluded_value ) !== false ) {
224
+ return true;
225
+ }
226
+ }
227
+
228
+ return false;
229
  }
230
 
231
  /**
233
  *
234
  * @since 1.0
235
  */
236
+ function rocket_lazyload_smilies() {
237
+ if ( ! rocket_lazyload_get_option( 'images' ) || ! apply_filters( 'do_rocket_lazyload', true ) ) {
238
+ return;
239
+ }
240
 
241
+ remove_filter( 'the_content', 'convert_smilies' );
242
+ remove_filter( 'the_excerpt', 'convert_smilies' );
243
+ remove_filter( 'comment_text', 'convert_smilies', 20 );
244
+
245
+ add_filter( 'the_content', 'rocket_convert_smilies' );
246
+ add_filter( 'the_excerpt', 'rocket_convert_smilies' );
247
+ add_filter( 'comment_text', 'rocket_convert_smilies', 20 );
248
+ }
249
+ add_action( 'init', 'rocket_lazyload_smilies' );
250
 
251
  /**
252
  * Convert text equivalent of smilies to images.
253
  *
254
  * @source convert_smilies() in /wp-includes/formattings.php
255
  * @since 1.0
256
+ *
257
+ * @param string $text text content to parse.
258
+ * @return string Updated text content
259
  */
260
  function rocket_convert_smilies( $text ) {
261
 
263
  $output = '';
264
 
265
  if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) {
266
+ // HTML loop taken from texturize function, could possible be consolidated.
267
+ $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between.
268
+ $stop = count( $textarr );// loop stuff.
269
 
270
+ // Ignore proessing of specific tags.
271
  $tags_to_ignore = 'code|pre|style|script|textarea';
272
  $ignore_block_element = '';
273
 
274
  for ( $i = 0; $i < $stop; $i++ ) {
275
  $content = $textarr[ $i ];
276
 
277
+ // If we're in an ignore block, wait until we find its closing tag.
278
+ if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) {
279
  $ignore_block_element = $matches[1];
280
  }
281
 
282
+ // If it's not a tag and not in ignore block.
283
+ if ( '' === $ignore_block_element && strlen( $content ) > 0 && '<' !== $content[0] ) {
284
  $content = preg_replace_callback( $wp_smiliessearch, 'rocket_translate_smiley', $content );
285
  }
286
 
287
+ // did we exit ignore block.
288
+ if ( '' !== $ignore_block_element && '</' . $ignore_block_element . '>' === $content ) {
289
  $ignore_block_element = '';
290
  }
291
 
303
  *
304
  * @source translate_smiley() in /wp-includes/formattings.php
305
  * @since 1.0
306
+ *
307
+ * @param string $matches a string matching the pattern for smilies.
308
+ * @return string The updated HTML code to display smilies
309
  */
310
  function rocket_translate_smiley( $matches ) {
311
  global $wpsmiliestrans;
312
 
313
+ if ( count( $matches ) === 0 ) {
314
  return '';
315
+ }
316
 
317
  $smiley = trim( reset( $matches ) );
318
  $img = $wpsmiliestrans[ $smiley ];
322
  $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
323
 
324
  // Don't convert smilies that aren't images - they're probably emoji.
325
+ if ( ! in_array( $ext, $image_exts, true ) ) {
326
  return $img;
327
  }
328
 
337
  */
338
  $src_url = apply_filters( 'smilies_src', includes_url( "images/smilies/$img" ), $img, site_url() );
339
 
340
+ // Don't lazy-load if process is stopped with a hook.
341
  if ( apply_filters( 'do_rocket_lazyload', true ) ) {
342
  return sprintf( ' <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-lazy-original="%s" alt="%s" class="wp-smiley" /> ', esc_url( $src_url ), esc_attr( $smiley ) );
343
  } else {
344
  return sprintf( ' <img src="%s" alt="%s" class="wp-smiley" /> ', esc_url( $src_url ), esc_attr( $smiley ) );
345
  }
346
 
347
+ }
348
+
349
+ /**
350
+ * Compatibility with images with srcset attribute
351
+ *
352
+ * @since 1.1
353
+ * @author Geoffrey Crofte (code from WP Rocket plugin)
354
+ *
355
+ * @param string $html the HTML code to parse.
356
+ * @return string the updated HTML code
357
+ */
358
+ function rocket_lazyload_on_srcset( $html ) {
359
+ if ( preg_match( '/srcset=("(?:[^"]+)"|\'(?:[^\']+)\'|(?:[^ >]+))/i', $html ) ) {
360
+ $html = str_replace( 'srcset=', 'data-lazy-srcset=', $html );
361
+ }
362
+
363
+ if ( preg_match( '/sizes=("(?:[^"]+)"|\'(?:[^\']+)\'|(?:[^ >]+))/i', $html ) ) {
364
+ $html = str_replace( 'sizes=', 'data-lazy-sizes=', $html );
365
+ }
366
+
367
+ return $html;
368
+ }
369
+ add_filter( 'rocket_lazyload_html', 'rocket_lazyload_on_srcset' );
370
+
371
+ /**
372
+ * Replace iframes by LazyLoad
373
+ *
374
+ * @since 1.1
375
+ * @author Geoffrey Crofte (code from WP Rocket plugin)
376
+ *
377
+ * @param string $html the HTML code to parse.
378
+ * @return string the updated HTML code
379
+ */
380
+ function rocket_lazyload_iframes( $html ) {
381
+ // Don't LazyLoad if process is stopped for these reasons.
382
+ if ( ! rocket_lazyload_get_option( 'iframes' ) || ! apply_filters( 'do_rocket_lazyload_iframes', true ) || is_feed() || is_preview() || empty( $html ) || ( defined( 'DONOTLAZYLOAD' ) && DONOTLAZYLOAD ) ) {
383
+ return $html;
384
+ }
385
+
386
+ $matches = array();
387
+ preg_match_all( '/<iframe\s+.*?>/', $html, $matches );
388
+
389
+ foreach ( $matches[0] as $k => $iframe ) {
390
+
391
+ // Don't mess with the Gravity Forms ajax iframe.
392
+ if ( strpos( $iframe, 'gform_ajax_frame' ) ) {
393
+ continue;
394
+ }
395
+
396
+ // Don't lazyload if iframe has data-no-lazy attribute.
397
+ if ( strpos( $iframe, 'data-no-lazy=' ) ) {
398
+ continue;
399
+ }
400
+
401
+ /**
402
+ * Filter the LazyLoad placeholder on src attribute
403
+ *
404
+ * @since 1.1
405
+ *
406
+ * @param string $placeholder placeholder that will be printed.
407
+ */
408
+ $placeholder = apply_filters( 'rocket_lazyload_placeholder', 'data:image/gif;base64,R0lGODdhAQABAPAAAP///wAAACwAAAAAAQABAEACAkQBADs=' );
409
+
410
+ // todo: add "fitvids compatible" class or data-attribute to check in JS (see JS L.57).
411
+ $iframe = preg_replace( '/<iframe(.*?)src=/is', '<iframe$1src="' . $placeholder . '" data-lazy-src=', $iframe );
412
+
413
+ $html = str_replace( $matches[0][ $k ], $iframe, $html );
414
+
415
+ /**
416
+ * Filter the LazyLoad HTML output on iframes
417
+ *
418
+ * @since 1.1
419
+ *
420
+ * @param array $html Output that will be printed.
421
+ */
422
+ $html = apply_filters( 'rocket_lazyload_iframe_html', $html );
423
+ }
424
+
425
+ return $html;
426
+ }
427
+ add_filter( 'the_content', 'rocket_lazyload_iframes', PHP_INT_MAX );
428
+ add_filter( 'widget_text', 'rocket_lazyload_iframes', PHP_INT_MAX );