hexo-theme-linen 1.0.32 → 1.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/layout/layout.ejs +3 -3
- package/package.json +1 -1
- package/scripts/lazyload/client.js +126 -65
- package/scripts/lazyload/inject.js +2 -1
- package/source/linen-theme/css/lazyload.css +2 -2
- package/source/linen-theme/css/leaflet.css +661 -661
- package/source/linen-theme/js/hdr.js +28 -1
- package/source/linen-theme/js/lazyload.js +126 -65
package/layout/layout.ejs
CHANGED
|
@@ -122,9 +122,6 @@ const version = theme.version;
|
|
|
122
122
|
<script src="<%=url_for(`${url}?v=${version}`)%>"></script>
|
|
123
123
|
<% }); %>
|
|
124
124
|
<% } %>
|
|
125
|
-
<% if (theme?.lazyload?.enable ?? true) { %>
|
|
126
|
-
<script src="<%=url_for(`/linen-theme/js/lazyload.js?v=${version}`)%>"></script>
|
|
127
|
-
<% } %>
|
|
128
125
|
<% if (page.hdrAssetsPrefix) { %>
|
|
129
126
|
<script>
|
|
130
127
|
var hdrAssetsPrefix = "<%-page.hdrAssetsPrefix%>"
|
|
@@ -133,6 +130,9 @@ const version = theme.version;
|
|
|
133
130
|
<% if (page.hdrSwitch) { %>
|
|
134
131
|
<script src="<%=url_for(`/linen-theme/js/hdr.js?v=${version}`)%>"></script>
|
|
135
132
|
<% } %>
|
|
133
|
+
<% if (theme?.lazyload?.enable ?? true) { %>
|
|
134
|
+
<script src="<%=url_for(`/linen-theme/js/lazyload.js?v=${version}`)%>"></script>
|
|
135
|
+
<% } %>
|
|
136
136
|
<% if (theme?.appends?.length > 0) { %>
|
|
137
137
|
<% theme.appends.forEach(appendItem => { %>
|
|
138
138
|
<%-appendItem%>
|
package/package.json
CHANGED
|
@@ -94,26 +94,34 @@
|
|
|
94
94
|
if (typeof window === "undefined") {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
|
-
function get(object, path, defaultValue) {
|
|
98
|
-
if (object == null) return defaultValue;
|
|
99
|
-
|
|
100
|
-
// 把 a[0].b 转成 a.0.b
|
|
101
|
-
var pathArray =
|
|
102
|
-
typeof path === "string"
|
|
103
|
-
? path.replace(/\[(\w+)\]/g, ".$1").split(".")
|
|
104
|
-
: path;
|
|
105
|
-
|
|
106
|
-
var result = object;
|
|
107
|
-
|
|
108
|
-
for (var i = 0; i < pathArray.length; i++) {
|
|
109
|
-
if (result == null) return defaultValue;
|
|
110
|
-
result = result[pathArray[i]];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return result === undefined ? defaultValue : result;
|
|
114
|
-
}
|
|
115
97
|
var lazyloadItems = document.querySelectorAll(".lazyload-wrap");
|
|
116
98
|
var loadingQueue = [];
|
|
99
|
+
var scheduleFrame = window.requestAnimationFrame || function (callback) {
|
|
100
|
+
return window.setTimeout(callback, 16);
|
|
101
|
+
};
|
|
102
|
+
var revealQueue = [];
|
|
103
|
+
var revealScheduled = false;
|
|
104
|
+
var flushRevealQueue = function flushRevealQueue() {
|
|
105
|
+
var callbacks = revealQueue.splice(0);
|
|
106
|
+
revealScheduled = false;
|
|
107
|
+
callbacks.forEach(function (callback) {
|
|
108
|
+
if (callback) callback();
|
|
109
|
+
});
|
|
110
|
+
if (revealQueue.length) {
|
|
111
|
+
scheduleReveal();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
var scheduleReveal = function scheduleReveal(callback) {
|
|
115
|
+
if (callback) revealQueue.push(callback);
|
|
116
|
+
if (revealScheduled) return;
|
|
117
|
+
revealScheduled = true;
|
|
118
|
+
// Wait for one paint opportunity before revealing. The second frame is
|
|
119
|
+
// shared by all images that become ready together, avoiding per-image
|
|
120
|
+
// frame callbacks and preserving the transition for cached HDR images.
|
|
121
|
+
scheduleFrame(function () {
|
|
122
|
+
scheduleFrame(flushRevealQueue);
|
|
123
|
+
});
|
|
124
|
+
};
|
|
117
125
|
var appendStyles = function appendStyles(element, styles) {
|
|
118
126
|
var currentStyle = element.getAttribute("style");
|
|
119
127
|
var newStyles = "";
|
|
@@ -128,6 +136,10 @@
|
|
|
128
136
|
var nElement = document.createElement("div");
|
|
129
137
|
nElement.innerHTML = contentStr;
|
|
130
138
|
nElement.classList.add("inner-wrap");
|
|
139
|
+
nElement.style.opacity = "0";
|
|
140
|
+
if (!window.$lazyload || window.$lazyload.showTransition !== false) {
|
|
141
|
+
nElement.style.transition = "opacity ease-in-out 0.3s";
|
|
142
|
+
}
|
|
131
143
|
return nElement;
|
|
132
144
|
};
|
|
133
145
|
var restore_fallback = function restore_fallback(element) {
|
|
@@ -151,6 +163,28 @@
|
|
|
151
163
|
}
|
|
152
164
|
return obj;
|
|
153
165
|
};
|
|
166
|
+
var renderBlurHashPlaceholder = function renderBlurHashPlaceholder(element) {
|
|
167
|
+
var placeholderImage = element.dataset.blurhash;
|
|
168
|
+
if (!placeholderImage || element.dataset.blurhashRendered === "true") {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
var width = 32;
|
|
172
|
+
var height = 32;
|
|
173
|
+
var pixels = blurhash.decodeBlurHash(
|
|
174
|
+
placeholderImage.replace("blurhash:", ""),
|
|
175
|
+
width,
|
|
176
|
+
height,
|
|
177
|
+
);
|
|
178
|
+
var canvas = document.createElement("canvas");
|
|
179
|
+
var ctx = canvas.getContext("2d");
|
|
180
|
+
canvas.width = width;
|
|
181
|
+
canvas.height = height;
|
|
182
|
+
var imageData = ctx.createImageData(width, height);
|
|
183
|
+
imageData.data.set(pixels);
|
|
184
|
+
ctx.putImageData(imageData, 0, 0);
|
|
185
|
+
element.children[0].appendChild(canvas);
|
|
186
|
+
element.dataset.blurhashRendered = "true";
|
|
187
|
+
};
|
|
154
188
|
var initPlaceholder = function initPlaceholder(element) {
|
|
155
189
|
var wrap = document.createElement("div");
|
|
156
190
|
// prevent triggering load event
|
|
@@ -166,25 +200,9 @@
|
|
|
166
200
|
var placeholderImage =
|
|
167
201
|
resourceElement.dataset.placeholderimg || altAttributes.placeholderImage;
|
|
168
202
|
if (placeholderImage && /blurhash:/.test(placeholderImage)) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
var height = 32;
|
|
173
|
-
var pixels = blurhash.decodeBlurHash(
|
|
174
|
-
placeholderImage.replace("blurhash:", ""),
|
|
175
|
-
width,
|
|
176
|
-
height,
|
|
177
|
-
);
|
|
178
|
-
var ctx = canvas.getContext("2d");
|
|
179
|
-
canvas.width = width;
|
|
180
|
-
canvas.height = height;
|
|
181
|
-
var imageData = ctx.createImageData(width, height);
|
|
182
|
-
imageData.data.set(pixels);
|
|
183
|
-
ctx.putImageData(imageData, 0, 0);
|
|
184
|
-
return canvas;
|
|
185
|
-
};
|
|
186
|
-
var cv = createCanvas();
|
|
187
|
-
element.children[0].appendChild(cv);
|
|
203
|
+
// Decode only when this item is actually restored. Doing this for
|
|
204
|
+
// every image during page initialization can block the main thread.
|
|
205
|
+
element.dataset.blurhash = placeholderImage;
|
|
188
206
|
}
|
|
189
207
|
element.dataset.content = element.dataset.content
|
|
190
208
|
.replace(/%24placeholder%3D(\S+)%3Dplaceholder/gi, "")
|
|
@@ -196,34 +214,70 @@
|
|
|
196
214
|
loadingQueue.push(element);
|
|
197
215
|
}
|
|
198
216
|
if (element.classList && element.classList.contains("loaded")) return;
|
|
217
|
+
renderBlurHashPlaceholder(element);
|
|
199
218
|
var contentStr = decodeURIComponent(element.dataset.content);
|
|
200
219
|
var newElement = createResourceElement(contentStr);
|
|
201
220
|
var initOnLoadEvent = function initOnLoadEvent(resourceElement) {
|
|
202
|
-
resourceElement.children[0]
|
|
221
|
+
var imageElement = resourceElement.children[0];
|
|
222
|
+
var revealedSource = "";
|
|
223
|
+
var revealToken = 0;
|
|
224
|
+
var showTransition =
|
|
225
|
+
!window.$lazyload || window.$lazyload.showTransition !== false;
|
|
226
|
+
var clearPlaceholder = function clearPlaceholder() {
|
|
227
|
+
var keepPlaceholder =
|
|
228
|
+
element.getAttribute("data-hdr-active") === "true" ||
|
|
229
|
+
(window.$lazyload && window.$lazyload.keepPlaceholder === true);
|
|
230
|
+
if (!keepPlaceholder) {
|
|
231
|
+
element.children[0].classList.add("loaded");
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
var revealResource = function revealResource() {
|
|
235
|
+
var source = imageElement.currentSrc || imageElement.src || "";
|
|
236
|
+
if (revealedSource === source && element.classList.contains("loaded")) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
var token = ++revealToken;
|
|
240
|
+
// `load` means the resource is available, but the browser may still
|
|
241
|
+
// need a paint opportunity before the image becomes visible. Do not
|
|
242
|
+
// call HTMLImageElement.decode() here: some HDR decoders crash the
|
|
243
|
+
// renderer before JavaScript can handle the resulting exception.
|
|
244
|
+
scheduleReveal(function () {
|
|
245
|
+
if (token !== revealToken) return;
|
|
246
|
+
if ((imageElement.currentSrc || imageElement.src || "") !== source) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
revealedSource = source;
|
|
250
|
+
// The inline opacity is already 0 and the inline transition is set
|
|
251
|
+
// before insertion, so the next frame can reveal without forcing a
|
|
252
|
+
// synchronous layout for every image.
|
|
253
|
+
resourceElement.style.opacity = "1";
|
|
254
|
+
resourceElement.classList.add("loaded");
|
|
255
|
+
element.classList.add("loaded");
|
|
256
|
+
if (!showTransition) {
|
|
257
|
+
clearPlaceholder();
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
imageElement.onload = function () {
|
|
203
262
|
try {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
wrapElement.setAttribute("data-pswp-width", width);
|
|
223
|
-
wrapElement.setAttribute("data-pswp-height", height);
|
|
224
|
-
wrapElement.setAttribute("data-cropped", true);
|
|
225
|
-
}
|
|
226
|
-
}, 100);
|
|
263
|
+
revealResource();
|
|
264
|
+
var isImage = imageElement && imageElement.tagName === "IMG";
|
|
265
|
+
var wrapElement = element.parentElement;
|
|
266
|
+
var width = imageElement.naturalWidth;
|
|
267
|
+
if (
|
|
268
|
+
isImage &&
|
|
269
|
+
wrapElement &&
|
|
270
|
+
wrapElement.tagName === "A" &&
|
|
271
|
+
wrapElement.getAttribute("data-pswp-hassize") !== "true"
|
|
272
|
+
) {
|
|
273
|
+
var height = imageElement.naturalHeight;
|
|
274
|
+
element.children[0].style.paddingBottom = `${
|
|
275
|
+
(height / width) * 100
|
|
276
|
+
}%`;
|
|
277
|
+
wrapElement.setAttribute("data-pswp-width", width);
|
|
278
|
+
wrapElement.setAttribute("data-pswp-height", height);
|
|
279
|
+
wrapElement.setAttribute("data-cropped", true);
|
|
280
|
+
}
|
|
227
281
|
var errorElement = element.querySelectorAll(".error-wrap")[0];
|
|
228
282
|
if (errorElement) {
|
|
229
283
|
element.removeChild(errorElement);
|
|
@@ -232,10 +286,17 @@
|
|
|
232
286
|
console.log(e);
|
|
233
287
|
}
|
|
234
288
|
};
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
289
|
+
// Cached images can already be complete before the load listener is
|
|
290
|
+
// observed. Use the same paint-safe path for that case.
|
|
291
|
+
if (imageElement.complete && imageElement.naturalWidth) {
|
|
292
|
+
revealResource();
|
|
293
|
+
}
|
|
294
|
+
resourceElement.ontransitionend = function (event) {
|
|
295
|
+
if (event.propertyName && event.propertyName !== "opacity") return;
|
|
296
|
+
// HDR gain-map composition can finish after the normal image
|
|
297
|
+
// load/opacity transition. Keep its placeholder, but clear it for
|
|
298
|
+
// normal images so transparent PNG/WebP images are not covered by it.
|
|
299
|
+
clearPlaceholder();
|
|
239
300
|
};
|
|
240
301
|
if (/<video/.test(contentStr)) {
|
|
241
302
|
setTimeout(function () {
|
|
@@ -135,7 +135,8 @@ module.exports = function (hexo) {
|
|
|
135
135
|
|
|
136
136
|
let settingsContent = `<script>var $lazyload = {
|
|
137
137
|
intersectionRatio: ${intersectionRatio},
|
|
138
|
-
preloadCount: ${preloadCount},
|
|
138
|
+
preloadCount: ${preloadCount},
|
|
139
|
+
showTransition: ${showTransition},
|
|
139
140
|
keepPlaceholder: ${
|
|
140
141
|
page?.lazyload?.keepPlaceholder ?? false
|
|
141
142
|
}}</script>`;
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
padding-bottom: 66.66667%;
|
|
21
21
|
background-size: 100% 100%;
|
|
22
22
|
background-repeat: no-repeat;
|
|
23
|
-
background-image: url(../img/lazyload/loading.svg);
|
|
23
|
+
background-image: url(../linen-theme/img/lazyload/loading.svg);
|
|
24
24
|
background-color: #fff;
|
|
25
25
|
}
|
|
26
26
|
.lazyload-wrap .placeholder canvas{
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
.lazyload-wrap .error-wrap .error-tip{
|
|
78
78
|
width: 60%;
|
|
79
79
|
background-size: cover;
|
|
80
|
-
background-image: url(../img/lazyload/error-tip.svg);
|
|
80
|
+
background-image: url(../linen-theme/img/lazyload/error-tip.svg);
|
|
81
81
|
}
|
|
82
82
|
.lazyload-wrap .error-wrap .error-tip::before{
|
|
83
83
|
content: '';
|